# Wazuh 4.14 Offline Installation - Air-Gapped Guide

> Install Wazuh 4.14 without internet access - download packages, set up a local repository, generate certificates, step-by-step offline setup and upgrades

Source: https://opennix.org/en/docs/wazuh/deployment/wazuh-offline-installation/


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](/docs/wazuh/installation/)
- 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:

```bash
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:

```bash
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:

```bash
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

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

### Download Filebeat configuration

```bash
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:

```bash
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:

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

## Configuring a local repository

### For Debian/Ubuntu

Create a local APT repository:

```bash
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:

```bash
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:

```bash
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:

```bash
yum install createrepo_c
```

Add the repository:

```bash
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:

```bash
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:

```yaml
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:

```yaml
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
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:

```bash
# 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

```bash
# Debian/Ubuntu
apt-get install wazuh-indexer

# RHEL/CentOS
yum install wazuh-indexer
```

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

```yaml
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:

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

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

Verification:

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

### 2. Install Wazuh Manager

```bash
# Debian/Ubuntu
apt-get install wazuh-manager

# RHEL/CentOS
yum install wazuh-manager
```

Install Filebeat:

```bash
# 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:

```bash
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`:

```yaml
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:

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

### 3. Install Wazuh Dashboard

```bash
# Debian/Ubuntu
apt-get install wazuh-dashboard

# RHEL/CentOS
yum install wazuh-dashboard
```

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

```yaml
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:

```bash
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:

```bash
# 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

```bash
# 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:

```bash
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

```bash
# 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:

```bash
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:

```bash
ls -la /var/local/wazuh-repo/
```

2. For Debian/Ubuntu, rebuild the package index:

```bash
cd /var/local/wazuh-repo
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
apt-get update
```

3. For RHEL/CentOS, regenerate the metadata:

```bash
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:

```bash
openssl x509 -in /etc/wazuh-indexer/certs/root-ca.pem -text -noout | grep Issuer
```

2. Confirm that the SAN in the certificate matches the node IP address:

```bash
openssl x509 -in /etc/wazuh-indexer/certs/indexer.pem -text -noout | grep -A1 "Subject Alternative Name"
```

3. 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`:

```bash
sysctl vm.max_map_count
```

If the value is below 262144, increase it:

```bash
sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
```

2. Verify data directory ownership:

```bash
chown -R wazuh-indexer:wazuh-indexer /var/lib/wazuh-indexer
```

3. Review logs:

```bash
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:

```bash
systemctl status filebeat
filebeat test output
```

2. Verify the indexer address in `/etc/filebeat/filebeat.yml`

3. Test connectivity manually:

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

## Additional resources

- [Deployment options overview](/docs/wazuh/deployment/)
- [Wazuh installation - step-by-step guide](/docs/wazuh/installation/)
- [Wazuh quickstart](/docs/wazuh/installation/wazuh-quickstart/)
- [Wazuh Ansible deployment](/docs/wazuh/deployment/wazuh-ansible-deployment/)

