diff --git a/docs/09-MIKROTIK-ADGUARD-DOT-DOH.md b/docs/09-MIKROTIK-ADGUARD-DOT-DOH.md new file mode 100644 index 0000000..ecf92a7 --- /dev/null +++ b/docs/09-MIKROTIK-ADGUARD-DOT-DOH.md @@ -0,0 +1,243 @@ +# MikroTik AdGuard Home with DoT/DoH + +**Status:** Completed +**Implemented:** 2026-01-25 + +--- + +## Overview + +Single DNS endpoint for both internal and external clients with ad blocking and encrypted DNS. + +## Architecture + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ EXTERNAL │ +│ │ +│ Mobile/Remote ──► dns.xtrm-lab.org ──► WAN:853 (DoT) │ +│ ──► WAN:8443 (DoH) │ +└─────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ MikroTik hAP ax³ │ +│ 192.168.31.1 │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ NAT (DSTNAT) │ │ +│ │ WAN:853 ──► 172.17.0.2:853 (DoT) │ │ +│ │ WAN:8443 ──► 172.17.0.2:443 (DoH) │ │ +│ │ LAN:53 ──► 172.17.0.2:53 (DNS redirect) │ │ +│ │ LAN:3000 ──► 172.17.0.2:80 (Web UI) │ │ +│ └─────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ AdGuard Home Container │ │ +│ │ 172.17.0.2 (veth-adguard) │ │ +│ │ │ │ +│ │ Ports: 53 (DNS), 80 (HTTP), 443 (HTTPS), 853 (DoT) │ │ +│ │ Storage: usb1/adguard/{conf,work,root} │ │ +│ └─────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ Upstream DNS │ +│ ┌──────────────────┐ │ +│ │ 192.168.31.4 │ ◄── Unraid AdGuard (primary)│ +│ │ 8.8.8.8 │ ◄── Google (fallback) │ +│ │ 1.1.1.1 │ ◄── Cloudflare (fallback) │ +│ └──────────────────┘ │ +└─────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ INTERNAL │ +│ │ +│ LAN Clients ──► 192.168.31.1:53 ──► NAT redirect ──► Container │ +│ (192.168.31.0/24) │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +## Network Configuration + +### Container Network +| Component | IP Address | Interface | +|-----------|------------|-----------| +| MikroTik (gateway) | 172.17.0.1/24 | veth-adguard | +| AdGuard container | 172.17.0.2/24 | veth-adguard | + +### Port Mapping +| Service | External Port | Internal Target | Protocol | +|---------|---------------|-----------------|----------| +| DNS | 53 | 172.17.0.2:53 | UDP/TCP | +| DoT | 853 | 172.17.0.2:853 | TCP | +| DoH | 8443 | 172.17.0.2:443 | TCP | +| Web UI | 3000 | 172.17.0.2:80 | TCP | + +## Routing & NAT Rules + +### DNS Flow for LAN Clients + +``` +1. Client (192.168.31.x) sends DNS query to any IP:53 +2. DSTNAT rule intercepts and redirects to 172.17.0.2:53 +3. SRCNAT masquerade ensures return traffic goes back through MikroTik +4. AdGuard processes query, checks filters +5. If not cached/blocked, forwards to upstream (192.168.31.4 first) +6. Response returns to client +``` + +### NAT Rules (in order) + +```routeros +# 1. Exception rules (must be FIRST to prevent loops) +chain=dstnat action=accept protocol=udp src-address=172.17.0.0/24 dst-port=53 + comment="Allow MikroTik AdGuard outbound DNS" + +chain=dstnat action=accept protocol=udp src-address=192.168.31.4 dst-port=53 + comment="Allow Unraid AdGuard outbound DNS" + +chain=dstnat action=accept protocol=tcp src-address=192.168.31.4 dst-port=53 + comment="Allow Unraid AdGuard outbound DNS TCP" + +# 2. LAN DNS redirect +chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 + protocol=udp src-address=192.168.31.0/24 dst-port=53 + comment="Redirect DNS to MikroTik AdGuard" + +chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 + protocol=tcp src-address=192.168.31.0/24 dst-port=53 + comment="Redirect DNS to MikroTik AdGuard TCP" + +# 3. Masquerade for symmetric routing +chain=srcnat action=masquerade protocol=udp src-address=192.168.31.0/24 + dst-address=172.17.0.2 dst-port=53 + comment="Masquerade DNS to MikroTik AdGuard" + +chain=srcnat action=masquerade protocol=tcp src-address=192.168.31.0/24 + dst-address=172.17.0.2 dst-port=53 + comment="Masquerade DNS to MikroTik AdGuard TCP" + +# 4. External access (DoT/DoH) +chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=853 + protocol=tcp in-interface=eth1_WAN dst-port=853 + comment="DNS over TLS (DoT)" + +chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=443 + protocol=tcp in-interface=eth1_WAN dst-port=8443 + comment="DNS over HTTPS (DoH)" + +# 5. Web UI access +chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=80 + protocol=tcp dst-address=192.168.31.1 dst-port=3000 + comment="AdGuard Web UI" +``` + +### Firewall Filter Rules + +```routeros +# Allow traffic to/from container network +chain=input action=accept dst-address=172.17.0.0/24 + comment="Allow container network" + +chain=input action=accept src-address=172.17.0.0/24 + comment="Allow from container network" + +chain=forward action=accept dst-address=172.17.0.0/24 + comment="Allow to container network" + +chain=forward action=accept src-address=172.17.0.0/24 + comment="Allow from container network" +``` + +### MikroTik DNS Configuration + +```routeros +/ip dns + servers=172.17.0.2 + allow-remote-requests=yes +``` + +## Container Configuration + +### Mounts +| Name | Source | Destination | +|------|--------|-------------| +| agh-config | usb1/adguard/conf | /opt/adguardhome/conf | +| agh-work | usb1/adguard/work | /opt/adguardhome/work | + +### Container Settings +- **Image:** adguard/adguardhome:latest +- **Version:** v0.107.71 +- **Root dir:** usb1/adguard/root +- **DNS:** 8.8.8.8 (for container itself during startup) +- **Start on boot:** yes +- **Logging:** yes + +## TLS Configuration + +- **Server name:** dns.xtrm-lab.org +- **Certificate:** Let's Encrypt (ECDSA) +- **Valid until:** 2026-03-10 +- **Certificate location:** /mnt/user/appdata/claude-code/certbot/config/live/dns.xtrm-lab.org/ + +## AdGuard Settings + +### Credentials +- **Username:** admin +- **Password:** admin123 +- **Web UI:** http://192.168.31.1:3000 + +### Upstream DNS +1. 192.168.31.4 (Unraid AdGuard - primary, has filter lists) +2. 8.8.8.8 (Google - fallback) +3. 1.1.1.1 (Cloudflare - fallback) + +### Bootstrap DNS +- 8.8.8.8 +- 1.1.1.1 + +## Usage + +### For LAN Clients +No configuration needed - DNS queries are automatically redirected. + +### For Android (Private DNS) +Settings → Network → Private DNS → dns.xtrm-lab.org + +### For iOS (DNS over HTTPS) +Use a DNS profile with: https://dns.xtrm-lab.org:8443/dns-query + +### For Browsers (DoH) +Firefox/Chrome: https://dns.xtrm-lab.org:8443/dns-query + +## Troubleshooting + +### Check container status +```routeros +/container print +``` + +### Check container logs +```routeros +:log print where topics~"container" +``` + +### Test DNS resolution +```routeros +:resolve google.com server=172.17.0.2 +``` + +### Check NAT rules +```routeros +/ip firewall nat print where comment~"DNS" or comment~"AdGuard" +``` + +## Scripts + +Setup script: `scripts/mikrotik-adguard-setup.rsc` + +## Related Documents + +- [00-CURRENT-STATE.md](00-CURRENT-STATE.md) - Current infrastructure state +- [incidents/2026-01-25-dns-outbound-blocked-after-mikrotik-restart.md](incidents/2026-01-25-dns-outbound-blocked-after-mikrotik-restart.md) - DNS incident that led to this setup diff --git a/docs/wip/MIKROTIK-ADGUARD-DOT-DOH.md b/docs/wip/MIKROTIK-ADGUARD-DOT-DOH.md deleted file mode 100644 index 6676c13..0000000 --- a/docs/wip/MIKROTIK-ADGUARD-DOT-DOH.md +++ /dev/null @@ -1,113 +0,0 @@ -# MikroTik AdGuard Home with DoT/DoH - -**Status:** Completed -**Started:** 2026-01-25 -**Completed:** 2026-01-25 - ---- - -## Objective - -Single DNS endpoint with failover: -- External: dns.xtrm-lab.org (DoT 853, DoH 8443) -- Internal: 192.168.31.1 (all LAN clients) -- Failover: Unraid AdGuard (192.168.31.4) as upstream backup - -## Architecture - -``` -External ──► dns.xtrm-lab.org ──► NAT ──┐ - (DoT 853, DoH 8443) │ - ▼ -Internal ──► 192.168.31.1:53 ────► MikroTik AdGuard - (LAN clients) (172.17.0.2) - │ - ▼ - Upstreams: - - 192.168.31.4 (Unraid AdGuard) - - 8.8.8.8 (Google) - - 1.1.1.1 (Cloudflare) -``` - -## Implementation Steps - -- [x] 1. Install AdGuard container on MikroTik -- [x] 2. Configure veth interface with IP (172.17.0.2/24) -- [x] 3. Configure AdGuard upstreams (192.168.31.4, 8.8.8.8, 1.1.1.1) -- [x] 4. Enable DoT/DoH in AdGuard -- [x] 5. Configure TLS certificates (dns.xtrm-lab.org, Let's Encrypt) -- [x] 6. Update NAT rules (DoT/DoH → container) -- [x] 7. Update DNS redirect rules (LAN → container) -- [x] 8. Test internal DNS (working) -- [ ] 9. Test external DoT/DoH (pending external test) -- [x] 10. Update documentation - -## Container Configuration - -- **Image:** adguard/adguardhome:latest -- **Version:** v0.107.71 -- **Root dir:** usb1/adguard/root -- **Interface:** veth-adguard (172.17.0.2/24) -- **Gateway:** 172.17.0.1 -- **Mounts:** agh-config, agh-work - -## Network Configuration - -| Service | External Port | Internal Target | -|---------|---------------|-----------------| -| DNS (UDP/TCP) | 53 | 172.17.0.2:53 | -| DoT (TCP) | 853 | 172.17.0.2:853 | -| DoH (TCP) | 8443 | 172.17.0.2:443 | -| Web UI | 3000 | 172.17.0.2:80 | - -## NAT Rules - -``` -# DNS redirect for LAN -chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp/tcp src-address=192.168.31.0/24 dst-port=53 - -# DoT external access -chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=853 protocol=tcp in-interface=eth1_WAN dst-port=853 - -# DoH external access (using port 8443 to avoid Traefik conflict) -chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=443 protocol=tcp in-interface=eth1_WAN dst-port=8443 - -# Web UI access -chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=80 protocol=tcp dst-address=192.168.31.1 dst-port=3000 -``` - -## TLS Configuration - -- **Server name:** dns.xtrm-lab.org -- **Certificate:** Let's Encrypt (valid until 2026-03-10) -- **DoT port:** 853 -- **DoH port:** 443 (internal) / 8443 (external) -- **Certificate location:** /mnt/user/appdata/claude-code/certbot/config/live/dns.xtrm-lab.org/ - -## AdGuard Credentials - -- **Username:** admin -- **Password:** admin123 -- **Web UI:** http://192.168.31.1:3000 - -## Usage - -### Internal (LAN clients) -Clients automatically use 192.168.31.1:53 via DHCP/NAT redirect. - -### External DoT (Android/iOS Private DNS) -``` -dns.xtrm-lab.org -``` - -### External DoH -``` -https://dns.xtrm-lab.org:8443/dns-query -``` - -## Notes - -- Old docker-bridge removed (was causing routing conflict) -- Container network 172.17.0.0/24 conflicts with standard Docker on Unraid -- Unraid AdGuard (192.168.31.4) used as primary upstream for ad filtering -- Container starts on boot automatically diff --git a/scripts/mikrotik-adguard-setup.rsc b/scripts/mikrotik-adguard-setup.rsc new file mode 100644 index 0000000..02e8930 --- /dev/null +++ b/scripts/mikrotik-adguard-setup.rsc @@ -0,0 +1,109 @@ +# MikroTik AdGuard Home Setup Script +# Created: 2026-01-25 +# Repository: https://git.xtrm-lab.org/jazzymc/infrastructure +# +# Prerequisites: +# - RouterOS 7.4+ with container package +# - USB storage mounted as usb1 +# - Container mode enabled: /system/device-mode/update container=yes + +#------------------------------------------------------------ +# Variables +#------------------------------------------------------------ +:local containerName "adguardhome" +:local containerImage "adguard/adguardhome:latest" +:local vethName "veth-adguard" +:local containerIP "172.17.0.2" +:local gatewayIP "172.17.0.1" +:local containerNet "172.17.0.0/24" +:local lanNet "192.168.31.0/24" +:local unraidAdguard "192.168.31.4" +:local wanInterface "eth1_WAN" + +#------------------------------------------------------------ +# 1. Create veth interface +#------------------------------------------------------------ +/interface veth add name=$vethName address=$containerIP/24 gateway=$gatewayIP + +#------------------------------------------------------------ +# 2. Add IP to veth (MikroTik side) +#------------------------------------------------------------ +/ip address add address=$gatewayIP/24 interface=$vethName + +#------------------------------------------------------------ +# 3. Create container mounts +#------------------------------------------------------------ +/container mounts add name=agh-config src=usb1/adguard/conf dst=/opt/adguardhome/conf +/container mounts add name=agh-work src=usb1/adguard/work dst=/opt/adguardhome/work + +#------------------------------------------------------------ +# 4. Pull and create container +#------------------------------------------------------------ +/container add remote-image=$containerImage interface=$vethName root-dir=usb1/adguard/root \ + mounts=agh-config,agh-work logging=yes start-on-boot=yes dns=8.8.8.8 \ + hostname="mikrotik-adguard" name=$containerName + +#------------------------------------------------------------ +# 5. Firewall - Allow container network traffic +#------------------------------------------------------------ +# Input chain +/ip firewall filter add chain=input action=accept dst-address=$containerNet comment="Allow container network" +/ip firewall filter add chain=input action=accept src-address=$containerNet comment="Allow from container network" + +# Forward chain +/ip firewall filter add chain=forward action=accept dst-address=$containerNet comment="Allow to container network" +/ip firewall filter add chain=forward action=accept src-address=$containerNet comment="Allow from container network" + +#------------------------------------------------------------ +# 6. NAT Rules - DNS Redirect +#------------------------------------------------------------ +# Allow container outbound DNS (prevent redirect loop) +/ip firewall nat add chain=dstnat action=accept protocol=udp src-address=$containerNet dst-port=53 \ + comment="Allow MikroTik AdGuard outbound DNS" + +# Allow Unraid AdGuard outbound DNS +/ip firewall nat add chain=dstnat action=accept protocol=udp src-address=$unraidAdguard dst-port=53 \ + comment="Allow Unraid AdGuard outbound DNS" +/ip firewall nat add chain=dstnat action=accept protocol=tcp src-address=$unraidAdguard dst-port=53 \ + comment="Allow Unraid AdGuard outbound DNS TCP" + +# Redirect LAN DNS to container +/ip firewall nat add chain=dstnat action=dst-nat to-addresses=$containerIP to-ports=53 \ + protocol=udp src-address=$lanNet dst-port=53 comment="Redirect DNS to MikroTik AdGuard" +/ip firewall nat add chain=dstnat action=dst-nat to-addresses=$containerIP to-ports=53 \ + protocol=tcp src-address=$lanNet dst-port=53 comment="Redirect DNS to MikroTik AdGuard TCP" + +# Masquerade for return traffic +/ip firewall nat add chain=srcnat action=masquerade protocol=udp src-address=$lanNet \ + dst-address=$containerIP dst-port=53 comment="Masquerade DNS to MikroTik AdGuard" +/ip firewall nat add chain=srcnat action=masquerade protocol=tcp src-address=$lanNet \ + dst-address=$containerIP dst-port=53 comment="Masquerade DNS to MikroTik AdGuard TCP" + +#------------------------------------------------------------ +# 7. NAT Rules - External Access (DoT/DoH) +#------------------------------------------------------------ +# DoT (DNS over TLS) - port 853 +/ip firewall nat add chain=dstnat action=dst-nat to-addresses=$containerIP to-ports=853 \ + protocol=tcp in-interface=$wanInterface dst-port=853 comment="DNS over TLS (DoT)" + +# DoH (DNS over HTTPS) - port 8443 external -> 443 internal +/ip firewall nat add chain=dstnat action=dst-nat to-addresses=$containerIP to-ports=443 \ + protocol=tcp in-interface=$wanInterface dst-port=8443 comment="DNS over HTTPS (DoH)" + +# Web UI access - port 3000 -> 80 +/ip firewall nat add chain=dstnat action=dst-nat to-addresses=$containerIP to-ports=80 \ + protocol=tcp dst-address=192.168.31.1 dst-port=3000 comment="AdGuard Web UI" + +#------------------------------------------------------------ +# 8. Set MikroTik DNS to use container +#------------------------------------------------------------ +/ip dns set servers=$containerIP allow-remote-requests=yes + +#------------------------------------------------------------ +# 9. Start container +#------------------------------------------------------------ +/container start $containerName + +:log info "AdGuard Home container setup complete" +:log info "Web UI: http://192.168.31.1:3000" +:log info "Complete initial setup, then configure TLS for DoT/DoH"