All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
New Structure: - 01-NETWORK-MAP.md - Network topology, IPs, Docker networks, services - 02-SERVICES-CRITICAL.md - DNS, Auth, Routing (P0/P1 services) - 03-SERVICES-OTHER.md - All non-critical services - 04-HARDWARE-INVENTORY.md - Physical devices and specs - 05-CHANGELOG.md - Major events only New Folders: - docs/archive/ - Legacy docs (read-only reference) - docs/wip/ - Planned changes and ideas - UPGRADE-2026-HARDWARE.md - N5 Air + N100 migration plan - GITOPS-CONTAINERS.md - Phase 2 container GitOps Changes: - Moved all 22 legacy docs to archive/ - Consolidated container IPs, physical map, and services into single network map - Extracted critical vs non-critical service classification - Simplified changelog to major events only Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
Phase 1: Global DNS Portability
Status: ✅ COMPLETED (2026-01-18)
Pi-hole ad-blocking works on all devices via Tailscale MagicDNS and DoH/DoT endpoints.
Tailscale Configuration
| Parameter | Value |
|---|---|
| Unraid Tailscale IP | 100.100.208.70 |
| Hostname | xtrm-unraid |
| Subnet Route | 192.168.31.0/24 (advertised & approved) |
| Global DNS | Pi-hole via MagicDNS |
| Override Local DNS | Enabled |
Connected Devices
| Device | Tailscale IP | Status |
|---|---|---|
| xtrm-unraid | 100.100.208.70 | Online |
| kaloyans-macbook-air | 100.68.118.59 | Active |
| mikrotik-tailscale-1 | 100.75.93.123 | Online |
| samsung-sm-s938b | 100.111.64.56 | Offline |
DNS Services
Pi-hole Instances
| Instance | Location | IP | Web UI | Status |
|---|---|---|---|---|
| Primary | MikroTik Container | 172.17.0.2 | ph2.xtrm-lab.org | ✅ Running |
| Secondary | Unraid (macvlan br0) | 192.168.31.4 | ph1.xtrm-lab.org | ✅ Running |
Sync: nebula-sync (healthy) syncs Unraid → MikroTik every 5 minutes
Unbound Instances (Recursive DNS)
| Instance | Location | IP | Status |
|---|---|---|---|
| Primary | MikroTik Container | 172.17.0.3 | ✅ Running |
| Secondary | Unraid (macvlan br0) | 192.168.31.5 | ✅ Running |
Pi-hole Upstream Configuration
Unraid Pi-hole (192.168.31.4):
upstreams = ["172.17.0.3#53", "192.168.31.5#53"]
DoH Endpoint (DNS over HTTPS)
| Parameter | Value |
|---|---|
| URL | https://doh.xtrm-lab.org/dns-query |
| Container | DoH-Server (ghcr.io/ich777/doh-server) |
| Listen Port | 8053 |
| Upstream DNS | udp:192.168.31.1:53 |
| Network | dockerproxy |
Traefik Route (dynamic.yml):
doh-secure:
rule: "Host(`doh.xtrm-lab.org`)"
entryPoints: [https]
tls:
certResolver: cloudflare
service: doh # → http://DoH-Server:8053
Test:
curl -H 'accept: application/dns-json' 'https://doh.xtrm-lab.org/dns-query?name=google.com&type=A'
DoT Endpoint (DNS over TLS)
| Parameter | Value |
|---|---|
| Hostname | doh.xtrm-lab.org:853 |
| Container | stunnel-dot (dweomer/stunnel) |
| Accept Port | 853 |
| Forward To | 192.168.31.4:53 (Unraid Pi-hole) |
MikroTik NAT: WAN:853 → 192.168.31.2:853
Android Private DNS: Settings → Private DNS → doh.xtrm-lab.org
DNS Architecture
┌─────────────────────────────────────┐
│ External Clients │
└──────────────┬──────────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Tailscale │ │ DoH │ │ DoT │
│ MagicDNS │ │ doh.xtrm-lab.org│ │ :853 │
│ 100.100.100.100 │ │ (Traefik→DoH) │ │ (stunnel) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└────────────────────────┼────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ LAN (192.168.31.0/24) │
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ MikroTik Pi-hole │ │ Unraid Pi-hole │ │
│ │ 172.17.0.2 │ │ 192.168.31.4 │ │
│ │ (NAT forced for LAN) │ │ (Direct access allowed) │ │
│ └───────────┬─────────────┘ └───────────┬─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ MikroTik Unbound │ │ Unraid Unbound │ │
│ │ 172.17.0.3 (recursive) │ │ 192.168.31.5 (recursive)│ │
│ └─────────────────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
DHCP DNS Servers (MikroTik)
| Priority | Server | Notes |
|---|---|---|
| Primary | 192.168.31.1 | MikroTik (NAT forces to Pi-hole 172.17.0.2) |
| Secondary | 192.168.31.4 | Unraid Pi-hole (direct, for failover) |
MikroTik DNS NAT Rules
| Rule | Action | Description |
|---|---|---|
| 3 | ACCEPT | Traffic TO 192.168.31.4:53 (allows Unraid Pi-hole) |
| 7 | DST-NAT | Force LAN DNS to 172.17.0.2 (MikroTik Pi-hole) |
| 21 | DST-NAT | DoT WAN:853 → 192.168.31.2:853 |
Failover Behavior
| Scenario | Behavior |
|---|---|
| MikroTik Pi-hole down | Clients use secondary DNS (192.168.31.4) |
| MikroTik Unbound down | Pi-holes use Unraid Unbound (192.168.31.5) |
| Unraid down | MikroTik services continue independently |
Client Configuration
macOS (DoH)
- Firefox/Chrome: Settings → Security → Custom DNS →
https://doh.xtrm-lab.org/dns-query - System-wide: Install DNS profile with DoH URL
Android (DoT)
- Settings → Network → Private DNS →
doh.xtrm-lab.org
Tailscale Clients
- Automatic via MagicDNS (no configuration needed)
Verification Commands
# Test DoH endpoint
curl -H 'accept: application/dns-json' 'https://doh.xtrm-lab.org/dns-query?name=google.com&type=A'
# Test ad-blocking via DoH
curl -H 'accept: application/dns-json' 'https://doh.xtrm-lab.org/dns-query?name=ads.google.com&type=A'
# Expected: 0.0.0.0
# Test Pi-holes directly
dig +short google.com @172.17.0.2 # MikroTik Pi-hole
dig +short google.com @192.168.31.4 # Unraid Pi-hole
# Test Unbound directly
dig +short google.com @172.17.0.3 # MikroTik Unbound
dig +short google.com @192.168.31.5 # Unraid Unbound
# Check Tailscale ad-blocking
dig +short ads.google.com @100.100.100.100
# Expected: 0.0.0.0
Known Issues
| Issue | Status | Notes |
|---|---|---|
| Certificate renewal failing | ⚠️ Open | Cloudflare API token needs Zone:DNS:Edit permission. Certs expire Feb 11, 2026. |