209 lines
7.9 KiB
Markdown
209 lines
7.9 KiB
Markdown
# 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. |
|