Install Wazuh components step by step

Run these steps on each offline host, in the directory where you copied the files in step 6 of Download the packages and configuration files.

All-in-one deployment

An all-in-one deployment doesn't use wazuh-install-files.tar. The Wazuh packages create the root CA, the certificates, and the passwords on the host. Follow these steps:

  1. Decompress wazuh-offline.tar.gz and check the package signatures, as Preparing the packages describes.

  2. Follow All-in-one deployment in the Installation guide with these changes: skip Adding the Wazuh repository and Disable Wazuh updates. Check that the listed dependencies are installed with rpm -q (DEB: dpkg -s) instead of installing them, and bring any missing one as Prerequisites describes. Where the guide installs a package, run rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-indexer*.rpm (DEB: dpkg -i ./wazuh-offline/wazuh-packages/wazuh-indexer*.deb), and the same for wazuh-manager and wazuh-dashboard.

  3. When the Wazuh dashboard runs, come back to this guide. Continue with Securing your Wazuh installation of this guide, instead of the section with the same name in the Installation guide, and then read Running Wazuh offline.

Preparing the packages

  1. Decompress the installation files. For an all-in-one deployment, decompress only wazuh-offline.tar.gz.

    # umask 022
    # tar xf wazuh-offline.tar.gz
    # tar xf wazuh-install-files.tar
    

    wazuh-install-files.tar holds root-ca.pem, the certificates of every node in config.yml, and credentials.env with the five passwords. Place them on each node before you install its package. The package then uses them instead of generating its own.

  2. Verify the package signatures with the Wazuh key that wazuh-offline.tar.gz carries, wazuh-offline/GPG-KEY-WAZUH. These commands need gnupg, and binutils on DEB systems. Don't install a package that fails these checks.

    • Check that the fingerprint of the key is 0DCF CA55 47B1 9D2A 6099 5060 96B3 EE5F 2911 1145:

      # gpg --show-keys --with-fingerprint wazuh-offline/GPG-KEY-WAZUH
      

    Every package must show Signature, key ID 29111145: OK. rpm -K alone also passes on an unsigned package, so check the key ID.

    # rpm --import wazuh-offline/GPG-KEY-WAZUH
    # for p in wazuh-offline/wazuh-packages/*.rpm; do echo "$p"; rpm -Kv "$p" | grep -i signature; done
    

Installing the Wazuh indexer

Install and configure the Wazuh indexer on each indexer node. Before installing it, install the following dependencies, if missing, from your local package mirror, installation media, or copied packages (see Prerequisites):

  • coreutils

  • diffutils

  • hostname

  • iproute

  • openssl

  • procps-ng

  • shadow-utils

  • util-linux

  1. Place the passwords, the root CA certificate, and the certificates of this node before installing the package. Replace <INDEXER_NODE_NAME> with the name of the node as defined in config.yml, for example, indexer.

    # NODE_NAME=<INDEXER_NODE_NAME>
    
    # install -d -m 0750 -o root -g root /etc/wazuh-indexer /etc/wazuh-indexer/ca
    # install -m 0640 wazuh-install-files/root-ca.pem /etc/wazuh-indexer/ca/root-ca.pem
    # install -m 0600 /dev/null /etc/wazuh-indexer/local.env
    # grep '^WAZUH_INDEXER_' wazuh-install-files/credentials.env > /etc/wazuh-indexer/local.env
    # install -d -m 0750 /etc/wazuh-indexer/certs
    # install -m 0640 wazuh-install-files/$NODE_NAME.pem /etc/wazuh-indexer/certs/indexer.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-key.pem /etc/wazuh-indexer/certs/indexer-key.pem
    # install -m 0600 wazuh-install-files/admin.pem /etc/wazuh-indexer/certs/admin.pem
    # install -m 0600 wazuh-install-files/admin-key.pem /etc/wazuh-indexer/certs/admin-key.pem
    
  2. Install the Wazuh indexer package. The package uses the passwords and certificates you placed. It gives the node certificate, its key, and the root CA certificate to root, with the wazuh-indexer group. The admin certificate and its key stay readable by root only. Don't install it before placing them. Placing them afterwards doesn't configure the node.

    # rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-indexer*.rpm
    
  3. Edit /etc/wazuh-indexer/opensearch.yml and replace the following values:

    • network.host: Sets the address of this node for both HTTP and transport traffic. The node will bind to this address and will also use it as its publish address. Accepts an IP address or a hostname. Use the same node address set in the config.yml file to create the SSL certificates.

    • node.name: Name of the Wazuh indexer node as defined in the config.yml file. For example, indexer.

    • cluster.initial_cluster_manager_nodes: List of the names of the master-eligible nodes. These names are defined in the config.yml file. Replace the node-1 entry the package wrote, and add one line per node, according to your config.yml file definitions.

      cluster.initial_cluster_manager_nodes:
      - "indexer"
      - "indexer-2"
      - "indexer-3"
      
    • discovery.seed_hosts: List of the addresses of the master-eligible nodes. Each element can be either an IP address or a hostname. You can leave this setting commented if you are configuring the Wazuh indexer as a single-node. For multi-node configurations, uncomment this setting and set your master-eligible node addresses.

      discovery.seed_hosts:
        - "10.0.0.1"
        - "10.0.0.2"
        - "10.0.0.3"
      
    • plugins.security.nodes_dn: List of the Distinguished Names of the certificates of all the Wazuh indexer cluster nodes. The package writes only one line. Replace it with one line per Wazuh indexer node, using the names from your config.yml file in this order. Leave plugins.security.authcz.admin_dn as the package wrote it.

      plugins.security.nodes_dn:
      - "C=US,L=California,O=Wazuh,OU=Wazuh,CN=indexer"
      - "C=US,L=California,O=Wazuh,OU=Wazuh,CN=indexer-2"
      - "C=US,L=California,O=Wazuh,OU=Wazuh,CN=indexer-3"
      
  4. Set the Java heap of the Wazuh indexer. The package sets 1 GB, which isn't enough. The Wazuh dashboard then fails on its first start with circuit_breaking_exception. Use half of the host memory on a dedicated Wazuh indexer node. Use one quarter when the Wazuh manager and Wazuh dashboard share the host, by changing / 2 to / 4:

    # HEAP_MB=$(( $(free -m | awk 'NR == 2 {print $2}') / 2 ))
    # sed -i -e "s/^-Xms.*/-Xms${HEAP_MB}m/" -e "s/^-Xmx.*/-Xmx${HEAP_MB}m/" /etc/wazuh-indexer/jvm.options
    
  5. Enable and start the Wazuh indexer service.

    # systemctl daemon-reload
    # systemctl enable wazuh-indexer
    # systemctl start wazuh-indexer
    
  6. For multi-node clusters, repeat the previous steps on every Wazuh indexer node.

  7. After all Wazuh indexer nodes are running, run indexer-security-init.sh once, on any one of them. It loads the users of that node into the security index, which replaces the users of every other node, and starts the cluster.

    # /usr/share/wazuh-indexer/bin/indexer-security-init.sh
    
  8. Check that every Wazuh indexer node joined the cluster and that its status is green. Replace <WAZUH_INDEXER_ADDRESS> with the address of a Wazuh indexer node. When curl asks for the password, enter the WAZUH_INDEXER_ADMIN_PASSWORD value that the first command shows.

    # grep '^WAZUH_INDEXER_ADMIN_PASSWORD=' /etc/wazuh-indexer/export/credentials.env | cut -d= -f2-
    # curl --cacert /etc/wazuh-indexer/export/ca.pem -u admin https://<WAZUH_INDEXER_ADDRESS>:9200/_cat/nodes?v
    # curl --cacert /etc/wazuh-indexer/export/ca.pem -u admin https://<WAZUH_INDEXER_ADDRESS>:9200/_cluster/health?pretty
    

Installing the Wazuh manager

Install and configure the Wazuh manager on each manager node. Before installing it, install the following dependencies, if missing:

  • coreutils

  • shadow-utils

  1. Place the passwords, the root CA certificate, and the certificates of this node before installing the package. Replace <MANAGER_NODE_NAME> with the name of the node as defined in config.yml, for example, manager.

    # NODE_NAME=<MANAGER_NODE_NAME>
    
    # install -d -m 0750 -o root -g root /etc/wazuh-manager /etc/wazuh-manager/certs
    # install -d -m 0700 -o root -g root /etc/wazuh-manager/ca
    # install -m 0644 wazuh-install-files/root-ca.pem /etc/wazuh-manager/ca/root-ca.pem
    # install -m 0600 /dev/null /etc/wazuh-manager/local.env
    # grep -E '^(WAZUH_MANAGER_API_PASSWORD|WAZUH_MANAGER_WUI_PASSWORD|WAZUH_INDEXER_MANAGER_PASSWORD)=' wazuh-install-files/credentials.env > /etc/wazuh-manager/local.env
    # install -m 0640 wazuh-install-files/root-ca.pem /etc/wazuh-manager/certs/root-ca.pem
    # install -m 0640 wazuh-install-files/root-ca.pem /etc/wazuh-manager/certs/indexer-ca.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME.pem /etc/wazuh-manager/certs/indexer-connector.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-key.pem /etc/wazuh-manager/certs/indexer-connector-key.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-remoted.pem /etc/wazuh-manager/certs/remoted.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-remoted-key.pem /etc/wazuh-manager/certs/remoted-key.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-apid.pem /etc/wazuh-manager/certs/apid.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-apid-key.pem /etc/wazuh-manager/certs/apid-key.pem
    

    The root CA of the deployment also signed the Wazuh indexer certificates, so it is placed as indexer-ca.pem too. remoted.pem is the agent listener certificate, served on port 1517 and reused by enrollment on port 1515. apid.pem is the Wazuh manager API certificate. Without either pair, the Wazuh manager doesn't start.

  2. Install the Wazuh manager package. The package uses the files you placed instead of issuing its own, and gives the remoted and apid pairs their owner.

    # rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-manager*.rpm
    
  3. Check the credentials. On RPM systems, the installation prints UNSAFE /etc/wazuh-manager/certs/<FILE>.pem: group is root, not wazuh-manager for the files you placed. The package fixes the owner at the end of the installation, and nothing needs to be done. The check must end with no problem found. In a distributed deployment, it also warns that the dashboard client pair was not generated, which is expected:

    # /var/wazuh-manager/bin/wazuh-manager-resolve-credentials --check -H /var/wazuh-manager
    
  4. Check that the agent listener certificate comes from the deployment's root CA. Agents reject a Wazuh manager node whose certificate fails this check:

    # openssl verify -CAfile /etc/wazuh-manager/certs/root-ca.pem /etc/wazuh-manager/certs/remoted.pem
    
  5. In the <indexer> block of /etc/wazuh-manager/wazuh-manager.conf, replace 127.0.0.1 with the addresses of the Wazuh indexer nodes, one <host> entry per node. Do it on every Wazuh manager node, because the cluster doesn't synchronize this block. Leave the <ssl> settings as the package wrote them. The credentials aren't set here. The package stored them in the Wazuh manager keystore.

    <indexer>
      <hosts>
        <host>https://<WAZUH_INDEXER_1_IP_ADDRESS>:9200</host>
        <host>https://<WAZUH_INDEXER_2_IP_ADDRESS>:9200</host>
      </hosts>
      ...
    </indexer>
    
  6. Enable and start the Wazuh manager service, first on the master node and then on the worker nodes. A fresh installation doesn't start the service by itself.

    # systemctl daemon-reload
    # systemctl enable wazuh-manager
    # systemctl start wazuh-manager
    
  7. Run the following commands to verify that the Wazuh manager status is active and that it reaches the Wazuh indexer:

    # systemctl status wazuh-manager
    
    # grep 'indexer is reachable' /var/wazuh-manager/logs/wazuh-manager.log | tail -1
    

Wazuh cluster configuration for multi-node deployment

After completing the installation of the Wazuh manager on every node, you must configure one manager node as the master and the rest as workers. If you have only one Wazuh manager node, skip this section and go to Installing the Wazuh dashboard. wazuh-install-files.tar holds a clusterkey file only when config.yml lists more than one Wazuh manager node.

On every node, the package writes a <cluster> block with its own random key, node_type master, and bind_addr 127.0.0.1. Replace the whole block on each node.

Configuring the Wazuh manager master node

  1. Edit the following settings in the /etc/wazuh-manager/wazuh-manager.conf configuration file. Replace <CLUSTER_KEY> with the key in wazuh-install-files/clusterkey, which the following command shows, and <WAZUH_MASTER_ADDRESS> with the IP address of the master node.

    # cat wazuh-install-files/clusterkey
    
    <cluster>
      <name>wazuh</name>
      <node_name>master-node</node_name>
      <node_type>master</node_type>
      <key><CLUSTER_KEY></key>
      <port>1516</port>
      <bind_addr>0.0.0.0</bind_addr>
      <nodes>
        <node><WAZUH_MASTER_ADDRESS></node>
      </nodes>
      <hidden>no</hidden>
    </cluster>
    

    Parameters to be configured:

    Parameter

    Description

    name

    It indicates the name of the cluster.

    node_name

    It indicates the name of the current node.

    node_type

    It specifies the role of the node. It has to be set to master.

    key

    Key that is used to encrypt communication between cluster nodes. Use the key in wazuh-install-files/clusterkey, the same on every node.

    port

    It indicates the destination port for cluster communication.

    bind_addr

    It is the network IP to which the node is bound to listen for incoming requests (0.0.0.0 for any IP).

    nodes

    It is the address of the master node and can be either an IP or a DNS. This parameter must be specified in all nodes, including the master itself.

    hidden

    It shows or hides the cluster information in the generated alerts.

  2. Restart the Wazuh manager.

    # systemctl restart wazuh-manager
    

    Repeat these configuration steps for every Wazuh manager worker node in your cluster, with <node_type>worker</node_type>, a unique <node_name>, the same <key>, and <WAZUH_MASTER_ADDRESS> in <nodes>.

Testing the Wazuh manager cluster

To verify that the Wazuh cluster is enabled and all the nodes are connected, run the following command:

# /var/wazuh-manager/bin/cluster_control -l

The command returns output similar to the following example:

NAME          TYPE    VERSION  ADDRESS
master-node   master  5.0.0    10.0.0.3
worker-node1  worker  5.0.0    10.0.0.4
worker-node2  worker  5.0.0    10.0.0.5

Note that 10.0.0.3, 10.0.0.4, 10.0.0.5 are example IPs.

Installing the Wazuh dashboard

Install and configure the Wazuh dashboard node. Before installing it, install the following dependencies, if missing:

  • diffutils

  • libcap

  • openssl

  • shadow-utils

  • util-linux

  1. Place the passwords, the root CA certificate, and the certificate of this node before installing the package. Replace <DASHBOARD_NODE_NAME> with the name of the node as defined in config.yml, for example, dashboard.

    # NODE_NAME=<DASHBOARD_NODE_NAME>
    
    # install -d -m 0750 -o root -g root /etc/wazuh-dashboard /etc/wazuh-dashboard/certs
    # install -m 0600 /dev/null /etc/wazuh-dashboard/local.env
    # grep -E '^(WAZUH_INDEXER_KIBANASERVER_PASSWORD|WAZUH_MANAGER_WUI_PASSWORD)=' wazuh-install-files/credentials.env > /etc/wazuh-dashboard/local.env
    # install -m 0640 wazuh-install-files/$NODE_NAME.pem /etc/wazuh-dashboard/certs/dashboard.pem
    # install -m 0640 wazuh-install-files/$NODE_NAME-key.pem /etc/wazuh-dashboard/certs/dashboard-key.pem
    # install -m 0640 wazuh-install-files/root-ca.pem /etc/wazuh-dashboard/certs/indexer-ca.pem
    # install -m 0640 wazuh-install-files/root-ca.pem /etc/wazuh-dashboard/certs/manager-ca.pem
    

    The root CA of the deployment signed the Wazuh indexer and the Wazuh manager certificates, so it is placed as indexer-ca.pem and manager-ca.pem.

  2. Install the Wazuh dashboard package.

    # rpm -ivh ./wazuh-offline/wazuh-packages/wazuh-dashboard*.rpm
    
  3. Check the ownership of the certificates. The package gives the certificates you placed to root with the wazuh-dashboard group, with mode 0750 for the directory and 0640 for the files. It keeps local.env readable by root only, with owner root:root and mode 0600. Don't give them to the wazuh-dashboard user. The Wazuh dashboard refuses to start when a file in /etc/wazuh-dashboard/certs isn't owned by root or is writable by its group or others.

    # ls -ld /etc/wazuh-dashboard/certs /etc/wazuh-dashboard/certs/*
    
  4. Edit the /etc/wazuh-dashboard/opensearch_dashboards.yml file. The package already configures server.host, server.port, and opensearch.ssl.verificationMode. Verify these values and update only opensearch.hosts and wazuh_core.hosts.default.url:

    server.host: 0.0.0.0
    server.port: 443
    opensearch.hosts: ["https://<WAZUH_INDEXER_1_IP_ADDRESS>:9200", "https://<WAZUH_INDEXER_2_IP_ADDRESS>:9200"]
    opensearch.ssl.verificationMode: full
    wazuh_core.hosts:
      default:
        url: https://<WAZUH_MASTER_ADDRESS>
        port: 55000
        username: wazuh-internal-client
        run_as: true
        ca: '/etc/wazuh-dashboard/certs/manager-ca.pem'
    
    • server.host: This setting specifies the host of the Wazuh dashboard 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 accepts all available IP addresses on the host.

    • opensearch.hosts: The URLs of the Wazuh indexer nodes. Set this value to the Wazuh indexer node addresses, even when all components share the same host. The addresses of the nodes are separated by commas.

    • wazuh_core.hosts: The Wazuh manager API that the dashboard queries. url must point to the Wazuh manager API on the master node, the only node that runs it. Use one of the addresses in the master node's apid.pem certificate. Don't set a password. The package stored the wazuh-internal-client password in the Wazuh dashboard keystore, and the keystore value takes precedence over a password in this file. Leave run_as and ca as the package wrote them.

  5. Enable and start the Wazuh dashboard service.

    # systemctl daemon-reload
    # systemctl enable wazuh-dashboard
    # systemctl start wazuh-dashboard
    
  6. Run the following command to verify the Wazuh dashboard service is active.

    # systemctl status wazuh-dashboard
    
  7. Access the Wazuh web interface.

    • URL: https://<WAZUH_DASHBOARD_ADDRESS>

    • Username: admin

    • Password: the WAZUH_INDEXER_ADMIN_PASSWORD value in wazuh-install-files/credentials.env.

    When you first access the Wazuh dashboard, your browser displays a warning that a trusted authority didn't issue the certificate. You can add an exception in the browser's advanced options. For better security, import the deployment's root CA into the browser's certificate manager instead. It's wazuh-install-files/root-ca.pem, the same file as /etc/wazuh-dashboard/certs/indexer-ca.pem. You can also configure a certificate from a trusted authority. The certificate names only the Wazuh dashboard addresses in config.yml. To reach the dashboard by another address or DNS name without the warning, add it to the dashboard node's ip or dns list in config.yml. Do this before you run -g.