Cluster / HA Setup
Deploy DomU DNS across two Raspberry Pi nodes in a Master/Slave configuration for high availability. No database required β just file-based sync with HMAC-SHA256 authentication.
Architecture
text
dns-node-1 (Master) dns-node-2 (Slave)
βββββββββββββββββββββββ βββββββββββββββββββββββ
β Accepts API changes β β Read-only API β
β Stores JSON locally βββββββΆβ Receives push events β
β Fetches blocklists β β Polls master (30s) β
β Pushes to slaves β β Autonomous DNS op. β
βββββββββββββββββββββββ βββββββββββββββββββββββ
β β
βββββββββββ DNS ββββββββββββββ
Router: both IPs as DNSKey properties:
- Master handles all writes (zones, blocklist, config)
- Slave receives changes via HTTP push (immediate) + polling (fallback every 30s)
- Both nodes serve DNS autonomously from their local in-memory state
- If the master is down, the slave continues serving cached DNS responses
Prerequisites: Both Pis need static IPs, SSH access, and DomU DNS installed (see Quick Start). Open ports:
53/udp, 53/tcp, 80/tcp.
Step 1: Generate Sync Secret
The sync secret authenticates all masterβslave push events with HMAC-SHA256. Generate it once and use the same value on both nodes:
bash
# Generate 64-character hex secret (32 bytes) openssl rand -hex 32 # Example: a3f2c8b1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1 # On BOTH nodes, create /etc/domudns/env: sudo tee /etc/domudns/env << 'EOF' DOMUDNS_SYNC_SECRET=<YOUR_64_CHAR_HEX_SECRET> EOF sudo chmod 600 /etc/domudns/env # Secret file β restrict access!
Step 2: Configure Master (dns-node-1)
/etc/domudns/config.yaml on the master node:
yaml
cluster:
role: "master"
data_dir: "/var/lib/domudns/data"
slaves:
- "http://<SLAVE_IP>:80" # Replace with actual slave IP
dnsserver:
listen: "[::]:53"
upstream:
- "9.9.9.9"
- "149.112.112.112"
http:
listen: ":80"
system:
log_level: "info"Step 3: Configure Slave (dns-node-2)
/etc/domudns/config.yaml on the slave node:
yaml
cluster:
role: "slave"
data_dir: "/var/lib/domudns/data"
master_url: "http://<MASTER_IP>:80" # Replace with actual master IP
sync_interval: "30s"
dnsserver:
listen: "[::]:53"
upstream:
- "9.9.9.9"
http:
listen: ":80"
system:
log_level: "info"Start Both Services
bash
# On both nodes: sudo systemctl restart domudns sudo systemctl status domudns
Verify Cluster Sync
bash
# Check cluster status on master
curl -H "Authorization: Bearer <KEY>" \
http://<MASTER_IP>/api/cluster/status
# Create a test zone on master
curl -X POST http://<MASTER_IP>/api/zones \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{"domain": "test.lan", "ttl": 300}'
# Verify it appears on slave (within seconds)
curl http://<SLAVE_IP>/api/zones # Read-only, no auth needed for listing
# Test DNS from both nodes
dig @<MASTER_IP> test.lan SOA
dig @<SLAVE_IP> test.lan SOAConfigure Router for HA DNS
Set both node IPs as DNS servers in your router's DHCP settings:
| DNS Server | Role | Address |
|---|---|---|
| Primary | Master | IP of dns-node-1 |
| Secondary | Slave | IP of dns-node-2 |
If the master goes down, clients automatically fall back to the slave for DNS resolution.
Note: API changes (zones, blocklist) must always be made on the master. The slave's API is read-only and rejects write operations.