Skip to content

Install Wazuh

Prepare an offline package and deploy the Wazuh indexer, manager, Filebeat, and dashboard as an all-in-one lab.

Machine: Wazuh serverUser: root or sudo administratorStarting point: supported Linux host with fixed address and correct time
1 Prepare2 Indexer3 Manager4 Filebeat5 Dashboard6 Verify

Before you begin

Confirm the supported operating system, CPU, memory, storage, DNS, time synchronisation, and required ports against current Wazuh documentation. The demonstrated lab uses an all-in-one CentOS Stream host; distributed and DEB-based deployments are alternative routes.

Protect administrative access

Confirm the required source networks before changing firewall rules. Keep the current administration session open until management access has been verified.

Prepare the offline installation

On an internet-connected Linux machine, download the installation script, architecture-specific package bundle, and certificate configuration for the version you intend to deploy. Define stable node names and addresses in config.yml, generate the certificates, record transfer hashes and the vendor package checksums, and transfer the resulting files to the isolated host.

The detailed commands use the 4.14 release-family path. Before downloading, resolve it to one tested patch version, verify every central package uses that same patch, and record the exact filenames and checksums. Do not assume that a bundle downloaded on a later date contains the same packages.

Use explicit placeholders such as <WAZUH_SERVER_IP> and <INDEXER_NODE_NAME> in your working notes. Do not copy example addresses into a different environment without checking them.

Alternative: distributed or DEB deployment

The detailed procedure below retains the RPM and DEB commands and the multi-node certificate examples. Choose one deployment model before starting; do not mix commands from different routes.

Detailed installation procedure

The original proof-of-concept procedure is retained below in full, including package commands, certificate deployment, configuration examples, service checks, screenshots, and optional security steps.

Prerequisites

Ensure that curl, tar, and setcap are installed on the target system for the offline installation. On some Debian-based systems, gnupg may also be required.

Additionally, some systems have cp set as an alias for cp -i, which prompts for confirmation before overwriting files. To prevent this, run unalias cp.

Configure network access by component

Open only the ports required by the selected deployment and restrict every rule to its intended source network. In an all-in-one deployment, keep indexer port 9200/tcp on loopback and do not expose it through the host firewall. Port 55000/tcp is the Wazuh server API; it is not required for normal agent enrollment. Agents normally connect to 1514/tcp for events and 1515/tcp for automatic enrollment.

Port Purpose Typical source Required in this lab
443/tcp Dashboard Authorised analyst subnet Yes
1514/tcp Agent event channel Monitored endpoints Yes
1515/tcp Agent enrollment Monitored endpoints during enrollment Yes
55000/tcp Wazuh API Dashboard or administration hosts only Only when accessed remotely
9200/tcp Indexer API Wazuh central components only No external access for all-in-one

Replace <AGENT_SUBNET> and <ANALYST_SUBNET> before running these examples.

CentOS Stream / firewalld:

sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="<AGENT_SUBNET>" port port="1514" protocol="tcp" accept'
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="<AGENT_SUBNET>" port port="1515" protocol="tcp" accept'
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="<ANALYST_SUBNET>" port port="443" protocol="tcp" accept'
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Ubuntu / UFW:

sudo ufw allow from <AGENT_SUBNET> to any port 1514 proto tcp
sudo ufw allow from <AGENT_SUBNET> to any port 1515 proto tcp
sudo ufw allow from <ANALYST_SUBNET> to any port 443 proto tcp
sudo ufw status verbose

Download packages and configuration files

From any Linux system with Internet access, run the following commands to execute a script that downloads all necessary files for offline installation on x86_64 architectures. Choose the appropriate package format to download.

RPM:

curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh
chmod 744 wazuh-install.sh
./wazuh-install.sh -dw rpm -da x86_64

DEB:

curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh
chmod 744 wazuh-install.sh
./wazuh-install.sh -dw deb -da amd64

Download the certificates configuration file.

curl -sO https://packages.wazuh.com/4.14/config.yml

Modify config.yml to set up certificate creation.

  • For an all-in-one deployment, replace "<indexer-node-ip>", "<wazuh-manager-ip>", and "<dashboard-node-ip>" with 127.0.0.1.
  • For a distributed deployment, update the node names and IP addresses with the correct values for the Wazuh server, indexer, and dashboard. Add extra node fields as required.
nodes:
  # Wazuh indexer nodes
  indexer:
    - name: node-1
      ip: 10.0.0.20
    #- name: node-2
    #  ip: "<indexer-node-ip>"
    #- name: node-3
    #  ip: "<indexer-node-ip>"

  # Wazuh server nodes
  # If there is more than one Wazuh server
  # node, each one must have a node_type
  server:
    - name: wazuh-1
      ip: 10.0.0.20
    #  node_type: master
    #- name: wazuh-2
    #  ip: "<wazuh-manager-ip>"
    #  node_type: worker
    #- name: wazuh-3
    #  ip: "<wazuh-manager-ip>"
    #  node_type: worker

  # Wazuh dashboard nodes
  dashboard:
    - name: dashboard
      ip: 10.0.0.20

Run the ./wazuh-install.sh -g to generate the certificates. For a multi-node cluster, these certificates need to be later deployed to all Wazuh instances in your cluster.

./wazuh-install.sh -g

Transfer the following files to a directory on the host(s) where the offline installation will be performed. You can use scp for this:

  • wazuh-install.sh
  • wazuh-offline.tar.gz
  • wazuh-install-files.tar

Record SHA-256 checksums before transfer and verify them on every destination:

sha256sum wazuh-install.sh wazuh-offline.tar.gz wazuh-install-files.tar > wazuh-transfer.sha256
sha256sum --check wazuh-transfer.sha256

Before installing packages, also compare their SHA-512 values with the package checksums published for the selected Wazuh release. Stop if any checksum differs.

Install Wazuh components

In the working directory where you placed wazuh-offline.tar.gz and wazuh-install-files.tar, execute the following command to decompress the installation files:

tar xf wazuh-offline.tar.gz
tar xf wazuh-install-files.tar

Install the Wazuh indexer

RPM:

The following dependencies must be installed on the Wazuh indexer nodes.

  • coreutils
rpm --import ./wazuh-offline/wazuh-files/GPG-KEY-WAZUH
rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-indexer*.rpm

DEB:

The following dependencies must be installed on the Wazuh indexer nodes.

  • debconf
  • adduser
  • procps
dpkg -i ./wazuh-offline/wazuh-packages/wazuh-indexer*.deb

Run the following commands replacing <indexer-node-name> with the name of the Wazuh indexer node you are configuring as defined in config.yml. For example, node-1. This deploys the SSL certificates to encrypt communications between the Wazuh central components.

NODE_NAME=<INDEXER_NODE_NAME>
install -d -m 500 -o wazuh-indexer -g wazuh-indexer /etc/wazuh-indexer/certs
mv -n wazuh-install-files/$NODE_NAME.pem /etc/wazuh-indexer/certs/indexer.pem
mv -n wazuh-install-files/$NODE_NAME-key.pem /etc/wazuh-indexer/certs/indexer-key.pem
mv wazuh-install-files/admin-key.pem /etc/wazuh-indexer/certs/
mv wazuh-install-files/admin.pem /etc/wazuh-indexer/certs/
cp wazuh-install-files/root-ca.pem /etc/wazuh-indexer/certs/
chmod 500 /etc/wazuh-indexer/certs
chmod 400 /etc/wazuh-indexer/certs/*
chown -R wazuh-indexer:wazuh-indexer /etc/wazuh-indexer/certs

Move each node’s certificate and key files (e.g., node-1.pem and node-1-key.pem) to their respective certs folder. These files are specific to each node and shouldn’t be shared with others. However, do not move the root-ca.pem certificate—copy it instead, so it can be deployed to other component folders later.

Edit /etc/wazuh-indexer/opensearch.yml and modify the following settings:

  1. network.host – Defines the node’s address for HTTP and transport traffic. It should match the address used in config.yml when generating SSL certificates.
  2. node.name – Set this to the Wazuh indexer node name as defined in config.yml (e.g., node-1).
  3. cluster.initial_master_nodes – List the names of master-eligible nodes, as specified in config.yml.
network.host: "10.0.0.20"
node.name: "node-1"
cluster.initial_master_nodes:
- "node-1"
#- "node-2"
#- "node-3"
  1. discovery.seed_hosts – Contains the addresses of master-eligible nodes. Leave it commented for a single-node setup, but for multi-node configurations, uncomment it and specify the node addresses.
discovery.seed_hosts:
  - "10.0.0.1"
  - "10.0.0.2"
  - "10.0.0.3"
  1. plugins.security.nodes_dn – Lists the Distinguished Names (DNs) of certificates for all Wazuh indexer cluster nodes. Uncomment and modify these based on your settings and config.yml.
plugins.security.nodes_dn:
- "CN=node-1,OU=Wazuh,O=Wazuh,L=California,C=US"
- "CN=node-2,OU=Wazuh,O=Wazuh,L=California,C=US"
- "CN=node-3,OU=Wazuh,O=Wazuh,L=California,C=US"

Enable and start the Wazuh indexer service. Verify Wazuh indexer is active and running (exit with q)

systemctl daemon-reload
systemctl enable wazuh-indexer
systemctl start wazuh-indexer
systemctl status wazuh-indexer

Once all Wazuh indexer nodes are running, execute the indexer-security-init.sh script on any Wazuh indexer node. This updates the certificate information and initiates the cluster.

/usr/share/wazuh-indexer/bin/indexer-security-init.sh

The offline bundle initially uses temporary indexer credentials. Treat them as installation-only secrets, do not place them directly in shell history, and replace them during the security step before making the deployment available to other users.

Run the following commands to check that the installation is successful. The example uses the generated root CA instead of disabling certificate verification; adjust the certificate path if you stored the bundle elsewhere.

read -rp 'Temporary indexer username: ' INDEXER_USERNAME
read -rsp 'Temporary indexer password: ' INDEXER_PASSWORD; echo
curl --fail --show-error \
  --cacert /etc/wazuh-indexer/certs/root-ca.pem \
  --user "${INDEXER_USERNAME}:${INDEXER_PASSWORD}" \
  https://10.0.0.20:9200
unset INDEXER_PASSWORD
#Example output
{
  "name" : "node-1",
  "cluster_name" : "wazuh-cluster",
  "cluster_uuid" : "6hQpHd5cSzCLrhFo0T-Crg",
  "version" : {
    "number" : "7.10.2",
    "build_type" : "rpm",
    "build_hash" : "eee49cb340edc6c4d489bcd9324dda571fc8dc03",
    "build_date" : "2023-09-20T23:54:29.889267151Z",
    "build_snapshot" : false,
    "lucene_version" : "9.7.0",
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}

Install the Wazuh server

Run the following commands to import the Wazuh key and install the Wazuh manager.

RPM:

rpm --import ./wazuh-offline/wazuh-files/GPG-KEY-WAZUH
rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-manager*.rpm

DEB:

On systems with apt as package manager, the following dependencies must be installed on the Wazuh server nodes.

  • gnupg
  • apt-transport-https
dpkg -i ./wazuh-offline/wazuh-packages/wazuh-manager*.deb

Store the temporary Wazuh indexer username and password in the Wazuh manager keystore using the wazuh-keystore tool. Enter the values interactively so the password is not recorded in shell history. Replace these temporary credentials in the secure the Wazuh installation step.

read -rp 'Temporary indexer username: ' INDEXER_USERNAME
read -rsp 'Temporary indexer password: ' INDEXER_PASSWORD; echo
printf '%s' "$INDEXER_USERNAME" | /var/ossec/bin/wazuh-keystore -f indexer -k username
printf '%s' "$INDEXER_PASSWORD" | /var/ossec/bin/wazuh-keystore -f indexer -k password
unset INDEXER_PASSWORD

Enable and start the Wazuh manager service. Verify Wazuh manager is active and running (exit with q)

systemctl daemon-reload
systemctl enable wazuh-manager
systemctl start wazuh-manager
systemctl status wazuh-manager

Install Filebeat

Filebeat must be installed and configured on the same server as the Wazuh manager. Run the following command to install Filebeat.

RPM:

rpm -ivh ./wazuh-offline/wazuh-packages/filebeat*.rpm

DEB:

dpkg -i ./wazuh-offline/wazuh-packages/filebeat*.deb

Copy the configuration files to the correct location. When prompted, type "yes" to overwrite /etc/filebeat/filebeat.yml.

Note for CentOS: Remove &&\ from the command.

cp ./wazuh-offline/wazuh-files/filebeat.yml /etc/filebeat/ &&\
cp ./wazuh-offline/wazuh-files/wazuh-template.json /etc/filebeat/ &&\
chmod go+r /etc/filebeat/wazuh-template.json

Edit the /etc/filebeat/filebeat.yml configuration file and replace the following value:

hosts: The list of Wazuh indexer nodes to connect to. You can use either IP addresses or hostnames. By default, the host is set to localhost hosts: ["127.0.0.1:9200"]. Replace it with your Wazuh indexer address accordingly.

If you have more than one Wazuh indexer node, you can separate the addresses using commas. For example, hosts: ["10.0.0.1:9200", "10.0.0.2:9200", "10.0.0.3:9200"]

# Wazuh - Filebeat configuration file
 output.elasticsearch:
 hosts: ["10.0.0.20:9200"]
 protocol: https
 username: ${username}
 password: ${password}

Create a Filebeat keystore to securely store authentication credentials.

filebeat keystore create

Add the temporary indexer username and password to the Filebeat secrets keystore. Do not place the password in shell history; the commands below read it without echoing it.

printf '%s' 'admin' | filebeat keystore add username --stdin --force
read -rsp 'Temporary indexer password: ' INDEXER_PASSWORD
printf '%s' "$INDEXER_PASSWORD" | filebeat keystore add password --stdin --force
unset INDEXER_PASSWORD

Install the Wazuh module for Filebeat.

tar -xzf ./wazuh-offline/wazuh-files/wazuh-filebeat-0.4.tar.gz -C /usr/share/filebeat/module

Replace <SERVER_NODE_NAME> with your Wazuh server node certificate name, the same used in config.yml when creating the certificates. For example, wazuh-1. Then, move the certificates to their corresponding location.

NODE_NAME=<SERVER_NODE_NAME>
install -d -m 500 -o root -g root /etc/filebeat/certs
mv -n wazuh-install-files/$NODE_NAME.pem /etc/filebeat/certs/filebeat.pem
mv -n wazuh-install-files/$NODE_NAME-key.pem /etc/filebeat/certs/filebeat-key.pem
cp wazuh-install-files/root-ca.pem /etc/filebeat/certs/
chmod 500 /etc/filebeat/certs
chmod 400 /etc/filebeat/certs/*
chown -R root:root /etc/filebeat/certs

Enable and start the Filebeat service. Verify Filebeat is active and running (exit with q)

systemctl daemon-reload
systemctl enable filebeat
systemctl start filebeat
systemctl status filebeat

Run the following command to make sure Filebeat is successfully installed.

filebeat test output
#Example output
elasticsearch: https://10.0.0.20:9200...
  parse url... OK
  connection...
    parse host... OK
    dns lookup... OK
    addresses: 10.0.0.20
    dial up... OK
  TLS...
    security: server's certificate chain verification is enabled
    handshake... OK
    TLS version: TLSv1.3
    dial up... OK
  talk to server... OK
  version: 7.10.2

Wazuh server node is now successfully installed.

Install the Wazuh dashboard

RPM:

The following dependencies must be installed on the Wazuh dashboard node.

  • libcap
rpm --import ./wazuh-offline/wazuh-files/GPG-KEY-WAZUH
rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-dashboard*.rpm

DEB:

The following dependencies must be installed on the Wazuh dashboard node.

  • debhelper version 9 or later
  • tar
  • curl
  • libcap2-bin
dpkg -i ./wazuh-offline/wazuh-packages/wazuh-dashboard*.deb

Replace <DASHBOARD_NODE_NAME> with your Wazuh dashboard node name, the same used in config.yml to create the certificates. For example, dashboard. Then, move the certificates to their corresponding location.

NODE_NAME=<DASHBOARD_NODE_NAME>
install -d -m 500 -o wazuh-dashboard -g wazuh-dashboard /etc/wazuh-dashboard/certs
mv -n wazuh-install-files/$NODE_NAME.pem /etc/wazuh-dashboard/certs/dashboard.pem
mv -n wazuh-install-files/$NODE_NAME-key.pem /etc/wazuh-dashboard/certs/dashboard-key.pem
cp wazuh-install-files/root-ca.pem /etc/wazuh-dashboard/certs/
chmod 500 /etc/wazuh-dashboard/certs
chmod 400 /etc/wazuh-dashboard/certs/*
chown -R wazuh-dashboard:wazuh-dashboard /etc/wazuh-dashboard/certs

Edit the /etc/wazuh-dashboard/opensearch_dashboards.yml file and replace the following values:

  1. server.host: This setting specifies the host of the back end server. To allow remote users to connect, set the value to the IP address or DNS name of the Wazuh dashboard. The value 0.0.0.0 will accept all the available IP addresses of the host.
  2. opensearch.hosts: The URLs of the Wazuh indexer instances to use for all your queries. The Wazuh dashboard can be configured to connect to multiple Wazuh indexer nodes in the same cluster. The addresses of the nodes can be separated by commas. For example, ["https://10.0.0.2:9200", "https://10.0.0.3:9200","https://10.0.0.4:9200"]
server.host: 10.0.0.20
server.port: 443
opensearch.hosts: https://10.0.0.20:9200
opensearch.ssl.verificationMode: certificate

Enable and start the Wazuh dashboard. Verify Wazuh dashboard is active and running (exit with q)

systemctl daemon-reload
systemctl enable wazuh-dashboard
systemctl start wazuh-dashboard
systemctl status wazuh-dashboard

Edit the file /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml and replace the url value with the IP address or hostname of the Wazuh server master node.

hosts:
  - default:
      url: https://10.0.0.20
      port: 55000
      username: wazuh-wui
      password: wazuh-wui
      run_as: false

Access the web interface.

  • URL: https://
  • Username: admin
  • Password: admin

Browser certificate warning before importing the Wazuh dashboard certificate

Import the certificate

Upon the first access to the Wazuh dashboard, the browser shows a warning message stating that the certificate was not issued by a trusted authority. An exception can be added in the advanced options of the web browser or, for increased security, the root-ca.pem file previously generated can be imported to the certificate manager of the browser.

Copy /etc/wazuh-dashboard/certs/root-ca.pem to user’s home directory

cp /etc/wazuh-dashboard/certs/root-ca.pem ~/

Change ownership of user's home directory to the non-root user to enable read access to root-ca.pem

On Firefox, go to Settings, Privacy & Security and Certificates. Click View Certificates.

Wazuh dashboard certificate details in the browser

Click Import, select root-ca.pem in user’s home directory. Select Trust this CA to identify website and email users. Click OK.

Trusted Wazuh dashboard certificate after import

Delete root-ca.pem from user’s home directory.

rm -f "$HOME/root-ca.pem"

Secure the Wazuh installation

You have now installed and configured all the Wazuh central components. We recommend changing the default credentials to protect your infrastructure from possible attacks.

Use the Wazuh passwords tool to change all the internal users passwords.

/usr/share/wazuh-indexer/plugins/opensearch-security/tools/wazuh-passwords-tool.sh --api --change-all --admin-user wazuh --admin-password wazuh

Save the new Wazuh indexer password into the Wazuh manager keystore. Restart Wazuh manager service.

/var/ossec/bin/wazuh-keystore -f indexer -k password -v '<NEW_INDEXER_PASSWORD>'
systemctl restart wazuh-manager
systemctl status wazuh-manager

Add the new password to the Filebeat secrets keystore. Restart the Filebeat service

printf '%s' '<NEW_INDEXER_PASSWORD>' | filebeat keystore add password --stdin --force
systemctl restart filebeat
filebeat test output

Verify that new password has been added to /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml. Restart the Wazuh dashboard.

nano /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml
systemctl restart wazuh-dashboard
systemctl status wazuh-dashboard

Checkpoint: verify the central services

Check each service separately:

sudo systemctl status wazuh-indexer
sudo systemctl status wazuh-manager
sudo systemctl status filebeat
sudo systemctl status wazuh-dashboard

Expected: every required service reports active (running). Then test Filebeat output and open the dashboard from an authorised workstation. If a check fails, inspect that service's journal before changing unrelated configuration.

Completion criteriaThe central services are healthy, Filebeat can reach the indexer, the dashboard opens, and default credentials have been replaced.

↑ Back to Wazuh journey map