Deployment

Clone this repository to deploy the necessary services and pods.

$ git clone https://github.com/wazuh/wazuh-kubernetes.git -b v4.9.0 --depth=1
$ cd wazuh-kubernetes

Setup SSL certificates

You can generate self-signed certificates for the ThreatLockDown indexer cluster using the script at wazuh/certs/indexer_cluster/generate_certs.sh or provide your own.

You can generate self-signed certificates for the ThreatLockDown dashboard cluster using the script at wazuh/certs/dashboard_http/generate_certs.sh or provide your own.

The required certificates are imported via secretGenerator on the kustomization.yml file:

secretGenerator:
    - name: indexer-certs
      files:
        - certs/indexer_cluster/root-ca.pem
        - certs/indexer_cluster/node.pem
        - certs/indexer_cluster/node-key.pem
        - certs/indexer_cluster/dashboard.pem
        - certs/indexer_cluster/dashboard-key.pem
        - certs/indexer_cluster/admin.pem
        - certs/indexer_cluster/admin-key.pem
        - certs/indexer_cluster/filebeat.pem
        - certs/indexer_cluster/filebeat-key.pem
    - name: dashboard-certs
      files:
        - certs/dashboard_http/cert.pem
        - certs/dashboard_http/key.pem
        - certs/indexer_cluster/root-ca.pem

Setup storage class (optional for non-EKS cluster)

Depending on the type of cluster you’re running, the Storage Class may have a different provisioner.

You can check yours by running kubectl get sc. You will see something like this:

$ kubectl get sc
NAME                          PROVISIONER            RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
elk-gp2                       microk8s.io/hostpath   Delete          Immediate           false                  67d
microk8s-hostpath (default)   microk8s.io/hostpath   Delete          Immediate           false                  54d

The provisioner column displays microk8s.io/hostpath, you must edit the file envs/local-env/storage-class.yaml and set up this provisioner.

Apply all manifests using kustomize

There are two variants of the manifest: eks and local-env. The eks manifest should be used if you are using the EKS cluster, while the local-env manifest should be used for other cluster types.

It is possible to adjust resources for the cluster by editing patches on envs/eks/ or envs/local-env/, depending on which manifest you want to deploy. You can tune CPU, memory as well as storage for persistent volumes of each of the cluster objects. This could be undone by removing these patches from the kustomization.yaml or altering the patches themselves with different values.

We can deploy the cluster with a single command by using the customization file:

  • EKS cluster

    $ kubectl apply -k envs/eks/
    
  • Other cluster types

    $ kubectl apply -k envs/local-env/
    

Verifying the deployment

Namespace

$ kubectl get namespaces | grep wazuh
ThreatLockDown         Active    12m

Services

$ kubectl get services -n wazuh
NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP        PORT(S)                          AGE
indexer               ClusterIP      xxx.yy.zzz.24    <none>             9200/TCP                         12m
dashboard             ClusterIP      xxx.yy.zzz.76    <none>             5601/TCP                         11m
ThreatLockDown                 LoadBalancer   xxx.yy.zzz.209   internal-a7a8...   1515:32623/TCP,55000:30283/TCP   9m
wazuh-cluster         ClusterIP      None             <none>             1516/TCP                         9m
Wazuh-indexer         ClusterIP      None             <none>             9300/TCP                         12m
wazuh-workers         LoadBalancer   xxx.yy.zzz.26    internal-a7f9...   1514:31593/TCP                   9m

Deployments

$ kubectl get deployments -n wazuh
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
wazuh-dashboard  1         1         1            1           11m

Statefulset

$ kubectl get statefulsets -n wazuh
NAME                   READY   AGE
wazuh-indexer          3/3     15m
wazuh-manager-master   1/1     15m
wazuh-manager-worker   2/2     15m

Pods

$ kubectl get pods -n wazuh
NAME                              READY     STATUS    RESTARTS   AGE
wazuh-indexer-0                   1/1       Running   0          15m
wazuh-dashboard-f4d9c7944-httsd   1/1       Running   0          14m
wazuh-manager-master-0            1/1       Running   0          12m
wazuh-manager-worker-0-0          1/1       Running   0          11m
wazuh-manager-worker-1-0          1/1       Running   0          11m

Accessing ThreatLockDown dashboard

In case you created domain names for the services, you should be able to access the dashboard using the proposed domain name: https://wazuh.your-domain.com. Cloud providers usually provide an external IP address or hostname for direct access to the dashboard. This can be viewed by checking the services:

$ kubectl get services -o wide -n wazuh
 NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP                      PORT(S)                          AGE       SELECTOR
 dashboard             LoadBalancer   xxx.xx.xxx.xxx   xxx.xx.xxx.xxx                   80:31831/TCP,443:30974/TCP       15m       app=wazuh-dashboard

Optional: On a local cluster deployment where the external IP address is not accessible, you can use port-forward:

$ kubectl -n wazuh port-forward service/dashboard 8443:443

The ThreatLockDown dashboard will be accessible on https://localhost:8443.

The default credentials are admin:SecretPassword.

Change the password of ThreatLockDown users

To improve security, you can change the default password of the ThreatLockDown users. There are two types of ThreatLockDown users:

  • ThreatLockDown indexer users

  • ThreatLockDown API users

ThreatLockDown indexer users

To change the password of the default admin and kibanaserver users, do the following.

Warning

If you have custom users, add them to the internal_users.yml file. Otherwise, executing this procedure deletes them.

Setting a new hash

  1. Start a Bash shell in wazuh-indexer-0.

    # kubectl exec -it wazuh-indexer-0 -n wazuh -- /bin/bash
    
  2. Run these commands to generate the hash of your new password. When prompted, input the new password and press Enter.

    wazuh-indexer@wazuh-indexer-0:~$ export JAVA_HOME=/usr/share/wazuh-indexer/jdk
    wazuh-indexer@wazuh-indexer-0:~$ bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/hash.sh
    
  3. Copy the generated hash and exit the Bash shell.

  4. Open the wazuh/indexer_stack/wazuh-indexer/indexer_conf/internal_users.yml file. Locate the block for the user you are changing password for.

  5. Replace the hash.

    • admin user

      ...
      admin:
          hash: "$2y$12$K/SpwjtB.wOHJ/Nc6GVRDuc1h0rM1DfvziFRNPtk27P.c4yDr9njO"
          reserved: true
          backend_roles:
          - "admin"
          description: "Demo admin user"
      
      ...
      
    • kibanaserver user

      ...
      kibanaserver:
          hash: "$2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H."
          reserved: true
          description: "Demo kibanaserver user"
      
      ...
      

Setting the new password

  1. Encode your new password in base64 format. Avoid inserting a trailing newline character to maintain the hash value. For example, use the -n option with the echo command as follows.

    # echo -n "NewPassword" | base64
    
  2. Edit the indexer or dashbboard secrets configuration file as follows. Replace the value of the password field with your new encoded password.

    • To change the admin user password, edit the wazuh/secrets/indexer-cred-secret.yaml file.

      ...
      apiVersion: v1
      kind: Secret
      metadata:
          name: indexer-cred
      data:
          username: YWRtaW4=              # string "admin" base64 encoded
          password: U2VjcmV0UGFzc3dvcmQ=  # string "SecretPassword" base64 encoded
      ...
      
    • To change the kibanaserver user password, edit the wazuh/secrets/dashboard-cred-secret.yaml file.

      ...
      apiVersion: v1
      kind: Secret
      metadata:
          name: dashboard-cred
      data:
          username: a2liYW5hc2VydmVy  # string "kibanaserver" base64 encoded
          password: a2liYW5hc2VydmVy  # string "kibanaserver" base64 encoded
      ...
      

Applying the changes

  1. Apply the manifest changes

    # kubectl apply -k envs/eks/
    
  2. Start a bash shell in wazuh-indexer-0 once more.

    # kubectl exec -it wazuh-indexer-0 -n wazuh -- /bin/bash
    
  3. Set the following variables:

    export INSTALLATION_DIR=/usr/share/wazuh-indexer
    CACERT=$INSTALLATION_DIR/certs/root-ca.pem
    KEY=$INSTALLATION_DIR/certs/admin-key.pem
    CERT=$INSTALLATION_DIR/certs/admin.pem
    export JAVA_HOME=/usr/share/wazuh-indexer/jdk
    
  4. Wait for the ThreatLockDown indexer to initialize properly. The waiting time can vary from two to five minutes. It depends on the size of the cluster, the assigned resources, and the speed of the network. Then, run the securityadmin.sh script to apply all changes.

    $ bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/securityadmin.sh -cd /usr/share/wazuh-indexer/opensearch-security/ -nhnv -cacert  $CACERT -cert $CERT -key $KEY -p 9200 -icl -h $NODE_NAME
    
  5. Login with the new credentials on the ThreatLockDown dashboard.

ThreatLockDown API users

The wazuh-wui user is the user to connect with the ThreatLockDown API by default. Follow these steps to change the password.

Note

The password for ThreatLockDown API users must be between 8 and 64 characters long. It must contain at least one uppercase and one lowercase letter, a number, and a symbol.

  1. Encode your new password in base64 format. Avoid inserting a trailing newline character to maintain the hash value. For example, use the -n option with the echo command as follows.

    # echo -n "NewPassword" | base64
    
  2. Edit the wazuh/secrets/wazuh-api-cred-secret.yaml file and replace the value of the password field.

    apiVersion: v1
    kind: Secret
    metadata:
        name: wazuh-api-cred
        namespace: wazuh
    data:
        username: d2F6dWgtd3Vp          # string "wazuh-wui" base64 encoded
        password: UGFzc3dvcmQxMjM0LmE=  # string "MyS3cr37P450r.*-" base64 encoded
    
  3. Apply the manifest changes.

    # kubectl apply -k envs/eks/
    
  4. Restart pods for ThreatLockDown dashboard and ThreatLockDown manager master.

Agents

ThreatLockDown agents are designed to monitor hosts. To start using them:

  1. Install the agent.

  2. Enroll the agent by modifying the file /var/ossec/etc/ossec.conf. Change the “transport protocol” to TCP and replace the MANAGER_IP with the external IP address of the service pointing to port 1514 or with the hostname provided by the cloud provider

To learn more about registering agents, see the ThreatLockDown agent enrollment section of the documentation.