Unhealthy Romance: Part 2 (When love and hate collide)
# Installing Wazuh (v4.9.0) on Debian 13 Without the Installer Script - Part 2
When we last left our manual deployment of Wazuh v4.9.0 on Debian 13 (Trixie), we had successfully broken the circular authentication loop preventing the frontend dashboard from talking to our underlying database indexer. But in security operations, breaking one loop only clears the path to the next battle.
In this entry, we are documenting the actual mechanics of bridging the manager to a fleet of remote agents over a secure Tailscale overlay network.
---
## Prologue: The Silicon Museum
Before diving into the network commands, it's worth highlighting why we are documenting this in such painstaking detail. Many engineering tutorials assume you are working with clean, identical cloud instances deployed with a click of a button. Our reality is a **Silicon Museum**.
The newest, most modern machine in our five-node agent configuration is already **9 years old** (circa 2017). The oldest endpoint in the cluster still spinning real platter disks and executing instructions is **23 years old** (built in 2003!).
Deploying a modern, enterprise-grade SIEM stack with heavy Java Virtual Machine dependencies, elastic indexes, and active-response daemons on physical bare metal that spans nearly a quarter-century of computing history is not just an aesthetic challenge. It is a battle of resource optimization, software compilation tricks, and precise configuration adjustments.
---
## I. The TLS SAN Trap (Why the External Browser Stalled)
Once the core service was running, the dashboard was responsive locally over loopback (127.0.0.1). However, attempting to reach it from a remote terminal resulted in a silent, indefinite hang.
```text
subject=C=US, L=California, O=Wazuh, OU=Wazuh, CN=dashboard
X509v3 Subject Alternative Name:
IP Address:127.0.0.1
```
**The Fix: Manual Certificate Generation Without Wildcards**
```bash
sudo mkdir -p /etc/wazuh-dashboard/certs
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/wazuh-dashboard/certs/dashboard-key.pem -out /etc/wazuh-dashboard/certs/dashboard.pem -subj "/C=US/L=California/O=Wazuh/CN=" -addext "subjectAltName = IP:,IP:,IP:127.0.0.1,DNS:localhost"
```
---
## II. The Hidden Firewall Block (UFW vs. Tailscale IPTables)
```bash
sudo iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
sudo netfilter-persistent save
```
---
## III. The Dashboard Version Validation Error
```yaml
opensearch.ssl.verificationMode: none
```
---
## IV. The Ingestion Battle & Loading Legacy Templates
We bypassed the validation mismatch by routing the payload directly to the legacy `_template` API wrapper:
```bash
curl -k -u admin:"" -X PUT "[https://127.0.0.1:9200/_template/wazuh](https://127.0.0.1:9200/_template/wazuh)" -H "Content-Type: application/json" -d @/etc/filebeat/wazuh-template.json
```
---
## V. Multi-Platform Deployment & Hands-On Commands
### 1. Overcoming the Duplicate Agent Collision
```bash
sudo /var/ossec/bin/manage_agents -l
sudo /var/ossec/bin/manage_agents -r
sudo systemctl restart wazuh-manager
```
### 2. Mass Endpoint IP Realignment via Sed
```bash
sudo sed -i 's/.*<\/address>/<\/address>/' /var/ossec/etc/ossec.conf
sudo systemctl restart wazuh-agent
```
### 3. Overriding Hardcoded Windows Server Settings via PowerShell
```powershell
# Force live registration over Tailscale mesh interface
& "C:\Program Files (x86)\ossec-agent\agent-auth.exe" -m
# Programmatically rewrite configuration target IP
$conf = "C:\Program Files (x86)\ossec-agent\ossec.conf"
(Get-Content $conf) -replace '.*', ' ' | Set-Content $conf
Restart-Service -Name "Wazuh"
```
---
## VI. Part 2 Conclusion: Defending the Museum
By bypassing fragile, hardcoded automation scripts and addressing our TLS, firewall interface, and database ingestion layers manually at the architecture level, our infrastructure is solid. Every system in my fleet spanning nearly a quarter-century of hardware evolution is now securely reporting host-level security metrics.