paint-brush
Wazuh on Docker: Secure Your Dashboard with Let's Encrypt and Deploy Agent with Kubernetes Daemonsetby@okeybukks
926 reads
926 reads

Wazuh on Docker: Secure Your Dashboard with Let's Encrypt and Deploy Agent with Kubernetes Daemonset

by Achebe Okechukwu August 26th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

This guide walks you through setting up Wazuh with Docker, including configuring the Wazuh Manager, Indexer, and Dashboard, and securing your dashboard with Let’s Encrypt. It also covers deploying Wazuh agents on VMs and integrating them with Kubernetes. Follow the steps to ensure a secure and efficient Wazuh deployment.
featured image - Wazuh on Docker: Secure Your Dashboard with Let's Encrypt and Deploy Agent with Kubernetes Daemonset
Achebe Okechukwu  HackerNoon profile picture

Wazuh is an open-source security platform that takes pride in delivering robust endpoint security, advanced threat intelligence, streamlined security operations, and comprehensive cloud security. It’s a one-stop that provides a detailed breakdown of security issues for your on-premise and cloud resources. Read more here.


This article aims to provide a straightforward guide for setting up Wazuh using Docker, securing the Wazuh Dashboard domain with Let’s Encrypt, and deploying the necessary agents on a virtual machine (VM).


Prerequisites:

  • Docker and Docker Compose installed on your server.
  • A registered domain name for the Wazuh Dashboard.
  • A Kubernetes Cluster.


Wazuh is made up of three services, the Wazuh Manager, the Wazuh Indexer, and the Wazuh Dashboard. All three components will be installed using a Docker Compose file. Before the installation process, ensure the following ports are open in the VM;

  • 443 for HTTPS connection
  • 5601 Wazuh Dashboard port
  • 1514, 1515, 514/udp, 55000 used by Wazuh Manager for communication
  • 9200 Wazuh Indexer port


It is recommended to increase the `max_map_count` on the VM, because of the many memory-mapped areas created by the Wazuh Indexer.


To increase this count, run this command on the VM:

sysctl -w vm.max_map_count=262144


If you don’t set the max_map_count on your host, the Wazuh indexer will NOT work properly.


To get started, clone the official Wazuh repository with this command:

git clone https://github.com/wazuh/wazuh-docker.git


Here's a refined version of the instruction:

In the single-node/ folder, update the version tags for the wazuh/wazuh-manager, wazuh/wazuh-indexer, and wazuh/wazuh-dashboard images to 4.8.1 in the docker-compose.yml file.


As I write this guide, the available docker version for the Wazuh images is 4.8.1.


The next phase is creating the certificates needed by Wazuh’s resources for proper communication.


In the single-node/ folder, there’s a generate-indexer-certs.yml which is a docker compose file used for generating the certificates.


To create the Wazuh certificates, run the command below from the single-node/ folder:

docker-compose -f generate-indexer-certs.yml run --rm generator


The generated certificates are stored in the wazuh_indexer_ssl_certs/ folder which is used by Wazuh resources in the volumes section of the docker-compose.yml file.


To start the Wazuh deployment run this command from the single-node/ folder:

docker-compose up


The startup process takes about a minute. You can access the Wazuh dashboard at: https://virtual-machine-ip


At this point, when you visit https://virtual-machine-ip you’ll be greeted with:

This means our dashboard is insecure. To secure it, we will use Let’s Encrypt to generate certificates and enable HTTPS.

Before we get into securing the URL, we need to link the VM IP where Wazuh is hosted to a registered domain.


Linking an IP to a domain is beyond the scope of this article but if you are using a domain with Namecheap, you can learn how to do so here. Once you’ve done this, return to this article to create the Let’s Encrypt Certificate.


An excellent article by the Wazuh team on how to create the Let’s Encrypt certificate for the Wazuh dashboard will guide you to create a certificate for Wazuh deployed directly on the VM.

Continue reading once the certificate has been created.


Because Wazuh is deployed with docker, the steps specified in this section of the article don’t apply. To configure the created certificates with the Wazuh dashboard, docker volumes are used to map the generated certificates to the locations that are needed by the Wazuh dashboard container.


Follow these steps to map the generated certificates to the Wazuh dashboard container:


  1. Change the user and permission of the archive files:

    # change owner to UID used in running the docker compose command
    sudo chown -R 1000:1000 /etc/letsencrypt/archive/<YOUR_DOMAIN_NAME>/
    
    # change permission of the files
    sudo chmod -R 500 /etc/letsencrypt/archive/<YOUR_DOMAIN_NAME>/fullchain1.pem
    sudo chmod 440 /etc/letsencrypt/archive/<YOUR_DOMAIN_NAME>/privkey1.pem
    


  1. Use a soft link to link the generated certificates to a location mapped to the container certificates’ location:

    # change into the single-node/config folder
    cd single-node/config
    
    # create letsencrypt/ folder
    mkdir letsencrypt
    
    # change into the letsencrypt
    cd letsencrypt
    
    # link the certificate
    ln -s /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/privkey.pem privkey.pem
    ln -s /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/fullchain.pem fullchain.pem
    


  1. Stop the docker containers from running:

    docker compose down
    


  1. Add the fullchain.pem and privkey.pem files in the volumes of the Wazuh dashboard container:

    # create a backup for your docker compose file (wazuh/single-node)
    cp docker-compose.yml docker-compose-bk.yml
    
    # edit dicker-compose file
    - ./config/letsencrypt/privkey.pem:/usr/share/wazuh-dashboard/lets-encrypt/privkey.pem # New certificate added
    - ./config/letsencrypt/fullchain.pem:/usr/share/wazuh-dashboard/lets-encrypt/fullchain.pem # New certificate added
    - ./config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
    - ./config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
    - ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem
    - ./config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml
    - ./config/wazuh_dashboard/wazuh.yml:/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml
    - wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config
    - wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom
    


  1. Edit the opensearch_dashboards.yml file to reference the created certificates:

    server.host: 0.0.0.0
    server.port: 5601
    opensearch.hosts: https://wazuh.indexer:9200
    opensearch.ssl.verificationMode: certificate
    opensearch.requestHeadersWhitelist: ["securitytenant","Authorization"]
    opensearch_security.multitenancy.enabled: false
    opensearch_security.readonly_mode.roles: ["kibana_read_only"]
    server.ssl.enabled: true
    server.ssl.key: "/usr/share/wazuh-dashboard/lets-encrypt/privkey.pem" # Newly referenced certificate
    server.ssl.certificate: "/usr/share/wazuh-dashboard/lets-encrypt/fullchain.pem" # Newly referenced certificate
    opensearch.ssl.certificateAuthorities: ["/usr/share/wazuh-dashboard/certs/root-ca.pem"]
    uiSettings.overrides.defaultRoute: /app/wz-home
    


  1. Setup Certificate Auto-renewal:

    # Edit the /etc/letsencrypt/renewal/<YOUR_DOMAIN_NAME>.conf file
    
    # renew_before_expiry = 30 days
    version = 2.11.0
    archive_dir = /etc/letsencrypt/archive/<YOUR_DOMAIN_NAME>
    cert = /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/cert.pem
    privkey = /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/privkey.pem
    chain = /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>chain.pem
    fullchain = /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/fullchain.pem
    
    # Options used in the renewal process
    [renewalparams]
    account = 4a622a9****************c
    authenticator = standalone
    server = https://acme-v02.api.letsencrypt.org/directory
    key_type = ecdsa
    renew_hook = docker restart wazuh_dashboard
    


  1. Test the renewal hook by running the command below:

    certbot renew --dry-run
    


  1. Restart the Wazuh deployment:

    # wazuh/single-node/
    
    docker-compose up
    


The dashboard should be secured after the restart of the deployment. The default username and password for the dashboard are admin and SecretPassword respectively.



Deploying Wazuh Agent

Deploying the Wazuh Manager, Indexer, and Dashboard, along with securing its domain, is just one aspect of the setup. To effectively monitor virtual machines, a Wazuh agent must be installed on each machine. For more detailed information on Wazuh agents, you can read this article.


To deploy this agent in a Kubernetes cluster, a daemonset is utilized, ensuring an agent runs in all the cluster’s nodes. To kick start the deployment process, a daemonset.yml is created whose values can be gotten from this gist. Before creating the daemonset, a couple of environment variables have to be assigned values:

  • JOIN_MANAGER_MASTER_HOST: This is the domain/IP where the Wazuh deployment is running.

  • JOIN_MANAGER_WORKER_HOST: This has same value as the JOIN_MANAGER_MASTER_HOST variable.

  • JOIN_MANAGER_PASSWORD: This is the API password. The default value is MyS3cr37P450r.*-

    if wish to change this password, you can check out this article.

  • JOIN_MANAGER_USER: This the API Username. The default value is wazuh-wui


Once the above variables have been assigned their values, you can run this command in your Kubernetes cluster:

kubectl apply -f daemonset.yml


From your Wazuh dashboard, you should have something similar to the image below.

If you follow the above steps, you should be able to successfully deploy a Wazuh application using docker, securing its domain, and also deploy agents on VMs to be monitored on Kubernetes.


Thanks for reading!


References