Sanitized mirror from private repository - 2026-04-06 03:11:43 UTC
This commit is contained in:
147
docs/networking/ADGUARD_DNS_MESH.md
Normal file
147
docs/networking/ADGUARD_DNS_MESH.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# AdGuard DNS Mesh
|
||||
|
||||
Network-wide ad blocking and split-horizon DNS for all Headscale mesh nodes.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Headscale (Calypso)
|
||||
pushes DNS config to all nodes
|
||||
│
|
||||
┌──────┴──────┐
|
||||
▼ ▼
|
||||
Calypso AdGuard Atlantis AdGuard
|
||||
100.103.48.78:53 100.83.230.112:53
|
||||
(primary) (backup)
|
||||
│ │
|
||||
└──────┬──────┘
|
||||
▼
|
||||
All Tailscale nodes
|
||||
(ad blocking + split-horizon)
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Headscale** pushes two DNS nameservers (Tailscale IPs) to all connected nodes
|
||||
2. Each node resolves DNS through **Calypso AdGuard** (primary) or **Atlantis AdGuard** (fallback)
|
||||
3. AdGuard provides **ad blocking** (filter lists) and **split-horizon DNS** (38 rewrites for internal services)
|
||||
4. Upstream DNS uses DoH: AdGuard DNS, Cloudflare, Quad9, Google, LibreDNS
|
||||
|
||||
## Headscale DNS Config
|
||||
|
||||
File: `/volume1/docker/headscale/config/config.yaml` on Calypso
|
||||
Repo: `hosts/synology/calypso/headscale-config.yaml`
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns: true
|
||||
base_domain: tail.vish.gg
|
||||
nameservers:
|
||||
global:
|
||||
- 100.103.48.78 # Calypso AdGuard (Tailscale IP)
|
||||
- 100.83.230.112 # Atlantis AdGuard (Tailscale IP)
|
||||
```
|
||||
|
||||
Using Tailscale IPs (not LAN IPs) ensures remote nodes (Seattle, Jellyfish, mobile devices, GL.iNet routers) can reach the DNS servers.
|
||||
|
||||
## Split-Horizon DNS Rewrites (38 rules)
|
||||
|
||||
Both Calypso and Atlantis AdGuard instances have identical rewrites:
|
||||
|
||||
| Domain | Answer | Purpose |
|
||||
|--------|--------|---------|
|
||||
| `*.vish.gg` | `100.85.21.51` | Wildcard → matrix-ubuntu (NPM) |
|
||||
| `pt.vish.gg` | `192.168.0.154` | Portainer (direct, not proxied) |
|
||||
| `sso.vish.gg` | `192.168.0.154` | Authentik SSO |
|
||||
| `git.vish.gg` | `192.168.0.154` | Gitea |
|
||||
| `dash.vish.gg` | `192.168.0.154` | Homarr dashboard |
|
||||
| `gf.vish.gg` | `192.168.0.154` | Grafana |
|
||||
| `headscale.vish.gg` | `192.168.0.250` | Headscale server |
|
||||
| `derp.vish.gg` | `192.168.0.250` | DERP relay (Calypso) |
|
||||
| `derp-atl.vish.gg` | `192.168.0.200` | DERP relay (Atlantis) |
|
||||
| `derp-sea.vish.gg` | `100.82.197.124` | DERP relay (Seattle) |
|
||||
| `turn.thevish.io` | `192.168.0.200` | TURN server |
|
||||
| `*.tail.vish.gg` | per-node Tailscale IP | MagicDNS node records (12) |
|
||||
| `*.vish.local` | per-node Tailscale IP | Local aliases (8) |
|
||||
| `*.crista.home` | per-node Tailscale IP | Crista network aliases (2) |
|
||||
| `*.thevish.io` | `100.85.21.51` | thevish.io wildcard |
|
||||
| `*.crista.love` | `100.85.21.51` | crista.love wildcard |
|
||||
|
||||
## Node Status
|
||||
|
||||
| Node | accept-dns | Split-Horizon | Ad Blocking | Notes |
|
||||
|------|:---:|:---:|:---:|-------|
|
||||
| homelab-vm | enabled | Yes | Yes | |
|
||||
| atlantis | enabled | Yes | Yes | |
|
||||
| seattle | enabled | Yes | Yes | Remote VPS |
|
||||
| nuc | enabled | Yes | Yes | |
|
||||
| pi-5 | enabled | Yes | Yes | |
|
||||
| matrix-ubuntu | enabled | Yes | Yes | |
|
||||
| jellyfish | enabled | Yes | Yes | No dig/nslookup, verified via python |
|
||||
| calypso | enabled | N/A | N/A | IS the AdGuard server; Synology can't override resolv.conf |
|
||||
| setillo | enabled | No | Yes (local) | Synology limitation; has own local AdGuard |
|
||||
| guava | N/A | N/A | Via LAN | TrueNAS app; uses Calypso AdGuard at 192.168.0.250 on LAN |
|
||||
|
||||
Mobile devices, GL.iNet routers, and Home Assistant use default `--accept-dns=true` and inherit DNS from Headscale automatically.
|
||||
|
||||
## Rollback
|
||||
|
||||
### Immediate (~2 min) - revert Headscale DNS to LAN IPs
|
||||
|
||||
```bash
|
||||
ssh calypso 'sed -i "s/100.103.48.78/192.168.0.250/" /volume1/docker/headscale/config/config.yaml && \
|
||||
sed -i "s/100.83.230.112/192.168.68.100/" /volume1/docker/headscale/config/config.yaml'
|
||||
# Restart headscale via Portainer or:
|
||||
ssh calypso '/usr/local/bin/docker restart headscale'
|
||||
```
|
||||
|
||||
### Per-node override
|
||||
|
||||
```bash
|
||||
# On the affected node:
|
||||
tailscale set --accept-dns=false
|
||||
```
|
||||
|
||||
### Nuclear - bypass Tailscale DNS entirely
|
||||
|
||||
```bash
|
||||
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
|
||||
```
|
||||
|
||||
### Symptoms
|
||||
|
||||
| Symptom | Cause | Fix |
|
||||
|---------|-------|-----|
|
||||
| DNS resolution hangs | Both AdGuard containers down | Restart AdGuard on Calypso/Atlantis |
|
||||
| Wrong split-horizon (public IP) | Rewrite missing on responding AdGuard | Add missing rewrite via AdGuard UI |
|
||||
| One node can't resolve | Tailscale tunnel down | `tailscale ping calypso` to diagnose |
|
||||
|
||||
## AdGuard Instances
|
||||
|
||||
| Instance | Host | LAN IP | Tailscale IP | Web UI | Role |
|
||||
|----------|------|--------|-------------|--------|------|
|
||||
| Calypso | Synology | 192.168.0.250:9080 | 100.103.48.78:9080 | http://192.168.0.250:9080 | Primary |
|
||||
| Atlantis | Synology | 192.168.0.200:9080 | 100.83.230.112:9080 | http://192.168.0.200:9080 | Backup |
|
||||
| NUC | Intel NUC | 192.168.68.100:9080 | 100.72.55.21:9080 | http://192.168.68.100:9080 | Local (Concord subnet) |
|
||||
| Setillo | Synology | 192.168.69.x | 100.125.0.20 | host network | Local (remote site) |
|
||||
|
||||
## Maintenance
|
||||
|
||||
When adding a new split-horizon rewrite, add it to **both** Calypso and Atlantis AdGuard instances to keep them in sync. Use the AdGuard web UI or API:
|
||||
|
||||
```bash
|
||||
# Calypso (via MCP tool or API)
|
||||
curl -u vish:PASSWORD -X POST http://192.168.0.250:9080/control/rewrite/add \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"domain":"new.vish.gg","answer":"192.168.0.154"}'
|
||||
|
||||
# Atlantis (same, different host)
|
||||
curl -u vish:PASSWORD -X POST http://192.168.0.200:9080/control/rewrite/add \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"domain":"new.vish.gg","answer":"192.168.0.154"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Deployed: 2026-03-31*
|
||||
*Config: `hosts/synology/calypso/headscale-config.yaml`*
|
||||
Reference in New Issue
Block a user