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:
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;
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:
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
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
Stop the docker containers from running:
docker compose down
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
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
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
Test the renewal hook by running the command below:
certbot renew --dry-run
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 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!