Wazuh 4.14 Offline Installation - Air-Gapped Guide

Offline installation enables Wazuh 4.14 deployment in air-gapped networks without internet connectivity. All required packages, dependencies, and scripts are downloaded in advance on an internet-connected host, transferred to the target servers, and installed from local storage.

Procedure overview

The offline installation process consists of the following stages:

  1. Download packages and dependencies on an internet-connected host
  2. Transfer files to the target servers
  3. Configure a local repository
  4. Generate TLS certificates
  5. Install components in the correct order
  6. Validate the deployment

Prerequisites

Download host (internet-connected)

  • Any Linux system with internet access
  • Utilities: curl, tar, gpg
  • At least 5 GB of free disk space

Target servers (no internet)

  • A 64-bit OS from the supported list
  • Minimum 4 CPU cores and 8 GB RAM for all-in-one
  • Open ports between nodes: 1514, 1515, 9200, 443, 55000
  • A file transfer method (USB, SCP over local network, NFS)

Downloading packages

Automated download

Wazuh provides a script for downloading all required files automatically:

curl -sO https://packages.wazuh.com/4.14/wazuh-offline.tar.gz

This archive contains:

  • Wazuh Indexer, Manager, and Dashboard packages for supported operating systems
  • Repository GPG keys
  • Configuration files
  • Installation script

Manual package download

For selective downloads, retrieve only the packages you need.

For Debian/Ubuntu:

mkdir -p wazuh-offline/deb

# Wazuh Indexer
curl -sO https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-indexer/wazuh-indexer_4.14.3-1_amd64.deb \
  -o wazuh-offline/deb/

# Wazuh Manager
curl -sO https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-manager/wazuh-manager_4.14.3-1_amd64.deb \
  -o wazuh-offline/deb/

# Wazuh Dashboard
curl -sO https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-dashboard/wazuh-dashboard_4.14.3-1_amd64.deb \
  -o wazuh-offline/deb/

# Filebeat
curl -sO https://packages.wazuh.com/4.x/apt/pool/main/f/filebeat/filebeat-oss-7.10.2-amd64.deb \
  -o wazuh-offline/deb/

For RHEL/CentOS:

mkdir -p wazuh-offline/rpm

curl -sO https://packages.wazuh.com/4.x/yum/wazuh-indexer-4.14.3-1.x86_64.rpm \
  -o wazuh-offline/rpm/

curl -sO https://packages.wazuh.com/4.x/yum/wazuh-manager-4.14.3-1.x86_64.rpm \
  -o wazuh-offline/rpm/

curl -sO https://packages.wazuh.com/4.x/yum/wazuh-dashboard-4.14.3-1.x86_64.rpm \
  -o wazuh-offline/rpm/

Download the GPG key

curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH -o wazuh-offline/GPG-KEY-WAZUH

Download Filebeat configuration

curl -sO https://packages.wazuh.com/4.x/filebeat/wazuh-filebeat-0.4.tar.gz \
  -o wazuh-offline/wazuh-filebeat-0.4.tar.gz

Transferring to target servers

Bundle all downloaded files:

tar czf wazuh-offline-bundle.tar.gz wazuh-offline/

Transfer the archive to target servers using any available method:

  • USB drive: copy to USB media, physically transport
  • SCP over local network: scp wazuh-offline-bundle.tar.gz user@target:/tmp/
  • NFS mount: copy to a shared directory

On the target server, extract the archive:

tar xzf /tmp/wazuh-offline-bundle.tar.gz -C /tmp/

Configuring a local repository

For Debian/Ubuntu

Create a local APT repository:

mkdir -p /var/local/wazuh-repo

cp /tmp/wazuh-offline/deb/*.deb /var/local/wazuh-repo/

cd /var/local/wazuh-repo
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz

Add the repository to APT:

echo "deb [trusted=yes] file:///var/local/wazuh-repo ./" > /etc/apt/sources.list.d/wazuh-local.list
apt-get update

For RHEL/CentOS

Create a local YUM repository:

mkdir -p /var/local/wazuh-repo

cp /tmp/wazuh-offline/rpm/*.rpm /var/local/wazuh-repo/

createrepo /var/local/wazuh-repo/

If createrepo is not installed, install it beforehand or include it in the offline bundle:

yum install createrepo_c

Add the repository:

cat > /etc/yum.repos.d/wazuh-local.repo << 'EOF'
[wazuh-local]
name=Wazuh Local Repository
baseurl=file:///var/local/wazuh-repo/
enabled=1
gpgcheck=0
EOF

Certificate generation

Download the generation script

On the internet-connected host, download the script and configuration template:

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

Configure config.yml

Edit config.yml to specify the names and IP addresses of all nodes:

nodes:
  indexer:
    - name: wazuh-indexer-1
      ip: 192.168.1.10
  server:
    - name: wazuh-manager-1
      ip: 192.168.1.20
  dashboard:
    - name: wazuh-dashboard-1
      ip: 192.168.1.30

For a multi-node configuration, list all nodes:

nodes:
  indexer:
    - name: wazuh-indexer-1
      ip: 192.168.1.10
    - name: wazuh-indexer-2
      ip: 192.168.1.11
    - name: wazuh-indexer-3
      ip: 192.168.1.12
  server:
    - name: wazuh-manager-master
      ip: 192.168.1.20
      node_type: master
    - name: wazuh-manager-worker
      ip: 192.168.1.21
      node_type: worker
  dashboard:
    - name: wazuh-dashboard-1
      ip: 192.168.1.30

Generate the certificates

bash wazuh-certs-tool.sh -A

The script creates a wazuh-certificates/ directory containing all required certificates. Transfer it to the target servers alongside the packages.

Distribute certificates

On each target server, copy the appropriate certificates:

# On the indexer node
mkdir -p /etc/wazuh-indexer/certs
cp wazuh-certificates/root-ca.pem /etc/wazuh-indexer/certs/
cp wazuh-certificates/wazuh-indexer-1.pem /etc/wazuh-indexer/certs/indexer.pem
cp wazuh-certificates/wazuh-indexer-1-key.pem /etc/wazuh-indexer/certs/indexer-key.pem
chmod 400 /etc/wazuh-indexer/certs/*
chown -R wazuh-indexer:wazuh-indexer /etc/wazuh-indexer/certs

Step-by-step installation

The installation order is strict. Installing components out of sequence causes errors.

1. Install Wazuh Indexer

# Debian/Ubuntu
apt-get install wazuh-indexer

# RHEL/CentOS
yum install wazuh-indexer

Configure /etc/wazuh-indexer/opensearch.yml:

cluster.name: wazuh-cluster
node.name: wazuh-indexer-1
network.host: 0.0.0.0
node.master: true
node.data: true

plugins.security.ssl.transport.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.transport.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem

plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.http.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem

Start and initialize:

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

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

Verification:

curl -sk -u admin:admin https://localhost:9200/_cluster/health?pretty

2. Install Wazuh Manager

# Debian/Ubuntu
apt-get install wazuh-manager

# RHEL/CentOS
yum install wazuh-manager

Install Filebeat:

# Debian/Ubuntu
dpkg -i /tmp/wazuh-offline/deb/filebeat-oss-*.deb

# RHEL/CentOS
rpm -ivh /tmp/wazuh-offline/rpm/filebeat-oss-*.rpm

Configure Filebeat to forward data to the indexer:

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

Edit /etc/filebeat/filebeat.yml:

output.elasticsearch:
  hosts: ["https://192.168.1.10:9200"]
  username: admin
  password: admin
  ssl.certificate_authorities:
    - /etc/filebeat/certs/root-ca.pem
  ssl.certificate: /etc/filebeat/certs/filebeat.pem
  ssl.key: /etc/filebeat/certs/filebeat-key.pem

Start the services:

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

3. Install Wazuh Dashboard

# Debian/Ubuntu
apt-get install wazuh-dashboard

# RHEL/CentOS
yum install wazuh-dashboard

Configure /etc/wazuh-dashboard/opensearch_dashboards.yml:

server.host: 0.0.0.0
server.port: 443
opensearch.hosts: ["https://192.168.1.10:9200"]
opensearch.ssl.certificateAuthorities: ["/etc/wazuh-dashboard/certs/root-ca.pem"]
server.ssl.enabled: true
server.ssl.certificate: "/etc/wazuh-dashboard/certs/dashboard.pem"
server.ssl.key: "/etc/wazuh-dashboard/certs/dashboard-key.pem"

Start the service:

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

Access the dashboard at https://<ip-address>:443.

Offline agent installation

Download agent packages

On the internet-connected host, download the package for the required OS:

# Linux DEB
curl -sO https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.14.3-1_amd64.deb

# Linux RPM
curl -sO https://packages.wazuh.com/4.x/yum/wazuh-agent-4.14.3-1.x86_64.rpm

# Windows
curl -sO https://packages.wazuh.com/4.x/windows/wazuh-agent-4.14.3-1.msi

Install on the target host

# Debian/Ubuntu
WAZUH_MANAGER="192.168.1.20" dpkg -i wazuh-agent_4.14.3-1_amd64.deb

# RHEL/CentOS
WAZUH_MANAGER="192.168.1.20" rpm -ivh wazuh-agent-4.14.3-1.x86_64.rpm

Start the agent:

systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent

Updating in offline mode

Preparing an update

  1. Download the new version packages on the internet-connected host
  2. Transfer the packages to target servers
  3. Update the local repository

Update order

Updates are performed in reverse order:

  1. Agents
  2. Manager
  3. Indexer
  4. Dashboard

Updating a component

# Debian/Ubuntu
apt-get install --only-upgrade wazuh-indexer
systemctl restart wazuh-indexer

# RHEL/CentOS
yum update wazuh-indexer
systemctl restart wazuh-indexer

Before updating the indexer, create a data backup:

curl -sk -u admin:admin \
  -X PUT "https://localhost:9200/_snapshot/backup/pre-upgrade" \
  -H "Content-Type: application/json" \
  -d '{"indices":"wazuh-*"}'

Troubleshooting

Package not found in local repository

Symptoms: error Unable to locate package or No package available.

Solution:

  1. Check the repository contents:
ls -la /var/local/wazuh-repo/
  1. For Debian/Ubuntu, rebuild the package index:
cd /var/local/wazuh-repo
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
apt-get update
  1. For RHEL/CentOS, regenerate the metadata:
createrepo --update /var/local/wazuh-repo/
yum clean all && yum makecache

Certificate errors when connecting components

Symptoms: logs show ssl_exception errors; components cannot establish TLS connections.

Solution:

  1. Verify that all components use certificates from the same CA:
openssl x509 -in /etc/wazuh-indexer/certs/root-ca.pem -text -noout | grep Issuer
  1. Confirm that the SAN in the certificate matches the node IP address:
openssl x509 -in /etc/wazuh-indexer/certs/indexer.pem -text -noout | grep -A1 "Subject Alternative Name"
  1. Check file permissions on the certificate files

Indexer fails to start

Symptoms: the wazuh-indexer service does not start; logs contain JVM or filesystem errors.

Solution:

  1. Check vm.max_map_count:
sysctl vm.max_map_count

If the value is below 262144, increase it:

sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
  1. Verify data directory ownership:
chown -R wazuh-indexer:wazuh-indexer /var/lib/wazuh-indexer
  1. Review logs:
journalctl -u wazuh-indexer -n 100

Filebeat not sending data to the indexer

Symptoms: alerts do not appear in the dashboard even though the manager is running.

Solution:

  1. Check Filebeat status:
systemctl status filebeat
filebeat test output
  1. Verify the indexer address in /etc/filebeat/filebeat.yml

  2. Test connectivity manually:

curl -sk -u admin:admin https://192.168.1.10:9200

Additional resources

Last updated on