Add MikroTik AdGuard setup script and complete documentation
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Added scripts/mikrotik-adguard-setup.rsc with full setup commands - Created docs/09-MIKROTIK-ADGUARD-DOT-DOH.md with: - Architecture diagram - Complete NAT/routing rules documentation - Container configuration details - TLS/DoT/DoH setup - Troubleshooting guide - Removed WIP document (moved to completed docs)
This commit is contained in:
243
docs/09-MIKROTIK-ADGUARD-DOT-DOH.md
Normal file
243
docs/09-MIKROTIK-ADGUARD-DOT-DOH.md
Normal file
@@ -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
|
||||
@@ -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
|
||||
109
scripts/mikrotik-adguard-setup.rsc
Normal file
109
scripts/mikrotik-adguard-setup.rsc
Normal file
@@ -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"
|
||||
Reference in New Issue
Block a user