# 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):** ```yaml doh-secure: rule: "Host(`doh.xtrm-lab.org`)" entryPoints: [https] tls: certResolver: cloudflare service: doh # → http://DoH-Server:8053 ``` **Test:** ```bash 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 ```bash # 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. |