- Replaced Pi-hole container with AdGuard Home (172.17.0.5) - Configured native DoH/DoT/DoQ with TLS certificates - Updated DNS architecture diagram - Updated NAT rules documentation - Added encrypted DNS endpoints Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
Infrastructure Upgrade Proposal: xtrm-lab.org (v2)
Current Infrastructure State
Document Updated: 2026-01-22 Target Domain: xtrm-lab.org
Network Topology
MikroTik hAP ax³ Router (192.168.31.1)
| Parameter | Value |
|---|---|
| RouterOS Version | 7.20.6 (stable) |
| WAN IP (Static) | 62.73.120.142 |
| LAN Subnet | 192.168.31.0/24 |
| Docker Bridge | 172.17.0.0/24 |
| SSH Access | ssh -i /root/.ssh/mikrotik_key -p 2222 xtrm@192.168.31.1 |
SSH Users:
xtrm- Primary admin user (key-based from Unraid)unraid- Secondary admin user (key-based from Unraid)
Interfaces:
ether1- WAN (62.73.120.142/23)bridge- LAN (192.168.31.1/24)docker-bridge- Container network (172.17.0.1/24)back-to-home-vpn- WireGuard VPN (192.168.216.1/24)
SNMP Configuration:
| Device | Community | Access | Status |
|---|---|---|---|
| hAP ax³ | netdisco |
192.168.31.2 only | Enabled |
| CSS326 | public |
Any (SwOS limit) | Enabled |
| cAP ac | netdisco |
192.168.31.2 only | Enabled |
Running Containers on MikroTik:
| Container | IP | Storage | Purpose |
|---|---|---|---|
| unbound:latest | 172.17.0.3 | usb1/unbound/root | Recursive DNS resolver |
| tailscale:latest | 172.17.0.4 | usb1/tailscale/root | Tailscale VPN client |
| adguardhome:latest | 172.17.0.5 | usb1/adguardhome | DNS sinkhole with DoH/DoT/DoQ |
AdGuard Home Configuration (172.17.0.5):
| Service | Port | Protocol | Status |
|---|---|---|---|
| DNS | 53 | UDP/TCP | Active |
| Web UI | 80 | HTTP | Active |
| DoH (DNS-over-HTTPS) | 443 | HTTPS | Active (TLS) |
| DoT (DNS-over-TLS) | 853 | TCP | Active (TLS) |
| DoQ (DNS-over-QUIC) | 8853 | UDP | Active (TLS) |
TLS Certificate: Let's Encrypt wildcard cert for *.xtrm-lab.org (shared from Traefik)
Server Name: dns.xtrm-lab.org
Certificate Expiry: 2026-04-02
MikroTik CSS326-24G-2S+ Switch (192.168.31.9)
| Parameter | Value |
|---|---|
| Role | Managed Layer 2 Switch |
| Model | CSS326-24G-2S+ |
| Ports | 24x Gigabit + 2x SFP |
| OS | SwOS (MikroTik Switch OS) |
| Web UI | http://192.168.31.9/index.html |
MikroTik cAP ac (192.168.31.6)
| Parameter | Value |
|---|---|
| Role | CAPsMAN Managed Access Point |
| RouterOS Version | 7.20.1 (stable) |
| Identity | CAP XL ac |
Unraid Server (192.168.31.2)
Tailscale IP: 100.100.208.70
SSH Access: ssh -i ~/.ssh/id_ed25519_unraid root@192.168.31.2 -p 422
Docker Networks
| Network | Subnet | Purpose |
|---|---|---|
| dockerproxy | 172.18.0.0/16 | Traefik-accessible services |
| netbox | 172.24.0.0/16 | NetBox stack |
| slurpit_slurpit-network | Auto | Slurp'it stack |
| br0 | 192.168.31.0/24 | LAN macvlan |
| bridge | 172.17.0.0/16 | Default Docker bridge |
| host | - | Host network stack |
Key Services
| Service | Container | Static IP | External URL |
|---|---|---|---|
| Core Infrastructure | |||
| Reverse Proxy | traefik | 172.18.0.3 | traefik.xtrm-lab.org |
| Docker Socket | dockersocket | 172.18.0.2 | - |
| Dashboard | homarr | 172.18.0.4 | xtrm-lab.org |
| Security | |||
| Identity Provider | authentik | 172.18.0.11 | auth.xtrm-lab.org |
| Authentik Worker | authentik-worker | 172.18.0.12 | - |
| Password Manager | vaultwarden | 172.18.0.15 | vault.xtrm-lab.org |
| Databases | |||
| PostgreSQL | postgresql17 | 172.18.0.13 | - |
| Redis | Redis | 172.18.0.14 | - |
| DNS | |||
| Pi-hole (Unraid) | binhex-official-pihole | 192.168.31.4 | ph1.xtrm-lab.org |
| Unbound (Unraid) | unbound | 192.168.31.5 | - |
| DevOps | |||
| Git Server | gitea | 172.18.0.31 | git.xtrm-lab.org |
| CI/CD Server | woodpecker-server | 172.18.0.32 | ci.xtrm-lab.org |
| CI/CD Agent | woodpecker-agent | 172.18.0.33 | - |
| Network Management | |||
| NetBox | netbox | 172.24.0.5 | netbox.xtrm-lab.org |
| NetBox Worker | netbox-worker | 172.24.0.6 | - |
| NetBox PostgreSQL | netbox-postgres | 172.24.0.4 | - |
| NetBox Redis | netbox-redis | 172.24.0.2 | - |
| NetBox Redis Cache | netbox-redis-cache | 172.24.0.3 | - |
| NetDisco Web | netdisco-web | 172.18.0.41 | netdisco.xtrm-lab.org |
| NetDisco Backend | netdisco-backend | 172.18.0.42 | - |
| Unimus | unimus | host | unimus.xtrm-lab.org |
| Slurp'it Discovery | |||
| Slurp'it Portal | slurpit-portal | dockerproxy | slurpit.xtrm-lab.org |
| Slurp'it Scanner | slurpit-scanner | slurpit-network | - |
| Slurp'it Scraper | slurpit-scraper | slurpit-network | - |
| Slurp'it Warehouse | slurpit-warehouse | slurpit-network | - |
| Slurp'it MariaDB | slurpit-mariadb | slurpit-network | - |
| Slurp'it MongoDB | slurpit-mongodb | slurpit-network | - |
| Monitoring | |||
| Uptime Kuma | UptimeKuma | 172.18.0.20 | uptime.xtrm-lab.org |
| Uptime Kuma API | Uptime-Kuma-API | 172.18.0.18 | - |
| AutoKuma | AutoKuma | 172.18.0.19 | - |
| NetAlertX | NetAlertX | host | netalert.xtrm-lab.org |
| Speedtest Tracker | speedtest-tracker | 172.18.0.21 | speedtest.xtrm-lab.org |
| Productivity | |||
| Actual Budget | actual-budget | 172.18.0.16 | actual.xtrm-lab.org |
| n8n | n8n | 172.18.0.17 | n8n.xtrm-lab.org |
| Karakeep | karakeep | 172.18.0.25 | karakeep.xtrm-lab.org |
| Media & Storage | |||
| Plex | plex | host | plex.xtrm-lab.org |
| Nextcloud | Nextcloud | 172.18.0.24 | nextcloud.xtrm-lab.org |
| Libation | Libation | 172.18.0.23 | - |
| Transmission | transmission | 172.18.0.26 | - |
| Time Machine | TimeMachine | 192.168.31.12 | - |
| Remote Access | |||
| RustDesk ID | rustdesk-hbbs | bridge | rustdesk.xtrm-lab.org |
| RustDesk Relay | rustdesk-hbbr | bridge | - |
| Other | |||
| Home Assistant | HomeAssistant_inabox | host | ha.xtrm-lab.org |
| UrBackup | UrBackup | host | urbackup.xtrm-lab.org |
| Portainer | portainer | bridge | 192.168.31.2:9002 |
| Pangolin | pangolin | 172.18.0.51 | - |
Docker Compose Managed Stacks
| Stack | Location | Containers |
|---|---|---|
| NetBox | /mnt/user/appdata/netbox/docker-compose.yml |
netbox, netbox-worker, netbox-postgres, netbox-redis, netbox-redis-cache |
| NetDisco | /mnt/user/appdata/netdisco/docker-compose.yml |
netdisco-web, netdisco-backend |
| Gitea | /mnt/user/appdata/gitea/docker-compose.yml |
gitea |
| Woodpecker | /mnt/user/appdata/woodpecker/docker-compose.yml |
woodpecker-server, woodpecker-agent |
| Pangolin | /mnt/user/appdata/pangolin/docker-compose.yml |
pangolin |
| Slurp'it | /mnt/user/appdata/slurpit/docker-compose.yml |
slurpit-portal, slurpit-scanner, slurpit-scraper, slurpit-warehouse, slurpit-mariadb, slurpit-mongodb |
NetBox Plugins
| Plugin | Version | Status |
|---|---|---|
| slurpit_netbox | 1.2.7 | Active |
Note: Plugin config mounted from /mnt/user/appdata/netbox/config/plugins.py
DNS Architecture
┌─────────────────────────────────────┐
│ Internet │
│ (DoH/DoT/DoQ: dns.xtrm-lab.org) │
└───────────────┬─────────────────────┘
│
┌───────────────▼─────────────────────┐
│ MikroTik hAP ax³ (192.168.31.1) │
│ WAN: 62.73.120.142 │
│ Ports: 443(DoH), 853(DoT), │
│ 8853(DoQ), 53(DNS) │
└───────────────┬─────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ AdGuard Home │ │ Unraid Server │ │ LAN Devices │
│ 172.17.0.5 │ │ 192.168.31.2 │ │ 192.168.31.x │
│ Primary DNS │ │ │ │ │
│ DoH/DoT/DoQ Server │ └────────┬─────────┘ └──────────────────┘
└────────┬─────────────┘ │
│ ▼
▼ ┌──────────────────┐
┌──────────────────┐ │ Pi-hole (Unraid) │
│ Unbound (Router) │ │ 192.168.31.4 │
│ 172.17.0.3 │ │ Secondary DNS │
│ Recursive DNS │ └────────┬─────────┘
└──────────────────┘ │
▼
┌──────────────────┐
│ Unbound (Unraid) │
│ 192.168.31.5 │
│ Recursive DNS │
└──────────────────┘
Encrypted DNS Endpoints (MikroTik AdGuard Home):
- DoH:
https://dns.xtrm-lab.org/dns-query - DoT:
tls://dns.xtrm-lab.org:853 - DoQ:
quic://dns.xtrm-lab.org:8853
Current NAT/Port Forwarding (MikroTik)
| Rule | Protocol | WAN Port | Destination | Purpose |
|---|---|---|---|---|
| Forward HTTP | TCP | 80 | 192.168.31.2:8001 | Traefik HTTP |
| Forward HTTPS | TCP | 443 | 192.168.31.2:44301 | Traefik HTTPS |
| Plex | TCP | 32400 | 192.168.31.2:32400 | Plex Media Server |
| Transmission | TCP/UDP | 51413 | 192.168.31.2:51413 | BitTorrent |
| DoT | TCP | 853 | 172.17.0.5:853 | DNS over TLS (AdGuard) |
| DoQ | UDP | 8853 | 172.17.0.5:8853 | DNS over QUIC (AdGuard) |
| DNS Force | UDP/TCP | 53 | 172.17.0.5:53 | Force LAN DNS to AdGuard Home |
| AdGuard Web UI | TCP | - | 172.17.0.5:80 | Internal access via router IP |
| RustDesk | TCP/UDP | 21115-21119 | 192.168.31.2 | RustDesk Server |
Note: DoH (443) shares port with Traefik HTTPS. External DoH clients should use the dedicated endpoint or internal access.
Traefik Configuration
Entry Points:
- HTTP (:80) → Redirects to HTTPS
- HTTPS (:443)
Certificate Resolver: Cloudflare DNS Challenge
Docker Provider Constraint: traefik.constraint=valid
- Containers need this label to be auto-discovered
- Otherwise add routes to
/mnt/user/appdata/traefik/dynamic.yml
TLS Certificates Location: /mnt/user/appdata/traefik/certs/
xtrm-lab.org.crt- Wildcard certificate chainxtrm-lab.org.key- Private key
Reference Documents
- Phase 1: Global DNS Portability
- Phase 2: Fossorial Tunnel Stack
- Phase 3: Identity & Zero Trust
- Phase 4: Remote Gaming
- Phase 5: RustDesk Setup
- Phase 6: Portainer Management
- Phase 7: Gitea GitOps
- Phase 8: NetDisco Integration
- Container IP Assignments
- MikroTik WiFi & CAPsMAN
Backup & Cloud Sync
Rclone Configuration
| Remote | Type | Purpose |
|---|---|---|
| drive: | Google Drive | Cloud backup storage |
Config Location: /root/.config/rclone/rclone.conf
Automated Backups
| Backup | Source | Destination (Local) | Destination (Cloud) | Schedule | Retention |
|---|---|---|---|---|---|
| Flash Backup (Unraid plugin) | /boot/config/ | /mnt/user/Backup/flash | drive:Backups/flash | Daily (via Unraid) | 49 files |
| Flash Backup (Custom script) | /boot/config/ | /mnt/user/Backup/unraid-flash | drive:Backups/unraid-flash | Daily 3:00 AM | 7 days |
Flash Backup Script
- Script Path: /boot/config/plugins/user.scripts/scripts/flash-backup/script
- Schedule: 0 3 * * * (Daily at 3:00 AM)
- Retention: 7 days
- Format: flash-backup-YYYY-MM-DD.tar.gz
- Symlink: flash-backup-latest.tar.gz
Cloud Sync Summary
| Folder | Google Drive Path | Size | Files |
|---|---|---|---|
| /mnt/user/Backup/flash | drive:Backups/flash | 60.37 GiB | 49 |
| /mnt/user/Backup/unraid-flash | drive:Backups/unraid-flash | 371 MiB | 2 |