Restructure docs: archive VLAN migration, update IPs to VLAN 10
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Major documentation cleanup after VLAN migration completion:
- Archive 12 VLAN project docs to archive/vlan-migration/
- Archive 5 done WIP docs (VLAN proposals, AI stack, Fossorial, DNS backup)
- Create standing reference docs 08-DNS-ARCHITECTURE and 09-TAILSCALE-VPN
- Renumber docs to clean 01-09 sequence with merged CHANGELOG
- Update all active docs from stale 192.168.31.x to current VLAN 10 IPs
- Fix CSS1 (.10.9→.10.3) and ZX1 (.10.7→.10.4) IPs in hardware inventory
- Clean 06-VLAN-DEVICE-ASSIGNMENT: remove migration columns/sections, fix VLAN 25 subnet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kaloyan Danchev
2026-02-06 12:45:16 +02:00
parent 81f2f03400
commit ec9659d0cb
34 changed files with 1145 additions and 631 deletions

View File

@@ -0,0 +1,137 @@
# Fossorial Tunnel Stack (Pangolin + Gerbil)
**Status:** 💡 IDEA
**Priority:** Low
**Depends On:** Hardware upgrade (XTRM-N1 for resilience)
---
## Overview
Self-hosted tunnel solution for exposing services without Cloudflare/VPS dependency.
| Component | Purpose |
|-----------|---------|
| **Pangolin** | Central controller/dashboard |
| **Gerbil** | WireGuard peer manager |
| **Newt** | Tunnel connector agent |
---
## Why Fossorial?
Current state uses Traefik + Cloudflare DNS for external access.
Fossorial would provide:
- Independent tunneling (no Cloudflare dependency)
- Self-healing WireGuard connections
- Web-based tunnel management
- Potential for MikroTik container fallback
---
## Architecture
```
Internet (62.73.120.142)
▼ UDP 51820
┌─────────────────────┐
│ Gerbil (WG Manager) │
│ :51820 WireGuard │
│ :8080 API │
└─────────┬───────────┘
┌─────────▼───────────┐
│ Pangolin (Dashboard)│
│ :3000 Web UI │
└─────────┬───────────┘
┌─────────▼───────────┐
│ Newt (Connector) │
│ Dials out to peers │
└─────────────────────┘
```
---
## Prerequisites
- [ ] Port 51820/UDP forwarded on MikroTik
- [ ] `fossorial` Docker network created
- [ ] Secret key generated
---
## Deployment Steps
### 1. Create Network
```bash
docker network create --driver bridge fossorial
```
### 2. Deploy Pangolin
```bash
docker run -d \
--name pangolin \
--network fossorial \
-p 3000:3000 \
-v /mnt/user/appdata/pangolin/data:/app/data \
-e PANGOLIN_BASE_URL=https://pangolin.xtrm-lab.org \
-e PANGOLIN_SECRET_KEY=$(openssl rand -hex 32) \
fossoriumtech/pangolin:latest
```
### 3. Deploy Gerbil
```bash
docker run -d \
--name gerbil \
--network fossorial \
--cap-add=NET_ADMIN \
-p 51820:51820/udp \
-p 8080:8080 \
-v /mnt/user/appdata/gerbil:/app/data \
-e GERBIL_PUBLIC_IP=62.73.120.142 \
-e GERBIL_PUBLIC_PORT=51820 \
fossoriumtech/gerbil:latest
```
### 4. Deploy Newt
```bash
docker run -d \
--name newt \
--network fossorial \
-v /mnt/user/appdata/newt:/app/data \
-e NEWT_PANGOLIN_URL=https://pangolin.xtrm-lab.org \
-e NEWT_ENDPOINT=62.73.120.142:51820 \
fossoriumtech/newt:latest
```
### 5. MikroTik NAT
```routeros
/ip/firewall/nat add chain=dstnat \
action=dst-nat to-addresses=192.168.31.2 to-ports=51820 \
protocol=udp dst-port=51820 \
comment="Fossorial WireGuard"
```
---
## Current WireGuard (Not Affected)
Existing back-to-home-vpn uses port **59188**, completely separate.
---
## Decision Points
1. **Is this needed?** Tailscale + Traefik already provides external access
2. **When to implement?** After XTRM-N1 survival node for fallback option
3. **Use case?** If Cloudflare/Tailscale goes down
---
## References
- Original planning: `archive/02-PHASE2-FOSSORIAL-STACK.md`
- GitHub: https://github.com/fossoriumtech

View File

@@ -0,0 +1,169 @@
# Local AI Stack on Unraid
**Status:** ✅ Deployed
**Last Updated:** 2026-01-26
---
## Current Deployment
| Component | Status | URL/Port |
|-----------|--------|----------|
| Ollama | ✅ Running | http://192.168.31.2:11434 |
| Open WebUI | ✅ Running | http://192.168.31.2:3080 |
| Intel GPU | ✅ Enabled | /dev/dri passthrough |
### Models Installed
| Model | Size | Type |
|-------|------|------|
| qwen2.5-coder:7b | 4.7 GB | Base coding LLM |
| unraid-assistant | 4.7 GB | Custom model with infrastructure knowledge |
---
## Custom Model: unraid-assistant
A fine-tuned system prompt model that knows the xtrm-lab.org infrastructure:
### Knowledge Included
- **Network topology**: All VLANs (10,20,25,30,31,35,40,50), IPs, gateways
- **45+ Docker containers**: Names, images, ports, purposes
- **RouterOS 7**: Commands, VLAN patterns, firewall rules
- **Traefik**: Labels, routing, SSL configuration
- **Authentik**: SSO middleware, provider setup
- **External URLs**: All xtrm-lab.org services
### Usage
```bash
# Terminal (SSH to Unraid)
ai "How do I add a device to the IoT VLAN?"
ai "What port is gitea running on?"
ai "Show me Traefik labels for a new app with Authentik"
# Interactive mode
ai
```
### Rebuild Model
If infrastructure changes, update and rebuild:
```bash
# Edit the Modelfile
nano /mnt/user/appdata/ollama/Modelfile-unraid
# Rebuild
docker exec ollama ollama create unraid-assistant -f /root/.ollama/Modelfile-unraid
```
---
## Hardware
| Component | Spec |
|-----------|------|
| CPU | Intel N100 (4 cores) |
| RAM | 16GB (shared with Docker) |
| GPU | Intel UHD (iGPU via /dev/dri) |
| Storage | 1.7TB free on array |
### Performance
- ~1 token/sec with 7B models
- Responses take 30-90 seconds
- Suitable for occasional use, not real-time chat
---
## Containers Stopped for RAM
To free ~4.8GB for AI workloads:
| Container | RAM Freed | Purpose |
|-----------|-----------|---------|
| karakeep | 1.68 GB | Bookmark manager |
| unimus | 1.62 GB | Network backup |
| homarr | 686 MB | Dashboard |
| netdisco-web | 531 MB | Network discovery UI |
| netdisco-backend | 291 MB | Network discovery |
To restart if needed:
```bash
docker start karakeep unimus homarr netdisco-web netdisco-backend
```
---
## Docker Configuration
### Ollama
```bash
docker run -d \
--name ollama \
--restart unless-stopped \
--device /dev/dri \
-v /mnt/user/appdata/ollama:/root/.ollama \
-p 11434:11434 \
ollama/ollama
```
### Open WebUI
```bash
docker run -d \
--name open-webui \
--restart unless-stopped \
-p 3080:8080 \
-e OLLAMA_BASE_URL=http://192.168.31.2:11434 \
-v /mnt/user/appdata/open-webui:/app/backend/data \
ghcr.io/open-webui/open-webui:main
```
### AI Command Helper
```bash
# /usr/local/bin/ai
#\!/bin/bash
MODEL="unraid-assistant"
if [ $# -eq 0 ]; then
docker exec -it ollama ollama run $MODEL
else
docker exec ollama ollama run $MODEL "$*"
fi
```
---
## Open WebUI RAG Setup
For detailed documentation beyond system prompt:
1. Go to http://192.168.31.2:3080
2. **Workspace****Knowledge****+ Create**
3. Name: `Infrastructure`
4. Upload docs from `/mnt/user/appdata/open-webui/docs/`
Infrastructure docs are pre-copied to that location.
---
## Future: N5 Air (Ryzen AI 5 255) Upgrade
Planning to migrate AI stack to N5 Air with Ryzen AI 5 255:
| Metric | N100 (current) | Ryzen AI 5 255 |
|--------|----------------|--------------|
| Speed | ~1 tok/s | ~5-8 tok/s |
| Max model | 7B | 14B-32B |
| Response time | 30-90s | 5-15s |
Features XDNA NPU (16 TOPS) for potential AI acceleration. DDR5 + 6c/12t CPU will significantly improve inference.
---
## Files
| File | Purpose |
|------|---------|
| /mnt/user/appdata/ollama/Modelfile-unraid | Custom model definition |
| /usr/local/bin/ai | Terminal helper command |
| /mnt/user/appdata/open-webui/docs/ | RAG documents |

View File

@@ -1,8 +1,8 @@
# Archived Documentation
> ⚠️ **OBSOLETE - DO NOT UPDATE**
> **OBSOLETE - DO NOT UPDATE**
These documents are from the legacy documentation structure (pre-2026-01-25).
These documents are from completed projects and legacy documentation.
They are kept for historical reference only.
**For current documentation, see the parent `docs/` folder:**
@@ -10,7 +10,28 @@ They are kept for historical reference only.
- `02-SERVICES-CRITICAL.md` - Essential services
- `03-SERVICES-OTHER.md` - Non-critical services
- `04-HARDWARE-INVENTORY.md` - Hardware details
- `05-CHANGELOG.md` - Major events
- `05-PORT-UTILIZATION.md` - Device port assignments
- `06-VLAN-DEVICE-ASSIGNMENT.md` - VLAN device mapping
- `07-WIFI-CAPSMAN-CONFIG.md` - WiFi and CAPsMAN settings
- `08-DNS-ARCHITECTURE.md` - DNS failover architecture
- `09-TAILSCALE-VPN.md` - Tailscale VPN setup
- `CHANGELOG.md` - Change history
## Subfolders
### vlan-migration/
12 documents from the VLAN migration project (completed 2026-01-31):
- Migration plans (v1, v2, v3)
- Implementation status trackers
- Setup progress logs
- DNS/AdGuard/Tailscale project docs (superseded by standing docs 08- and 09-)
- Device migration worksheet
### Legacy Docs (root archive/)
- Pre-2026-01-25 documentation structure
- Completed WIP items (VLAN proposals, AI stack, Fossorial tunnels)
- Historical changelogs
**Do not reference these archived documents for current state.**
All relevant information has been migrated to the new structure.

View File

@@ -0,0 +1,332 @@
# WIP: VLAN Network Segmentation Proposal
**Status:** Planning
**Created:** 2026-01-25
**Updated:** 2026-01-25
---
## Decisions Made
- ✅ Separate Camera VLAN (VLAN 35)
- ✅ Guest WiFi: Password only (no captive portal)
- ✅ Keep 192.168.31.0/24 during transition (VLAN 1)
---
## Current State
Single flat network: `192.168.31.0/24` (will become transition VLAN)
---
## Proposed VLAN Architecture
```
┌─────────────────┐
│ INTERNET │
└────────┬────────┘
┌────────▼────────┐
│ MikroTik hAP │
│ (Router/FW) │
└────────┬────────┘
┌───────────┬───────────┬───────────┬───┴───┬───────────┬───────────┐
│ │ │ │ │ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌▼────────┐ ┌▼────────┐ ┌▼────────┐
│ VLAN 1 │ │ VLAN 10 │ │ VLAN 20 │ │ VLAN 30 │ │ VLAN 35 │ │ VLAN 40 │ │ VLAN 50 │
│ Legacy │ │ Mgmt │ │ Trusted │ │ IoT │ │ Cameras │ │ Servers │ │ Guest │
│.31.0/24 │ │.10.0/24 │ │.20.0/24 │ │.30.0/24 │ │.35.0/24 │ │.40.0/24 │ │.50.0/24 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
```
---
## VLAN Definitions
| VLAN ID | Name | Subnet | Gateway | Purpose |
|---------|------|--------|---------|---------|
| 1 | Legacy/Transition | 192.168.31.0/24 | .31.1 | Current network (temporary) |
| 10 | Management | 192.168.10.0/24 | .10.1 | Infrastructure admin |
| 20 | Trusted | 192.168.20.0/24 | .20.1 | Personal devices |
| 30 | IoT | 192.168.30.0/24 | .30.1 | Smart home devices |
| 35 | Cameras | 192.168.35.0/24 | .35.1 | Security cameras (isolated) |
| 40 | Servers | 192.168.40.0/24 | .40.1 | Exposed services |
| 50 | Guest | 192.168.50.0/24 | .50.1 | Visitor WiFi |
---
## VLAN 1: Legacy/Transition
**Purpose:** Current network - devices migrate from here
| Device | IP | Target VLAN |
|--------|-----|-------------|
| MikroTik | 192.168.31.1 | VLAN 10 |
| Unraid | 192.168.31.2 | VLAN 10 |
| AdGuard | 192.168.31.4 | VLAN 40 |
| LG TV | 192.168.31.100 | VLAN 30 |
**Note:** This VLAN will be deprecated after migration.
---
## VLAN 10: Management
**Purpose:** Infrastructure administration only
| Device | IP | Description |
|--------|-----|-------------|
| MikroTik | 192.168.10.1 | Router/Gateway |
| Unraid | 192.168.10.2 | Server management |
| CSS326 | 192.168.10.3 | Switch management |
| cAP ac | 192.168.10.4 | AP management |
**Access Rules:**
- ✅ Full access to all VLANs
- ✅ SSH, Web UI, API access
- ❌ No access FROM other VLANs (except established)
---
## VLAN 20: Trusted
**Purpose:** Personal/family devices
| Device Type | DHCP Range | Static Range |
|-------------|------------|--------------|
| Reserved | - | .20.10-.50 |
| Laptops | .20.100-.130 | - |
| Phones | .20.131-.160 | - |
| Tablets | .20.161-.180 | - |
| Other | .20.181-.220 | - |
**Access Rules:**
- ✅ Internet access
- ✅ Access to Servers VLAN
- ✅ Access to IoT VLAN (control devices)
- ✅ Access to Cameras VLAN (view feeds)
- ❌ No access to Management VLAN
- ❌ No access from Guest VLAN
---
## VLAN 30: IoT
**Purpose:** Smart home devices (isolated)
| Device Type | DHCP Range | Examples |
|-------------|------------|----------|
| Smart TVs | .30.100-.110 | LG TV, Apple TV |
| Speakers | .30.111-.130 | Sonos, HomePod |
| Hubs | .30.131-.150 | Zigbee, Z-Wave |
| Sensors | .30.151-.180 | Motion, temp |
| Other | .30.181-.220 | Plugs, lights |
**Access Rules:**
- ✅ Internet access (filtered)
- ✅ Local DNS (AdGuard)
- ✅ mDNS relay from Trusted
- ❌ No access to Management
- ❌ No access to Cameras
- ❌ No access to Servers (except specific)
- ❌ Cannot initiate to Trusted
---
## VLAN 35: Cameras
**Purpose:** Security cameras (highly isolated)
| Device Type | DHCP Range | Examples |
|-------------|------------|----------|
| Indoor | .35.100-.120 | - |
| Outdoor | .35.121-.140 | - |
| NVR | .35.10 | Recording server |
**Access Rules:**
- ⚠️ Limited internet (firmware updates only)
- ✅ Access to NVR only
- ✅ Trusted can VIEW (no control)
- ❌ No access to any other VLAN
- ❌ No inter-camera communication
- ❌ Blocked: China, Russia IPs (common camera callback)
---
## VLAN 40: Servers/DMZ
**Purpose:** Services accessible externally
| Service | IP | Ports | Description |
|---------|-----|-------|-------------|
| Traefik | 192.168.40.2 | 80,443 | Reverse proxy |
| AdGuard | 192.168.40.4 | 53,853,443 | DNS server |
| Gitea | 192.168.40.10 | 3000 | Git hosting |
| Woodpecker | 192.168.40.11 | 8000 | CI/CD |
| Plex | 192.168.40.20 | 32400 | Media |
**Access Rules:**
- ✅ Internet access
- ✅ Inbound from WAN (via NAT)
- ✅ Access from Trusted
- ❌ Cannot initiate to other VLANs
---
## VLAN 50: Guest
**Purpose:** Visitor WiFi (password protected, no captive portal)
| Setting | Value |
|---------|-------|
| DHCP Range | 192.168.50.100-.200 |
| Lease Time | 4 hours |
| Bandwidth | 50 Mbps limit |
| Client Isolation | Enabled |
**Access Rules:**
- ✅ Internet access only
- ❌ No access to ANY internal VLAN
- ❌ No inter-client communication
---
## Firewall Matrix
```
┌─────────────┬────────┬──────┬─────────┬─────┬─────────┬─────────┬───────┐
│ From \ To │ Legacy │ Mgmt │ Trusted │ IoT │ Cameras │ Servers │ Guest │
├─────────────┼────────┼──────┼─────────┼─────┼─────────┼─────────┼───────┤
│ Legacy │ ✅ │ ✅ │ ✅ │ ✅ │ ✅ │ ✅ │ ✅ │
│ Management │ ✅ │ ✅ │ ✅ │ ✅ │ ✅ │ ✅ │ ✅ │
│ Trusted │ ✅ │ ❌ │ ✅ │ ✅ │ 👁️ │ ✅ │ ❌ │
│ IoT │ ❌ │ ❌ │ ❌ │ ⚠️ │ ❌ │ ⚠️ │ ❌ │
│ Cameras │ ❌ │ ❌ │ ❌ │ ❌ │ ⚠️ │ ❌ │ ❌ │
│ Servers │ ❌ │ ❌ │ ❌ │ ❌ │ ❌ │ ✅ │ ❌ │
│ Guest │ ❌ │ ❌ │ ❌ │ ❌ │ ❌ │ ❌ │ ⚠️ │
│ Internet │ ❌ │ ❌ │ ❌ │ ❌ │ ❌ │ ✅ │ ❌ │
└─────────────┴────────┴──────┴─────────┴─────┴─────────┴─────────┴───────┘
✅ = Full access
❌ = Blocked
⚠️ = Limited (specific ports/IPs)
👁️ = View only (cameras: RTSP/HTTP streams)
```
---
## DNS Configuration
| VLAN | DNS Server | Filtering Level |
|------|------------|-----------------|
| 1 Legacy | 192.168.31.1 | Current setup |
| 10 Management | 192.168.10.1 | Minimal |
| 20 Trusted | 192.168.40.4 | Standard |
| 30 IoT | 192.168.40.4 | IoT blocklist |
| 35 Cameras | 192.168.40.4 | Strict + geo-block |
| 40 Servers | 8.8.8.8/1.1.1.1 | None (external) |
| 50 Guest | 192.168.40.4 | Strict |
---
## WiFi SSID Mapping
| SSID | VLAN | Band | Security | Hidden |
|------|------|------|----------|--------|
| Home | 20 | 2.4+5 GHz | WPA3 | No |
| Home-IoT | 30 | 2.4 GHz | WPA2 | No |
| Home-Guest | 50 | 2.4+5 GHz | WPA2 | No |
| Admin | 10 | 5 GHz | WPA3 | Yes |
---
## MikroTik Implementation
### 1. Create VLANs
```routeros
/interface vlan
add interface=bridge name=vlan10-mgmt vlan-id=10
add interface=bridge name=vlan20-trusted vlan-id=20
add interface=bridge name=vlan30-iot vlan-id=30
add interface=bridge name=vlan35-cameras vlan-id=35
add interface=bridge name=vlan40-servers vlan-id=40
add interface=bridge name=vlan50-guest vlan-id=50
```
### 2. IP Addresses
```routeros
/ip address
add address=192.168.10.1/24 interface=vlan10-mgmt
add address=192.168.20.1/24 interface=vlan20-trusted
add address=192.168.30.1/24 interface=vlan30-iot
add address=192.168.35.1/24 interface=vlan35-cameras
add address=192.168.40.1/24 interface=vlan40-servers
add address=192.168.50.1/24 interface=vlan50-guest
```
### 3. DHCP Pools
```routeros
/ip pool
add name=pool-trusted ranges=192.168.20.100-192.168.20.220
add name=pool-iot ranges=192.168.30.100-192.168.30.220
add name=pool-cameras ranges=192.168.35.100-192.168.35.140
add name=pool-servers ranges=192.168.40.100-192.168.40.150
add name=pool-guest ranges=192.168.50.100-192.168.50.200
```
### 4. Camera Geo-Blocking
```routeros
/ip firewall address-list
add list=blocked-countries address=0.0.0.0/8 comment="CN/RU blocks - add actual ranges"
/ip firewall filter
add chain=forward action=drop src-address=192.168.35.0/24 dst-address-list=blocked-countries
```
---
## Migration Plan
### Phase 1: Preparation (No Downtime)
- [ ] Document all static IPs and MAC addresses
- [ ] Create device inventory with target VLANs
- [ ] Configure VLANs on MikroTik (inactive)
- [ ] Configure switch trunk ports
- [ ] Test on isolated port
### Phase 2: Infrastructure (Brief Downtime)
- [ ] Create VLAN interfaces and IPs
- [ ] Configure DHCP per VLAN
- [ ] Move Unraid management to VLAN 10
- [ ] Move AdGuard to VLAN 40
- [ ] Update container networks
### Phase 3: WiFi (Rolling)
- [ ] Create new SSIDs per VLAN
- [ ] Move personal devices to VLAN 20
- [ ] Move IoT devices to VLAN 30
- [ ] Test mDNS/Bonjour relay
### Phase 4: Cameras & Security
- [ ] Move cameras to VLAN 35
- [ ] Implement geo-blocking
- [ ] Test camera isolation
- [ ] Verify Trusted can view feeds
### Phase 5: Cleanup
- [ ] Implement all firewall rules
- [ ] Enable DNS enforcement
- [ ] Migrate remaining devices from VLAN 1
- [ ] Document final configuration
- [ ] Deprecate VLAN 1 (keep for emergency)
---
## Rollback Plan
If issues occur:
1. All devices can temporarily use VLAN 1 (legacy)
2. MikroTik remains accessible on 192.168.31.1
3. Keep VLAN 1 DHCP active during transition

View File

@@ -0,0 +1,142 @@
# VLAN Network Segmentation
**Status:** 📋 PLANNED
**Priority:** Medium
**Risk:** HIGH (network disruption during implementation)
---
## Overview
Segment flat 192.168.31.0/24 network into VLANs for security isolation.
---
## Proposed VLANs
| VLAN | Name | Subnet | Gateway | Purpose |
|------|------|--------|---------|---------|
| 1 | Management | 192.168.31.0/24 | 192.168.31.1 | Infrastructure devices only |
| 10 | Secure | 192.168.10.0/24 | 192.168.10.1 | Trusted devices, servers |
| 20 | IoT | 192.168.20.0/24 | 192.168.20.1 | Smart home, cameras |
| 30 | Kids | 192.168.30.0/24 | 192.168.30.1 | Kids devices |
| 40 | Guest | 192.168.40.0/24 | 192.168.40.1 | Guest WiFi |
---
## WiFi SSID Mapping
| SSID | VLAN | Purpose |
|------|------|---------|
| XTRM | 10 | Primary (trusted devices) |
| XTRM-IoT | 20 | IoT devices |
| XTRM-Kids | 30 | Kids devices |
| XTRM-Guest | 40 | Guest access |
---
## Device Assignments
### VLAN 10 - Secure
| Device | Current IP | New IP |
|--------|------------|--------|
| XTRM-U/N5 | 192.168.31.2 | 192.168.10.2 |
| Nobara PC | 192.168.31.95 | 192.168.10.10 |
| MacBook | 192.168.31.99 | 192.168.10.15 |
| S25 Ultra | 192.168.31.98 | 192.168.10.20 |
### VLAN 20 - IoT
| Device | Current IP | New IP |
|--------|------------|--------|
| Home Assistant | 192.168.31.102 | 192.168.20.2 |
| Chromecast | 192.168.31.134 | 192.168.20.10 |
| Roborock S7 | 192.168.31.104 | 192.168.20.11 |
| Reolink Doorbell | 192.168.31.68 | 192.168.20.13 |
| HP Printer | 192.168.31.19 | 192.168.20.20 |
### VLAN 30 - Kids
| Device | Current IP | New IP |
|--------|------------|--------|
| Nora MacBook | 192.168.31.79 | 192.168.30.10 |
| Kimi Notebook | 192.168.31.108 | 192.168.30.11 |
| Dancho iPhone | 192.168.31.114 | 192.168.30.13 |
---
## Cross-VLAN Access Requirements
### S25 → Chromecast (Casting)
```routeros
/ip/firewall/filter add chain=forward \
src-address=192.168.10.0/24 dst-address=192.168.20.0/24 \
dst-port=8008,8009,8443 protocol=tcp action=accept
```
### Secure → Home Assistant
```routeros
/ip/firewall/filter add chain=forward \
src-address=192.168.10.0/24 dst-address=192.168.20.2 \
dst-port=8123 protocol=tcp action=accept
```
### mDNS Reflector (Device Discovery)
```routeros
/ip/dns/set mdns-repeat-ifaces=vlan10,vlan20
```
---
## Implementation Steps
### Phase 1: Router (HAP1)
1. Create VLAN interfaces
2. Assign IP addresses
3. Create DHCP servers per VLAN
4. Configure firewall rules
### Phase 2: Switch (CSS326)
1. Enable VLAN mode in SwOS
2. Configure trunk port (to HAP1)
3. Assign access VLANs to ports
4. Set PVIDs
### Phase 3: WiFi (CAPsMAN)
1. Create VLAN-tagged SSIDs
2. Update provisioning rules
3. Apply to CAP
---
## Risks
| Risk | Impact | Mitigation |
|------|--------|------------|
| All devices lose connectivity | HIGH | Schedule maintenance window |
| Docker br0 containers break | MEDIUM | Reconfigure macvlan |
| Static IPs need updating | LOW | Pre-configure DHCP reservations |
---
## Rollback
Disable VLAN filtering immediately:
```routeros
/interface/bridge/set bridge vlan-filtering=no
```
---
## Prerequisites
- [ ] Map CSS326 switch ports to devices
- [ ] Backup MikroTik config
- [ ] Schedule maintenance window (30-60 min)
- [ ] Decide WiFi passwords for new SSIDs
- [ ] Console/serial access to router (in case of lockout)
---
## References
- Full planning document: `archive/10-VLAN-NETWORK-SEGMENTATION.md`
- Device inventory: `archive/11-NETWORK-ASSET-INVENTORY.md`

View File

@@ -0,0 +1,355 @@
# VLAN Migration Plan
**Created:** 2026-01-25
**Status:** Planning
**Risk Level:** High (DNS/Network critical)
---
## Overview
Migrate from flat 192.168.31.0/24 network to segmented VLANs while maintaining service continuity.
### Critical Dependencies
- **Unraid (192.168.31.2)** - Hosts 40+ Docker containers including AdGuard
- **AdGuard Unraid (192.168.31.4)** - Secondary DNS server
- **AdGuard MikroTik (172.17.0.2)** - Primary DNS server (container on router)
---
## Phase 1: Pre-Migration Setup (No Downtime)
### 1.1 Enable REST API on MikroTik
```routeros
/ip service set www-ssl disabled=no
/ip service set api-ssl disabled=no
```
### 1.2 Create VLAN Interfaces on Router
```routeros
# Create VLANs on bridge
/interface vlan
add interface=bridge name=vlan10-mgmt vlan-id=10
add interface=bridge name=vlan20-trusted vlan-id=20
add interface=bridge name=vlan25-kids vlan-id=25
add interface=bridge name=vlan30-iot vlan-id=30
add interface=bridge name=vlan35-cameras vlan-id=35
add interface=bridge name=vlan40-servers vlan-id=40
add interface=bridge name=vlan50-guest vlan-id=50
```
### 1.3 Assign Gateway IPs to VLANs
```routeros
/ip address
add address=192.168.10.1/24 interface=vlan10-mgmt
add address=192.168.20.1/24 interface=vlan20-trusted
add address=192.168.25.1/24 interface=vlan25-kids
add address=192.168.30.1/24 interface=vlan30-iot
add address=192.168.35.1/24 interface=vlan35-cameras
add address=192.168.40.1/24 interface=vlan40-servers
add address=192.168.50.1/24 interface=vlan50-guest
```
### 1.4 Create DHCP Pools
```routeros
/ip pool
add name=pool-mgmt ranges=192.168.10.100-192.168.10.200
add name=pool-trusted ranges=192.168.20.100-192.168.20.200
add name=pool-kids ranges=192.168.25.100-192.168.25.200
add name=pool-iot ranges=192.168.30.100-192.168.30.200
add name=pool-cameras ranges=192.168.35.100-192.168.35.200
add name=pool-servers ranges=192.168.40.100-192.168.40.200
add name=pool-guest ranges=192.168.50.100-192.168.50.200
```
### 1.5 Create DHCP Servers
```routeros
/ip dhcp-server
add address-pool=pool-mgmt interface=vlan10-mgmt name=dhcp-mgmt
add address-pool=pool-trusted interface=vlan20-trusted name=dhcp-trusted
add address-pool=pool-kids interface=vlan25-kids name=dhcp-kids
add address-pool=pool-iot interface=vlan30-iot name=dhcp-iot
add address-pool=pool-cameras interface=vlan35-cameras name=dhcp-cameras
add address-pool=pool-servers interface=vlan40-servers name=dhcp-servers
add address-pool=pool-guest interface=vlan50-guest name=dhcp-guest
/ip dhcp-server network
add address=192.168.10.0/24 gateway=192.168.10.1 dns-server=192.168.10.10
add address=192.168.20.0/24 gateway=192.168.20.1 dns-server=192.168.10.10
add address=192.168.25.0/24 gateway=192.168.25.1 dns-server=192.168.10.10
add address=192.168.30.0/24 gateway=192.168.30.1 dns-server=192.168.10.10
add address=192.168.35.0/24 gateway=192.168.35.1 dns-server=192.168.10.10
add address=192.168.40.0/24 gateway=192.168.40.1 dns-server=192.168.10.10
add address=192.168.50.0/24 gateway=192.168.50.1 dns-server=192.168.10.10
```
---
## Phase 2: Static DHCP Leases (Pre-Migration)
Create static leases for all known devices BEFORE enabling VLANs.
### VLAN 10 - Management
```routeros
/ip dhcp-server lease
add address=192.168.10.20 mac-address=A8:B8:E0:02:B6:15 comment="XTRM-U Unraid" server=dhcp-mgmt
add address=192.168.10.10 mac-address=02:42:C0:A8:1F:04 comment="AdGuard Unraid" server=dhcp-mgmt
add address=192.168.10.2 mac-address=18:FD:74:54:3D:BC comment="CAP XL ac" server=dhcp-mgmt
add address=192.168.10.3 mac-address=F4:1E:57:C9:BD:09 comment="CSS326" server=dhcp-mgmt
add address=192.168.10.4 mac-address=1C:2A:A3:1E:78:67 comment="ZX1" server=dhcp-mgmt
add address=192.168.10.200 mac-address=48:DA:35:6F:BE:50 comment="NanoKVM" server=dhcp-mgmt
```
### VLAN 20 - Trusted
```routeros
/ip dhcp-server lease
add address=192.168.20.10 mac-address=82:6D:FB:D9:E0:47 comment="Nora MacBook" server=dhcp-trusted
add address=192.168.20.11 mac-address=AA:ED:8B:2A:40:F1 comment="Kaloyan S25" server=dhcp-trusted
add address=192.168.20.13 mac-address=82:EC:EF:B5:F2:AF comment="Kaloyan MacBook WiFi" server=dhcp-trusted
add address=192.168.20.16 mac-address=08:92:04:C6:07:C5 comment="Kaloyan MacBook LAN" server=dhcp-trusted
add address=192.168.20.17 mac-address=1C:83:41:32:F3:AF comment="Kaloyan Gaming PC" server=dhcp-trusted
```
### VLAN 25 - Kids
```routeros
/ip dhcp-server lease
add address=192.168.25.12 mac-address=F2:B8:14:61:C8:27 comment="Dancho iPhone" server=dhcp-kids
add address=192.168.25.14 mac-address=90:91:64:70:0D:86 comment="Kimi Notebook" server=dhcp-kids
add address=192.168.25.15 mac-address=2A:2B:BA:86:D4:AF comment="Kimi iPhone" server=dhcp-kids
add address=192.168.25.18 mac-address=A4:D1:D2:7B:52:BE comment="Compusbg iPad" server=dhcp-kids
```
### VLAN 30 - IoT
```routeros
/ip dhcp-server lease
add address=192.168.30.10 mac-address=50:2C:C6:7A:55:39 comment="GREE AC" server=dhcp-iot
add address=192.168.30.11 mac-address=B0:37:95:79:AF:9B comment="LG TV LAN" server=dhcp-iot
add address=192.168.30.12 mac-address=DC:03:98:6B:5A:3A comment="LG TV WiFi" server=dhcp-iot
add address=192.168.30.13 mac-address=D0:E7:82:F7:65:DD comment="Chromecast" server=dhcp-iot
add address=192.168.30.14 mac-address=B0:4A:39:3F:9A:14 comment="Roborock Vacuum" server=dhcp-iot
add address=192.168.30.20 mac-address=94:27:70:1E:0C:EE comment="Bosch Oven" server=dhcp-iot
add address=192.168.30.21 mac-address=C8:D7:78:40:65:40 comment="Bosch Dishwasher" server=dhcp-iot
add address=192.168.30.22 mac-address=C8:D7:78:D6:DC:FC comment="Bosch Washer" server=dhcp-iot
add address=192.168.30.31 mac-address=18:DE:50:5B:C8:A6 comment="Tuya Device 1" server=dhcp-iot
add address=192.168.30.32 mac-address=38:1F:8D:04:6F:E4 comment="Tuya Device 2" server=dhcp-iot
add address=192.168.30.38 mac-address=D4:AD:FC:BE:13:B0 comment="Intellirocks" server=dhcp-iot
add address=192.168.30.39 mac-address=C8:5C:CC:52:EA:53 comment="Xiaomi Air Purifier" server=dhcp-iot
```
### VLAN 35 - Cameras
```routeros
/ip dhcp-server lease
add address=192.168.35.10 mac-address=48:9E:9D:0E:16:F7 comment="Reolink Doorbell" server=dhcp-cameras
```
### VLAN 40 - Servers
```routeros
/ip dhcp-server lease
add address=192.168.40.19 mac-address=64:4E:D7:D8:43:3E comment="HP LaserJet" server=dhcp-servers
```
### VLAN 50 - Guest
```routeros
/ip dhcp-server lease
add address=192.168.50.10 mac-address=AC:87:A3:77:8F:BD comment="Unknown Apple" server=dhcp-guest
add address=192.168.50.11 mac-address=22:4C:7F:1D:85:8E comment="Unknown Random MAC" server=dhcp-guest
add address=192.168.50.12 mac-address=D0:C9:07:92:1A:8E comment="Unknown Private 1" server=dhcp-guest
add address=192.168.50.13 mac-address=D0:C9:07:8C:C9:46 comment="Unknown Private 2" server=dhcp-guest
```
---
## Phase 3: Switch Configuration
### 3.1 CSS326 VLAN Setup
**Port Assignments:**
| Port | Device | VLAN | Mode |
|------|--------|------|------|
| 1 | Uplink to HAP1 | Trunk | Tagged (all VLANs) |
| 2-8 | Room ports | TBD | Access |
| SFP1 | ZX1 Backbone | Trunk | Tagged (all VLANs) |
### 3.2 ZX1 VLAN Setup
**Port Assignments:**
| Port | Device | VLAN | Mode |
|------|--------|------|------|
| 1 | CSS326 Backbone | Trunk | Tagged (all VLANs) |
| 2 | Unraid | 10 | Access (Mgmt) |
| 3-8 | Other servers | TBD | Access |
---
## Phase 4: Unraid Migration (CRITICAL)
### The Challenge
- Unraid has IP 192.168.31.2 (will become 192.168.10.20)
- AdGuard container has IP 192.168.31.4 (will become 192.168.10.10)
- Many services reference these IPs
- DNS must remain functional throughout
### Migration Strategy
#### Option A: Dual-Stack Transition (Recommended)
1. Keep 192.168.31.0/24 network active during migration
2. Add VLAN 10 IP to Unraid as secondary
3. Update DNS/services to use new IP
4. Remove old IP after validation
#### Option B: Big Bang (Risky)
1. Pre-configure everything
2. Enable VLAN filtering on switch
3. Pray everything works
### Recommended Steps (Option A)
**Step 1: Add secondary IP to Unraid**
```bash
# On Unraid, temporarily add VLAN interface
ip link add link eth0 name eth0.10 type vlan id 10
ip addr add 192.168.10.20/24 dev eth0.10
ip link set eth0.10 up
```
**Step 2: Configure ZX1 port for Unraid as trunk (temporarily)**
- Allow both untagged (VLAN 1) and tagged (VLAN 10)
- Unraid can then communicate on both networks
**Step 3: Update AdGuard container**
```bash
# Update container to bind to new IP
docker network connect --ip 192.168.10.10 vlan10 adguardhome
```
**Step 4: Test connectivity**
- Ping 192.168.10.20 from router
- Ping 192.168.10.10 (AdGuard)
- Test DNS resolution via 192.168.10.10
**Step 5: Update DNS references**
- Update MikroTik DNS settings
- Update DHCP server DNS settings
- Update any hardcoded references
**Step 6: Switch Unraid to access mode**
- Change ZX1 port to access mode VLAN 10
- Unraid now only on VLAN 10
**Step 7: Remove old IP**
```bash
ip addr del 192.168.31.2/24 dev eth0
ip link del eth0.10
```
---
## Phase 5: Inter-VLAN Routing & Firewall
### Default Policy
- All VLANs can reach Internet
- Management (10) can reach all VLANs
- Trusted (20) can reach IoT (30), Cameras (35), Servers (40)
- Kids (25) limited access (parental controls via AdGuard)
- IoT (30) isolated - Internet only
- Cameras (35) isolated - only NVR access
- Guest (50) isolated - Internet only
### Firewall Rules (MikroTik)
```routeros
# Allow established/related
/ip firewall filter
add chain=forward connection-state=established,related action=accept
# Management can access everything
add chain=forward src-address=192.168.10.0/24 action=accept
# Trusted can access IoT, Cameras, Servers
add chain=forward src-address=192.168.20.0/24 dst-address=192.168.30.0/24 action=accept
add chain=forward src-address=192.168.20.0/24 dst-address=192.168.35.0/24 action=accept
add chain=forward src-address=192.168.20.0/24 dst-address=192.168.40.0/24 action=accept
# IoT to Internet only (drop inter-VLAN)
add chain=forward src-address=192.168.30.0/24 dst-address=192.168.0.0/16 action=drop
# Cameras to NVR only (future: add NVR IP)
add chain=forward src-address=192.168.35.0/24 dst-address=192.168.0.0/16 action=drop
# Guest to Internet only
add chain=forward src-address=192.168.50.0/24 dst-address=192.168.0.0/16 action=drop
# Drop everything else between VLANs
add chain=forward src-address=192.168.0.0/16 dst-address=192.168.0.0/16 action=drop
```
---
## Rollback Plan
If migration fails:
1. Disable VLAN filtering on CSS326/ZX1
2. All ports return to untagged VLAN 1
3. Network returns to flat 192.168.31.0/24
4. Restore original Unraid IP if changed
### Quick Rollback Commands
```routeros
# Disable VLAN filtering (emergency)
/interface bridge set bridge vlan-filtering=no
```
---
## Pre-Migration Checklist
- [ ] Backup MikroTik configuration
- [ ] Backup CSS326 configuration
- [ ] Backup ZX1 configuration
- [ ] Document current Unraid network config
- [ ] Test REST API access to router
- [ ] Verify all MAC addresses in device list
- [ ] Create all VLAN interfaces (disabled)
- [ ] Create all DHCP pools (disabled)
- [ ] Create all static leases
- [ ] Plan maintenance window (low usage time)
---
## Migration Order
1. **Night 1: Router Setup**
- Create VLANs, IPs, DHCP (all disabled)
- Create static leases
- Test with single device on VLAN 10
2. **Night 2: Switch Setup**
- Configure CSS326 VLANs (filtering off)
- Configure ZX1 VLANs (filtering off)
- Test trunk links
3. **Night 3: Unraid Migration**
- Add VLAN 10 interface to Unraid
- Migrate AdGuard to new IP
- Update DNS references
- Test extensively
4. **Night 4: Enable VLAN Filtering**
- Enable on CSS326
- Enable on ZX1
- Monitor for issues
5. **Day 5+: Device Migration**
- Migrate devices VLAN by VLAN
- Start with IoT (least critical)
- End with Trusted (most critical)
---
## Verification Tests
After each phase, verify:
- [ ] DNS resolution works (nslookup google.com)
- [ ] Internet access works (ping 8.8.8.8)
- [ ] Local services accessible (Unraid web UI)
- [ ] DHCP working (release/renew gets expected IP)
- [ ] Inter-VLAN routing as expected

View File

@@ -0,0 +1,275 @@
# 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 │
│ ┌──────────────────┐ │
│ │ Quad9 DoH │ ◄── dns.quad9.net/dns-query │
│ │ 9.9.9.9 │ ◄── Quad9 bootstrap │
│ │ 149.112.112.112 │ ◄── Quad9 secondary │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ 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. https://dns.quad9.net/dns-query (Quad9 DoH - malware blocking)
2. 9.9.9.9 (Quad9 bootstrap)
3. 149.112.112.112 (Quad9 bootstrap secondary)
### Bootstrap DNS
- 9.9.9.9
- 149.112.112.112
## 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
## Known Issues
### Container fails after restart with "could not load config json"
**Symptoms:**
- Container shows status `S` (stopped)
- Log shows: `could not load config json`
**Cause:** Container metadata/config.json corruption after MikroTik restart.
**Fix:**
```routeros
# 1. Remove broken container
/container remove [find name=adguardhome]
# 2. Recreate container (will re-download/extract image)
/container add remote-image=adguard/adguardhome:latest interface=veth-adguard root-dir=usb1/adguard/root logging=yes start-on-boot=yes dns=8.8.8.8 name=adguardhome
# 3. Wait for extraction to complete (check with /container print)
# 4. Add mountlists (note: parameter is "mountlists" not "mounts")
/container set 0 mountlists=agh-config,agh-work
# 5. Start container
/container start 0
# 6. Restore MikroTik DNS
/ip dns set servers=172.17.0.2
```
**Note:** The AdGuard configuration in `/opt/adguardhome/conf` is preserved because it is on a separate mount (usb1/adguard/conf).

View File

@@ -0,0 +1,146 @@
# MikroTik Tailscale Container
**Status:** Completed
**Implemented:** 2026-01-25
---
## Overview
Tailscale VPN running as a container on MikroTik for secure remote access to the home network.
## Architecture
```
┌─────────────────────────────────────────────────────────────────────┐
│ MikroTik hAP ax³ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ containers-br (172.17.0.1/24) │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ veth-adguard │ │ veth-tailscale │ │ │
│ │ │ 172.17.0.2 │ │ 172.17.0.3 │ │ │
│ │ └────────┬────────┘ └────────┬────────┘ │ │
│ └───────────┼─────────────────────────┼─────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ AdGuard Home │ │ Tailscale │ │
│ │ (DNS filtering) │ │ (VPN tunnel) │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │ │
└─────────────────────────────────────┼────────────────────────────────┘
Tailscale Network
(100.x.x.x)
```
## Container Configuration
| Setting | Value |
|---------|-------|
| Image | tailscale/tailscale:latest |
| Interface | veth-tailscale |
| Container IP | 172.17.0.3/24 |
| Gateway | 172.17.0.1 |
| Root dir | usb1/tailscale/root |
| Mount | ts-state → /var/lib/tailscale |
| Start on boot | yes |
## Environment Variables
| Variable | Value | Purpose |
|----------|-------|---------|
| TS_USERSPACE | true | Run in userspace mode (no kernel module) |
| TS_STATE_DIR | /var/lib/tailscale | State persistence directory |
| TS_SOCKET | /var/run/tailscale/tailscaled.sock | Socket location |
## Mounts
| Name | Source | Destination |
|------|--------|-------------|
| ts-state | usb1/tailscale/state | /var/lib/tailscale |
## Setup
### Prerequisites
1. Container bridge must exist (run `mikrotik-containers-bridge-setup.rsc` first)
2. USB storage mounted as usb1
### Initial Setup
1. Run `mikrotik-tailscale-setup.rsc` script
2. Wait for image extraction
3. Check logs for authentication URL:
```routeros
:log print where message~"login.tailscale"
```
4. Visit the URL to authenticate with your Tailscale account
### Manual Setup Commands
```routeros
# Create veth
/interface veth add name=veth-tailscale address=172.17.0.3/24 gateway=172.17.0.1
# Add to bridge
/interface bridge port add bridge=containers-br interface=veth-tailscale
# Create mount
/container/mounts/add list=ts-state src=usb1/tailscale/state dst=/var/lib/tailscale
# Create environment variables
/container/envs/add list=ts-env key=TS_USERSPACE value=true
/container/envs/add list=ts-env key=TS_STATE_DIR value=/var/lib/tailscale
/container/envs/add list=ts-env key=TS_SOCKET value=/var/run/tailscale/tailscaled.sock
# Create container
/container/add remote-image=tailscale/tailscale:latest interface=veth-tailscale root-dir=usb1/tailscale/root logging=yes start-on-boot=yes dns=8.8.8.8 name=tailscale
# After extraction completes
/container/set [find name=tailscale] mountlists=ts-state envlists=ts-env
# Start
/container/start [find name=tailscale]
```
## Troubleshooting
### Check container status
```routeros
/container print
```
### Check logs
```routeros
:log print where topics~"container" and message~"tailscale"
```
### Find authentication URL
```routeros
:log print where message~"login.tailscale"
```
### Container fails to reach internet
1. Verify bridge exists: `/interface bridge print`
2. Verify veth is in bridge: `/interface bridge port print`
3. Verify NAT rule exists: `/ip firewall nat print where comment~"Container"`
4. Check route: `/ip route print where dst-address~"172.17"`
### Re-authenticate
If authentication expires, restart the container and check logs for new auth URL:
```routeros
/container stop [find name=tailscale]
/container start [find name=tailscale]
:delay 10s
:log print where message~"login.tailscale"
```
## Scripts
- `scripts/mikrotik-containers-bridge-setup.rsc` - Bridge setup (run first)
- `scripts/mikrotik-tailscale-setup.rsc` - Tailscale container setup
## Related Documents
- [09-MIKROTIK-ADGUARD-DOT-DOH.md](09-MIKROTIK-ADGUARD-DOT-DOH.md) - AdGuard container setup

View File

@@ -0,0 +1,133 @@
# VLAN Network Segmentation
**Last Updated:** 2026-01-26
**Status:** Phase 1 Complete, Phase 2 Complete - VLAN Filtering ACTIVE
## Overview
Network segmentation using VLANs for security isolation between device types.
## VLAN Architecture
| VLAN ID | Name | Subnet | Gateway | Purpose | Devices |
|---------|------|--------|---------|---------|---------|
| 1 | Legacy | 192.168.31.0/24 | 192.168.31.1 | Default/Legacy network (transition) | - |
| 10 | Management | 192.168.10.0/24 | 192.168.10.1 | Network infrastructure | 6 |
| 20 | Trusted | 192.168.20.0/24 | 192.168.20.1 | Family devices (phones, laptops) | 9 |
| 25 | Kids | 192.168.25.0/24 | 192.168.25.1 | Kids devices (parental controls) | 6 |
| 30 | IoT | 192.168.30.0/24 | 192.168.30.1 | Smart home devices | 14 |
| 35 | Cameras | 192.168.35.0/24 | 192.168.35.1 | Security cameras (isolated) | 1 |
| 40 | Servers | 192.168.40.0/24 | 192.168.40.1 | Printers, services | 1 |
| 50 | Guest | 192.168.50.0/24 | 192.168.50.1 | Guest network (internet only) | 7 |
| **Total** | | | | | **44** |
## Current Status
### MikroTik hAP ax³ ✅ READY
- [x] VLAN interfaces created (10, 20, 25, 30, 35, 40, 50)
- [x] IP addresses assigned to all VLANs
- [x] DHCP servers for each VLAN
- [x] DHCP pools configured
- [x] Static DHCP leases (44 devices)
- [x] Bridge VLAN table entries
- [x] **DHCP DNS set to each VLAN gateway** (fixed 2026-01-26)
- [x] **VLAN interfaces added to LAN list** (fixed 2026-01-26)
- [x] **DNS redirect rules for all VLANs** (fixed 2026-01-26)
- [x] **NAT masquerade for VLAN→AdGuard** (fixed 2026-01-26)
- [x] Firewall rules for inter-VLAN isolation
- [x] VLAN filtering enabled (ACTIVE since 2026-01-26)
### CSS326 Switch ✅ CONFIGURED
- [x] VLAN mode enabled
- [x] VLANs created (1, 10, 20, 25, 30, 35, 40, 50)
- [x] Port 1 - Trunk to router (tagged all VLANs)
- [x] Port 2 - Access VLAN 10 (NanoKVM)
- [x] Port 17-18 - Access VLAN 25 (Kids rooms)
- [x] Port 19-21 - Access VLAN 20 (Main bedroom)
- [x] Port 22-24 - Access VLAN 30 (Living room)
- [x] SFP1 - Trunk to ZX1 (tagged all VLANs)
### Backup Created ✅
- MikroTik backup: `/mnt/user/appdata/backups/mikrotik/backup-before-vlan-filtering-20260125-213635.rsc`
## DHCP Configuration
| VLAN | Server | Pool | DNS Server | Lease |
|------|--------|------|------------|-------|
| 10 | dhcp-mgmt | 192.168.10.100-200 | 192.168.10.1 | 30m |
| 20 | dhcp-trusted | 192.168.20.100-220 | 192.168.20.1 | 30m |
| 25 | dhcp-kids | 192.168.25.100-200 | 192.168.25.1 | 30m |
| 30 | dhcp-iot | 192.168.30.100-220 | 192.168.30.1 | 30m |
| 35 | dhcp-cameras | 192.168.35.100-150 | 192.168.35.1 | 30m |
| 40 | dhcp-servers | 192.168.40.100-150 | 192.168.40.1 | 30m |
| 50 | dhcp-guest | 192.168.50.100-220 | 192.168.50.1 | 4h |
**DNS Flow:** Device → VLAN Gateway → NAT Redirect → AdGuard (172.17.0.2) → Internet
## Issues Fixed (2026-01-26)
### Problem: Internet broke when VLAN filtering enabled
**Root Causes:**
1. DHCP DNS pointed to 192.168.31.1 (legacy) - unreachable from VLANs
2. DNS redirect rules only covered 192.168.31.0/24
3. VLAN interfaces not in LAN firewall list
4. No NAT masquerade for VLAN→AdGuard traffic
**Fixes Applied:**
```routeros
# 1. DHCP DNS now points to each VLAN gateway
/ip dhcp-server network set [find address=192.168.20.0/24] dns-server=192.168.20.1
# ... repeated for all VLANs
# 2. DNS redirect for all VLANs
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp src-address-list=all-vlans dst-port=53
# 3. VLAN interfaces in LAN list
/interface list member add list=LAN interface=vlan20-trusted
# ... repeated for all VLANs
# 4. NAT masquerade for VLAN DNS
/ip firewall nat add chain=srcnat action=masquerade protocol=udp src-address-list=all-vlans dst-address=172.17.0.2 dst-port=53
```
## Activation Steps (When Ready)
### Step 1: Enable VLAN Filtering
```routeros
/interface bridge set bridge vlan-filtering=yes
```
### Step 2: Force DHCP Renewal on Devices
Devices need new IP from their VLAN DHCP:
- **Windows:** `ipconfig /release && ipconfig /renew`
- **Mac:** System Preferences → Network → Renew DHCP
- **Linux:** `sudo dhclient -r && sudo dhclient`
- **Phones/IoT:** Toggle WiFi off/on
### Rollback (If Needed)
```routeros
/interface bridge set bridge vlan-filtering=no
```
## CSS326 Port Assignment
| Port | Connection | VLAN | Mode |
|------|------------|------|------|
| 1 | HAP1 Router | All | Trunk |
| 2 | NanoKVM | 10 | Access |
| 3-16 | Unused | - | - |
| 17 | Boys Room B2 | 25 | Access |
| 18 | Boys Room B1 | 25 | Access |
| 19 | Main Bedroom M1 | 20 | Access |
| 20 | Main Bedroom M2 | 20 | Access |
| 21 | Main Bedroom M3 | 20 | Access |
| 22 | Living Room L1 | 30 | Access |
| 23 | Living Room L2 | 30 | Access |
| 24 | Living Room L3 | 30 | Access |
| SFP1 | ZX1 10G | All | Trunk |
| SFP2 | Unused | - | - |
## Related Documents
- [03-VLAN-DEVICE-ASSIGNMENT.md](03-VLAN-DEVICE-ASSIGNMENT.md) - Device inventory (44 devices)
- [04-VLAN-MIGRATION-PLAN.md](04-VLAN-MIGRATION-PLAN.md) - Original migration plan

View File

@@ -0,0 +1,409 @@
# VLAN Setup Progress
**Created:** 2026-01-28
**Status:** IN PROGRESS
**Last Updated:** 2026-01-28
---
## CRITICAL WARNING
**ALWAYS ASK FOR EXPLICIT CONFIRMATION BEFORE:**
1. Enabling VLAN filtering (`/interface bridge set bridge vlan-filtering=yes`)
2. Changing bridge port PVID values
3. Modifying bridge VLAN table
**Reason:** When VLAN filtering was enabled on 2026-01-28, the entire network lost connectivity:
- WiFi devices: No DHCP, no internet
- Wired devices on CSS326 (not VLAN 10): No DHCP, no internet
- Even with manual IP/DNS/gateway assignment: No internet
- Only VLAN 10 devices (Unraid on ether4/5) continued working
**Root Cause (suspected):** Bridge VLAN table or NAT/masquerade configuration issue for VLAN 1 traffic.
**Recovery:** User had to manually troubleshoot and fix the configuration.
---
## Current Network State
### Hardware Topology
```
Internet (62.73.120.142)
┌──────────────────────────────────────────────────────────────┐
│ HAP1 | MikroTik hAP ax³ │
│ IP: 192.168.88.1 │
│ RouterOS: 7.21.1 │
│ │
│ Ports: │
│ ├── ether1: WAN (DHCP from ISP) │
│ ├── ether2: CAP XL ac (via PP1) │
│ ├── ether3: CSS326 switch │
│ ├── ether4: Unraid eth1 ──┐ VLAN 10 (PVID=10) │
│ ├── ether5: Unraid eth2 ──┘ │
│ ├── wifi1: XTRM (5GHz) │
│ └── wifi2: XTRM2 (2.4GHz) │
│ │
│ Installed Packages: routeros, wifi-qcom, container, │
│ user-manager │
└──────────────────────────────────────────────────────────────┘
│ ether2
┌──────────────────────────────────────────────────────────────┐
│ CAP | MikroTik cAP XL ac │
│ IP: 192.168.88.250 │
│ RouterOS: 7.21.1 │
│ CAPsMAN managed by HAP1 │
│ │
│ WiFi (provisioned via CAPsMAN): │
│ ├── cap-wifi1: XTRM2 (2.4GHz) │
│ └── cap-wifi2: XTRM (5GHz) │
└──────────────────────────────────────────────────────────────┘
│ ether3
┌──────────────────────────────────────────────────────────────┐
│ CSS326-24G-2S+ │
│ IP: 192.168.88.254 │
│ SwOS │
│ (VLAN config pending) │
└──────────────────────────────────────────────────────────────┘
```
### SSH Access
| Device | IP | Port | User | Auth |
|--------|-----|------|------|------|
| HAP1 | 192.168.88.1 | 22 | xtrm | SSH key (~/.ssh/mikrotik_key) |
| CAP | 192.168.88.250 | 2222 | xtrm | SSH key (~/.ssh/mikrotik_key) |
| Unraid | 192.168.10.20 (pending) | 422 | root | SSH key (~/.ssh/id_ed25519_unraid) |
### WiFi Configuration
| SSID | Band | Password | Security |
|------|------|----------|----------|
| XTRM | 5GHz | M0stW4nt3d@home | WPA2/WPA3 |
| XTRM2 | 2.4GHz | M0stW4nt3d@IoT | WPA2 |
---
## VLAN Architecture (Planned)
| VLAN ID | Name | Subnet | Gateway | Purpose | Assignment Method |
|---------|------|--------|---------|---------|-------------------|
| 1 | Default | 192.168.88.0/24 | 192.168.88.1 | Current LAN (transition) | Default |
| 10 | Management | 192.168.10.0/24 | 192.168.10.1 | Infrastructure devices | Port-based |
| 20 | Trusted | 192.168.20.0/24 | 192.168.20.1 | Family devices | RADIUS MAC auth |
| 25 | Kids | 192.168.25.0/24 | 192.168.25.1 | Kids devices | RADIUS MAC auth |
| 30 | IoT | 192.168.30.0/24 | 192.168.30.1 | Smart home devices | RADIUS MAC auth |
| 35 | Cameras | 192.168.35.0/24 | 192.168.35.1 | Security cameras | Port-based |
| 40 | Servers | 192.168.40.0/24 | 192.168.40.1 | Services | Port-based |
| 50 | Guest | 192.168.50.0/24 | 192.168.50.1 | Unknown/Guest devices | RADIUS default |
### Assignment Strategy
- **Port-based:** Wired devices with dedicated ports (Unraid, cameras)
- **RADIUS MAC auth:** WiFi devices - MikroTik User Manager assigns VLAN based on MAC
- **Default VLAN 50:** Unknown devices get internet-only access
---
## Current Configuration Status
### VLAN 10 - Management (IN PROGRESS)
**Status:** Configured, waiting for Unraid to renew DHCP
**What's Done:**
- [x] VLAN interface created: `vlan10-mgmt`
- [x] IP assigned: `192.168.10.1/24`
- [x] DHCP pool: `192.168.10.100-192.168.10.200`
- [x] DHCP server: `dhcp-mgmt` (DNS: 8.8.8.8)
- [x] Static leases created for VLAN 10 devices
- [x] Bridge VLAN table configured
- [x] ether4/ether5 PVID set to 10
- [x] VLAN filtering enabled on bridge
**What's Pending:**
- [ ] Unraid needs to renew DHCP to get 192.168.10.20
- [ ] Verify Unraid connectivity on new IP
- [ ] Update Unraid SSH connection string in CLAUDE.md
**Bridge VLAN Table:**
```
VLAN 1: tagged=bridge, untagged=ether2,ether3,wifi1,wifi2
VLAN 10: tagged=bridge, untagged=ether4,ether5
```
**Bridge Ports:**
```
ether2: PVID=1 (CAP)
ether3: PVID=1 (CSS326)
ether4: PVID=10 (Unraid)
ether5: PVID=10 (Unraid)
wifi1: PVID=1 (XTRM 5GHz)
wifi2: PVID=1 (XTRM2 2.4GHz)
```
### VLAN 10 Static Leases
| IP | MAC | Device | Status |
|----|-----|--------|--------|
| 192.168.10.2 | 18:FD:74:54:3D:BC | CAP XL ac | Waiting |
| 192.168.10.3 | F4:1E:57:C9:BD:09 | CSS326 | Waiting |
| 192.168.10.10 | 02:42:C0:A8:1F:04 | AdGuard (Unraid) | Waiting |
| 192.168.10.200 | 48:DA:35:6F:BE:50 | NanoKVM | Waiting |
| 192.168.10.20 | A8:B8:E0:02:B6:15 | XTRM-U Unraid | Waiting |
### User Manager (Installed, Not Configured)
**Status:** Package installed, not enabled
**Purpose:** RADIUS server for MAC-based VLAN assignment on WiFi
**Next Steps:**
1. Enable User Manager
2. Add router as RADIUS client (NAS)
3. Create user entries with MAC addresses and VLAN attributes
4. Configure WiFi for RADIUS MAC authentication
5. Set default VLAN 50 for unknown MACs
---
## Device Inventory by VLAN
### VLAN 10 - Management (5 devices)
| Target IP | MAC | Device | Connection |
|-----------|-----|--------|------------|
| 192.168.10.2 | 18:FD:74:54:3D:BC | CAP XL ac | ether2 via PP1 |
| 192.168.10.3 | F4:1E:57:C9:BD:09 | CSS326 | ether3 |
| 192.168.10.10 | 02:42:C0:A8:1F:04 | AdGuard (Unraid) | Container |
| 192.168.10.200 | 48:DA:35:6F:BE:50 | NanoKVM | CSS326 port |
| 192.168.10.20 | A8:B8:E0:02:B6:15 | XTRM-U Unraid | ether4/5 |
### VLAN 20 - Trusted (5 devices)
| Target IP | MAC | Device | Owner |
|-----------|-----|--------|-------|
| 192.168.20.10 | 82:6D:FB:D9:E0:47 | MacBook Air | Nora |
| 192.168.20.11 | AA:ED:8B:2A:40:F1 | Samsung S25 Ultra | Kaloyan |
| 192.168.20.13 | 82:EC:EF:B5:F2:AF | MacBook Pro (WiFi) | Kaloyan |
| 192.168.20.16 | 08:92:04:C6:07:C5 | MacBook Pro (LAN) | Kaloyan |
| 192.168.20.17 | 1C:83:41:32:F3:AF | Gaming PC | Kaloyan |
### VLAN 25 - Kids (4 devices)
| Target IP | MAC | Device | Owner |
|-----------|-----|--------|-------|
| 192.168.25.12 | F2:B8:14:61:C8:27 | iPhone | Dancho |
| 192.168.25.14 | 90:91:64:70:0D:86 | Notebook | Kimi |
| 192.168.25.15 | 2A:2B:BA:86:D4:AF | iPhone | Kimi |
| 192.168.25.18 | A4:D1:D2:7B:52:BE | iPad | Compusbg |
### VLAN 30 - IoT (12 devices)
| Target IP | MAC | Device |
|-----------|-----|--------|
| 192.168.30.10 | 50:2C:C6:7A:55:39 | GREE AC |
| 192.168.30.11 | B0:37:95:79:AF:9B | LG TV (LAN) |
| 192.168.30.12 | DC:03:98:6B:5A:3A | LG TV (WiFi) |
| 192.168.30.13 | D0:E7:82:F7:65:DD | Chromecast |
| 192.168.30.14 | B0:4A:39:3F:9A:14 | Roborock Vacuum |
| 192.168.30.20 | 94:27:70:1E:0C:EE | Bosch Oven |
| 192.168.30.21 | C8:D7:78:40:65:40 | Bosch Dishwasher |
| 192.168.30.22 | C8:D7:78:D6:DC:FC | Bosch Washer |
| 192.168.30.31 | 18:DE:50:5B:C8:A6 | Tuya Device 1 |
| 192.168.30.32 | 38:1F:8D:04:6F:E4 | Tuya Device 2 |
| 192.168.30.38 | D4:AD:FC:BE:13:B0 | Intellirocks |
| 192.168.30.39 | C8:5C:CC:52:EA:53 | Xiaomi Air Purifier |
### VLAN 35 - Cameras (1 device)
| Target IP | MAC | Device |
|-----------|-----|--------|
| 192.168.35.10 | 48:9E:9D:0E:16:F7 | Reolink Doorbell |
### VLAN 40 - Servers (1 device)
| Target IP | MAC | Device |
|-----------|-----|--------|
| 192.168.40.19 | 64:4E:D7:D8:43:3E | HP LaserJet |
### VLAN 50 - Guest/Unknown (4 devices)
| Target IP | MAC | Notes |
|-----------|-----|-------|
| 192.168.50.10 | AC:87:A3:77:8F:BD | Unknown Apple device |
| 192.168.50.11 | 22:4C:7F:1D:85:8E | Random MAC (privacy) |
| 192.168.50.12 | D0:C9:07:92:1A:8E | Unknown |
| 192.168.50.13 | D0:C9:07:8C:C9:46 | Unknown |
---
## Useful Commands
### Check VLAN Status
```routeros
/interface vlan print
/interface bridge vlan print detail
/interface bridge port print
/interface bridge print where name=bridge
```
### Check DHCP Leases
```routeros
/ip dhcp-server lease print
/ip dhcp-server lease print where server=dhcp-mgmt
```
### Check User Manager
```routeros
/user-manager print
/user-manager user print
/user-manager router print
```
### Rollback VLAN Filtering
```routeros
/interface bridge set bridge vlan-filtering=no
```
### Force DHCP Renewal on Unraid
```bash
# On Unraid terminal
/etc/rc.d/rc.inet1 restart
# Or
dhclient -r eth0 && dhclient eth0
```
---
## Next Steps (In Order)
1. **Complete VLAN 10 Setup**
- Restart network on Unraid to get new IP (192.168.10.20)
- Verify connectivity
- Update CLAUDE.md with new Unraid IP
2. **Configure User Manager for RADIUS**
- Enable User Manager
- Add router as NAS (RADIUS client)
- Configure WiFi for MAC authentication
3. **Create Other VLANs**
- VLAN 20 (Trusted) - interface, DHCP, firewall
- VLAN 25 (Kids) - interface, DHCP, firewall
- VLAN 30 (IoT) - interface, DHCP, firewall
- VLAN 35 (Cameras) - interface, DHCP, firewall
- VLAN 40 (Servers) - interface, DHCP, firewall
- VLAN 50 (Guest) - interface, DHCP, firewall (default for unknown)
4. **Add MAC-VLAN Mappings to User Manager**
- Add all trusted device MACs → VLAN 20
- Add all kids device MACs → VLAN 25
- Add all IoT device MACs → VLAN 30
- Default (no match) → VLAN 50
5. **Configure Inter-VLAN Firewall Rules**
- Management → All (full access)
- Trusted → IoT, Cameras, Servers (control)
- Kids → Limited (parental controls)
- IoT → Internet only
- Cameras → Isolated
- Guest → Internet only
6. **Test and Verify**
- Test each VLAN connectivity
- Test inter-VLAN access rules
- Test unknown device goes to VLAN 50
---
## Firewall Rules (Planned)
```routeros
# Allow established/related
/ip firewall filter add chain=forward connection-state=established,related action=accept
# Management can access everything
/ip firewall filter add chain=forward src-address=192.168.10.0/24 action=accept
# Trusted can access IoT, Cameras, Servers
/ip firewall filter add chain=forward src-address=192.168.20.0/24 dst-address=192.168.30.0/24 action=accept
/ip firewall filter add chain=forward src-address=192.168.20.0/24 dst-address=192.168.35.0/24 action=accept
/ip firewall filter add chain=forward src-address=192.168.20.0/24 dst-address=192.168.40.0/24 action=accept
# IoT - Internet only (block inter-VLAN)
/ip firewall filter add chain=forward src-address=192.168.30.0/24 dst-address=192.168.0.0/16 action=drop
# Cameras - Isolated
/ip firewall filter add chain=forward src-address=192.168.35.0/24 dst-address=192.168.0.0/16 action=drop
# Guest - Internet only
/ip firewall filter add chain=forward src-address=192.168.50.0/24 dst-address=192.168.0.0/16 action=drop
# Drop all other inter-VLAN
/ip firewall filter add chain=forward src-address=192.168.0.0/16 dst-address=192.168.0.0/16 action=drop
```
---
## Incident Log
### 2026-01-28: Network Outage After VLAN Filtering Enabled
**Timeline:**
1. VLAN 10 interface, DHCP, static leases configured
2. Bridge VLAN table configured (VLAN 1 and VLAN 10)
3. ether4/ether5 PVID set to 10
4. VLAN filtering enabled
5. **Result:** All non-VLAN 10 devices lost connectivity
**Symptoms:**
- WiFi devices: No DHCP assignment
- CSS326 connected devices: No DHCP assignment
- Manual IP configuration: Still no internet
- VLAN 10 devices (Unraid): Working correctly
**Suspected Cause:**
- Bridge VLAN table may not have been properly configured for VLAN 1
- NAT masquerade may not have been applied to VLAN 1 traffic
- Possible missing egress tagging configuration
**Resolution:** Manual fix by user (details TBD)
**Lessons Learned:**
1. **ALWAYS** test VLAN config on a single device first before enabling filtering
2. **ALWAYS** ask for explicit user confirmation before enabling VLAN filtering
3. Have rollback command ready: `/interface bridge set bridge vlan-filtering=no`
4. Keep WinBox/MAC-based access available for recovery
5. Document exact state before making changes
---
## Pre-Change Checklist (MANDATORY)
Before enabling VLAN filtering, verify:
- [ ] Bridge VLAN table has VLAN 1 with all non-VLAN ports as untagged
- [ ] Bridge itself is tagged in all VLANs
- [ ] NAT masquerade rule covers all internal networks
- [ ] DHCP servers exist for all active VLANs
- [ ] Static routes/addresses configured if needed
- [ ] WinBox or MAC-based access available for recovery
- [ ] User has confirmed they are ready for potential outage
- [ ] Rollback command documented: `/interface bridge set bridge vlan-filtering=no`
---
## Reference Documents
- `docs/03-VLAN-DEVICE-ASSIGNMENT.md` - Full device inventory
- `docs/04-VLAN-MIGRATION-PLAN.md` - Original migration plan
- `docs/11-VLAN-IMPLEMENTATION.md` - VLAN architecture overview
- `docs/wip/VLAN-PROPOSAL.md` - Initial proposal

View File

@@ -0,0 +1,594 @@
# VLAN Setup Plan v2 - Critical Approach
**Created:** 2026-01-28
**Status:** PLANNING
**Approach:** Step-by-step with verification before each change
---
## CRITICAL RULES
1. **NO CHANGES WITHOUT EXPLICIT USER APPROVAL**
2. **VERIFY current state before each step**
3. **TEST after each step before proceeding**
4. **HAVE ROLLBACK ready for each step**
5. **STOP and assess if anything unexpected happens**
---
## Prerequisites
- Router: MikroTik hAP ax³ (freshly reset to factory defaults)
- Current IP: 192.168.88.1 (factory default)
- Access: WinBox or physical console available for recovery
---
## Phase 1: Basic Router Setup
### Step 1.1: Create User `xtrm`
**Action:**
```routeros
/user add name=xtrm password=M0stW4nt3d@xtrm group=full
```
**Verification:**
```routeros
/user print
```
**Expected Result:**
- User `xtrm` exists with group `full`
**Rollback:**
```routeros
/user remove xtrm
```
---
### Step 1.2: Change SSH Port to 2222
**Action:**
```routeros
/ip service set ssh port=2222
```
**Verification:**
```routeros
/ip service print where name=ssh
```
**Expected Result:**
- SSH service on port 2222
**Rollback:**
```routeros
/ip service set ssh port=22
```
**Test:** SSH to router on port 2222
---
### Step 1.3: Import SSH Key for User `xtrm`
**Prerequisite:** Upload `mikrotik_key.pub` to router via WinBox Files
**Action:**
```routeros
/user ssh-keys import public-key-file=mikrotik_key.pub user=xtrm
```
**Verification:**
```routeros
/user ssh-keys print
```
**Expected Result:**
- SSH key associated with user `xtrm`
**Test:** SSH with key authentication (no password)
---
## Phase 2: WiFi & CAPsMAN Setup
### Step 2.1: Create Security Profiles
**Action:**
```routeros
# For XTRM (5GHz) - High security
/interface wifi security add name=sec-xtrm authentication-types=wpa2-psk,wpa3-psk passphrase=M0stW4nt3d@home
# For XTRM2 (2.4GHz) - IoT compatibility
/interface wifi security add name=sec-xtrm2 authentication-types=wpa-psk,wpa2-psk passphrase=M0stW4nt3d@IoT
```
**Verification:**
```routeros
/interface wifi security print
```
**Expected Result:**
- `sec-xtrm`: WPA2-PSK + WPA3-PSK
- `sec-xtrm2`: WPA-PSK + WPA2-PSK (for old devices)
---
### Step 2.2: Create Configuration Profiles
**Action:**
```routeros
/interface wifi configuration add name=cfg-xtrm ssid=XTRM security=sec-xtrm country=Bulgaria
/interface wifi configuration add name=cfg-xtrm2 ssid=XTRM2 security=sec-xtrm2 country=Bulgaria
```
**Verification:**
```routeros
/interface wifi configuration print
```
---
### Step 2.3: Apply WiFi to Local Radios
**Action:**
```routeros
# wifi1 = 5GHz radio → XTRM
/interface wifi set wifi1 configuration=cfg-xtrm configuration.ssid=XTRM disabled=no
# wifi2 = 2.4GHz radio → XTRM2
/interface wifi set wifi2 configuration=cfg-xtrm2 configuration.ssid=XTRM2 disabled=no
```
**Verification:**
```routeros
/interface wifi print
```
**Test:** Connect a device to each SSID, verify internet works
---
### Step 2.4: Enable CAPsMAN
**Action:**
```routeros
/interface wifi capsman set enabled=yes interfaces=bridge
```
**Verification:**
```routeros
/interface wifi capsman print
```
---
### Step 2.5: Create CAPsMAN Provisioning Rules
**Action:**
```routeros
# For 5GHz radios → XTRM
/interface wifi provisioning add action=create-dynamic-enabled master-configuration=cfg-xtrm supported-bands=5ghz-a,5ghz-n,5ghz-ac
# For 2.4GHz radios → XTRM2
/interface wifi provisioning add action=create-dynamic-enabled master-configuration=cfg-xtrm2 supported-bands=2ghz-g,2ghz-n
```
**Verification:**
```routeros
/interface wifi provisioning print
```
---
### Step 2.6: Configure CAP to Join CAPsMAN
**On CAP device (192.168.88.250 or via WinBox):**
```routeros
/interface wifi cap set enabled=yes discovery-interfaces=bridge caps-man-addresses=""
```
**Verification on HAP:**
```routeros
/interface wifi capsman remote-cap print
/interface wifi radio print
```
**Expected Result:**
- CAP appears as connected
- CAP radios show up (cap-wifi1, cap-wifi2)
**Test:** Connect device to XTRM/XTRM2 via CAP, verify internet
---
## Phase 3: Install Additional Packages
### Step 3.1: Install User Manager and Container Packages
**Action:**
1. Download packages from MikroTik website (arm64, version 7.21.1)
2. Upload to router via WinBox:
- `user-manager-7.21.1-arm64.npk`
- `container-7.21.1-arm64.npk` (if not already installed)
3. Reboot router
**Verification after reboot:**
```routeros
/system package print
```
**Expected Result:**
- `user-manager` package listed
- `container` package listed
---
## Phase 4: Network Reconfiguration (CRITICAL)
### Step 4.0: Pre-Change Verification
**Before ANY changes, verify current state:**
```routeros
echo "=== CURRENT STATE ==="
/ip address print
/ip pool print
/ip dhcp-server print
/ip dhcp-server network print
/interface bridge print
/interface bridge port print
/interface bridge vlan print
/ip firewall nat print
```
**Document the output before proceeding!**
---
### Step 4.1: Change Network to 192.168.31.0/24
**Current:** 192.168.88.0/24 (factory default)
**Target:** 192.168.31.0/24
**Action (all in one command block to minimize disruption):**
```routeros
/ip address set [find where address~"192.168.88"] address=192.168.31.1/24
/ip pool set [find where name="default-dhcp"] ranges=192.168.31.100-192.168.31.254
/ip dhcp-server network set [find where address="192.168.88.0/24"] address=192.168.31.0/24 gateway=192.168.31.1 dns-server=8.8.8.8
```
**After change:** Reconnect to WiFi to get new IP
**Verification:**
```routeros
/ip address print
/ip pool print
/ip dhcp-server network print
/ping 8.8.8.8 count=2
```
**Test:** Browse internet from connected device
---
### Step 4.2: Create VLAN40 Interface (Catch-All)
**IMPORTANT:** Do NOT move IP to VLAN interface yet!
**Action:**
```routeros
/interface vlan add interface=bridge name=vlan40-catchall vlan-id=40
```
**Verification:**
```routeros
/interface vlan print
```
**Expected Result:**
- `vlan40-catchall` interface exists
- Network still works (IP still on bridge)
---
### Step 4.3: Add VLAN40 to Bridge VLAN Table
**Action:**
```routeros
/interface bridge vlan add bridge=bridge vlan-ids=40 tagged=bridge untagged=ether2,ether3,wifi1,wifi2
```
**Verification:**
```routeros
/interface bridge vlan print detail
```
---
### Step 4.4: Create VLAN40 DHCP Infrastructure
**Action:**
```routeros
# Create pool for VLAN40
/ip pool add name=pool-vlan40 ranges=192.168.31.100-192.168.31.254
# Add IP to VLAN40 interface (SECOND IP - keep bridge IP!)
/ip address add address=192.168.31.1/24 interface=vlan40-catchall
# This will show warning about duplicate - that's expected for now
```
**Verification:**
```routeros
/ip address print
```
**Expected:** TWO entries for 192.168.31.1 (bridge AND vlan40)
---
### Step 4.5: STOP AND VERIFY
**Before enabling VLAN filtering:**
1. Can you ping 192.168.31.1?
2. Can you access router via SSH?
3. Can you access router via WinBox?
4. Is internet working?
**If ANY answer is NO - STOP and troubleshoot!**
---
### Step 4.6: Enable VLAN Filtering (REQUIRES EXPLICIT USER APPROVAL)
⚠️ **THIS STEP REQUIRES USER TO TYPE "APPROVED" BEFORE EXECUTION** ⚠️
**Pre-flight checks:**
```routeros
/interface bridge vlan print detail
/interface bridge port print
```
**Ensure:**
- VLAN 40 has all current ports as untagged
- Bridge is tagged in VLAN 40
**Action:**
```routeros
/interface bridge set bridge vlan-filtering=yes
```
**Immediate verification:**
```routeros
/ping 8.8.8.8 count=2
```
**If ping fails - IMMEDIATELY rollback:**
```routeros
/interface bridge set bridge vlan-filtering=no
```
---
### Step 4.7: Post-Activation Cleanup
**Only after confirming VLAN filtering works:**
1. Move DHCP server to VLAN40 interface:
```routeros
/ip dhcp-server set defconf interface=vlan40-catchall
```
2. Remove duplicate IP from bridge:
```routeros
/ip address remove [find where interface=bridge and address~"192.168.31"]
```
**Verification:**
```routeros
/ip address print
/ip dhcp-server print
```
---
## Phase 5: Create VLAN10 (Management - Port Based)
### Step 5.1: Create VLAN10 Interface
**Action:**
```routeros
/interface vlan add interface=bridge name=vlan10-mgmt vlan-id=10
/ip address add address=192.168.10.1/24 interface=vlan10-mgmt
```
---
### Step 5.2: Create VLAN10 DHCP
**Action:**
```routeros
/ip pool add name=pool-mgmt ranges=192.168.10.100-192.168.10.200
/ip dhcp-server add address-pool=pool-mgmt interface=vlan10-mgmt name=dhcp-mgmt
/ip dhcp-server network add address=192.168.10.0/24 gateway=192.168.10.1 dns-server=8.8.8.8
```
---
### Step 5.3: Create VLAN10 Static Leases
**Action:**
```routeros
/ip dhcp-server lease
add address=192.168.10.2 mac-address=18:FD:74:54:3D:BC comment="CAP XL ac" server=dhcp-mgmt
add address=192.168.10.3 mac-address=F4:1E:57:C9:BD:09 comment="CSS326" server=dhcp-mgmt
add address=192.168.10.10 mac-address=02:42:C0:A8:1F:04 comment="AdGuard Unraid" server=dhcp-mgmt
add address=192.168.10.11 mac-address=48:DA:35:6F:BE:50 comment="NanoKVM" server=dhcp-mgmt
add address=192.168.10.20 mac-address=A8:B8:E0:02:B6:15 comment="XTRM-U Unraid" server=dhcp-mgmt
```
---
### Step 5.4: Configure Bridge for VLAN10
**Action:**
```routeros
# Add VLAN10 to bridge table - ether4/ether5 as untagged (Unraid ports)
/interface bridge vlan add bridge=bridge vlan-ids=10 tagged=bridge untagged=ether4,ether5
# Set PVID on Unraid ports
/interface bridge port set [find interface=ether4] pvid=10
/interface bridge port set [find interface=ether5] pvid=10
```
---
### Step 5.5: STOP AND TEST VLAN10
⚠️ **REQUIRES USER APPROVAL TO PROCEED** ⚠️
**Test:**
1. Unraid should get IP 192.168.10.20
2. Unraid should have internet access
3. Other devices still work on VLAN40
---
## Phase 6: Create Remaining VLANs
### VLAN Overview
| VLAN | Name | Subnet | Purpose | Assignment |
|------|------|--------|---------|------------|
| 10 | Management | 192.168.10.0/24 | Infrastructure | Port-based |
| 20 | Trusted | 192.168.20.0/24 | Family devices | RADIUS |
| 25 | Kids | 192.168.25.0/24 | Kids devices | RADIUS |
| 30 | IoT | 192.168.30.0/24 | Smart home | RADIUS |
| 35 | Cameras | 192.168.35.0/24 | Security | Port-based |
| 40 | Catch-All | 192.168.31.0/24 | Default/Unknown | Default |
### Step 6.1-6.4: Create Each VLAN
**Repeat for each VLAN (20, 25, 30, 35):**
```routeros
# Create interface
/interface vlan add interface=bridge name=vlanXX-name vlan-id=XX
# Add IP
/ip address add address=192.168.XX.1/24 interface=vlanXX-name
# Create pool
/ip pool add name=pool-vlanXX ranges=192.168.XX.100-192.168.XX.200
# Create DHCP server
/ip dhcp-server add address-pool=pool-vlanXX interface=vlanXX-name name=dhcp-vlanXX
# Create DHCP network
/ip dhcp-server network add address=192.168.XX.0/24 gateway=192.168.XX.1 dns-server=8.8.8.8
# Add to bridge VLAN table (tagged only - RADIUS will assign)
/interface bridge vlan add bridge=bridge vlan-ids=XX tagged=bridge
```
---
## Phase 7: Configure User Manager (RADIUS)
### Step 7.1: Enable User Manager
```routeros
/user-manager set enabled=yes
```
### Step 7.2: Add Router as RADIUS Client
```routeros
/user-manager router add name=local address=127.0.0.1 shared-secret=radius-secret
```
### Step 7.3: Add MAC-VLAN Mappings
**For each device, add user with MAC and VLAN attribute:**
```routeros
# Example for trusted device
/user-manager user add name=AA:ED:8B:2A:40:F1 password="" shared-users=1
/user-manager user set [find name=AA:ED:8B:2A:40:F1] attributes="Tunnel-Type:VLAN,Tunnel-Medium-Type:IEEE-802,Tunnel-Private-Group-Id:20"
```
### Step 7.4: Configure WiFi for RADIUS
```routeros
/interface wifi security set sec-xtrm radius=yes
/interface wifi security set sec-xtrm2 radius=yes
```
---
## Phase 8: Activation Plan
### Step 8.1: Final Pre-Activation Checklist
- [ ] All VLAN interfaces created
- [ ] All DHCP servers configured
- [ ] All static leases added
- [ ] User Manager configured with all MACs
- [ ] WiFi configured for RADIUS
- [ ] WinBox access verified
- [ ] Rollback command ready
### Step 8.2: Staged Activation
1. **Test VLAN10 only** (port-based, Unraid)
2. **Verify 24 hours**
3. **Test VLAN20** (one trusted device via RADIUS)
4. **Verify 24 hours**
5. **Enable remaining VLANs**
---
## Rollback Commands
**Disable VLAN filtering (emergency):**
```routeros
/interface bridge set bridge vlan-filtering=no
```
**Reset to factory:**
```routeros
/system reset-configuration no-defaults=no
```
---
## Device Inventory Reference
See: `docs/03-VLAN-DEVICE-ASSIGNMENT.md`
---
## Verification Commands
```routeros
# Check VLAN status
/interface vlan print
/interface bridge vlan print detail
/interface bridge port print
# Check DHCP
/ip dhcp-server print
/ip dhcp-server lease print
# Check connectivity
/ping 8.8.8.8 count=3
/ping 192.168.31.1 count=3
# Check User Manager
/user-manager user print
/user-manager router print
```

View File

@@ -0,0 +1,352 @@
# VLAN Setup Plan v3 - Safe Mode Approach
**Created:** 2026-01-31
**Status:** PLANNING
**Approach:** Safe Mode with atomic commands for auto-rollback protection
---
## Lessons Learned from Previous Failures
1. **IP on bridge stops working** when VLAN filtering is enabled
2. **Duplicate same IP** on bridge + VLAN interface causes routing confusion
3. **VLAN interface doesn't receive traffic** until VLAN filtering is enabled
4. **Solution**: Use Safe Mode + atomic script execution
---
## Prerequisites
- Router: MikroTik hAP ax³
- Current IP: 192.168.1.1/24 on bridge
- Access: WinBox connected via **MAC address** (not IP!)
- CAPsMAN: Already configured and working
---
## Phase 1: Preparation (No Risk)
### Step 1.1: Backup Current Configuration
```routeros
/system backup save name=before-vlan-v3
/export file=before-vlan-v3
```
Download both files from WinBox → Files.
### Step 1.2: Verify Current State
```routeros
/ip address print
/interface bridge print
/interface bridge port print
/interface bridge vlan print
/ip dhcp-server print
```
**Expected:**
- IP 192.168.1.1/24 on bridge
- VLAN filtering = no
- No bridge VLANs configured
---
## Phase 2: Create VLAN Infrastructure (Safe - No Filtering Yet)
### Step 2.1: Create VLAN 40 Interface
```routeros
/interface vlan add interface=bridge name=vlan40-catchall vlan-id=40
```
**Verify:**
```routeros
/interface vlan print
```
### Step 2.2: Add VLAN 40 to Bridge Table
All LAN ports untagged, bridge tagged (for CPU access):
```routeros
/interface bridge vlan add bridge=bridge vlan-ids=40 tagged=bridge untagged=ether2,ether3,ether4,ether5,wifi1,wifi2
```
**Verify:**
```routeros
/interface bridge vlan print detail
```
### Step 2.3: Set PVID on All LAN Ports
```routeros
/interface bridge port set [find interface=ether2] pvid=40
/interface bridge port set [find interface=ether3] pvid=40
/interface bridge port set [find interface=ether4] pvid=40
/interface bridge port set [find interface=ether5] pvid=40
/interface bridge port set [find interface=wifi1] pvid=40
/interface bridge port set [find interface=wifi2] pvid=40
```
**Verify:**
```routeros
/interface bridge port print
```
**Expected:** All ports show PVID=40
### Step 2.4: Add IP to VLAN Interface
This creates a "duplicate" IP temporarily:
```routeros
/ip address add address=192.168.1.1/24 interface=vlan40-catchall comment="VLAN40-Management"
```
**Verify:**
```routeros
/ip address print
```
**Expected:** Two entries for 192.168.1.1 (bridge and vlan40-catchall)
### Step 2.5: Create VLAN40 DHCP Pool (if not exists)
```routeros
/ip pool add name=pool-vlan40 ranges=192.168.1.10-192.168.1.250
```
### Step 2.6: Verify Everything Before Critical Step
```routeros
:put "=== VLAN Interface ==="
/interface vlan print
:put "=== Bridge VLANs ==="
/interface bridge vlan print detail
:put "=== Bridge Ports (check PVID) ==="
/interface bridge port print
:put "=== IP Addresses ==="
/ip address print
:put "=== Ping Test ==="
/ping 8.8.8.8 count=2
```
**STOP HERE if anything is wrong!**
---
## Phase 3: Enable VLAN Filtering (Critical - Use Safe Mode)
### Step 3.1: Enter Safe Mode in WinBox
1. In WinBox, press **Ctrl+X**
2. You'll see "Safe Mode" indicator in title bar
3. All changes will auto-rollback if connection is lost
### Step 3.2: Create the Activation Script
Create a script that does everything atomically:
```routeros
/system script add name=activate-vlan source={
# Enable VLAN filtering
/interface bridge set bridge vlan-filtering=yes
# Move DHCP server to VLAN interface
/ip dhcp-server set [find name~"defconf"] interface=vlan40-catchall
# Wait 2 seconds for changes to apply
:delay 2s
# Remove duplicate IP from bridge (keep only VLAN interface IP)
/ip address remove [find interface=bridge and address~"192.168.1.1"]
:put "VLAN activation complete"
}
```
### Step 3.3: Run the Script (While in Safe Mode!)
```routeros
/system script run activate-vlan
```
### Step 3.4: Verify Immediately
```routeros
/ping 8.8.8.8 count=3
/ip address print
/interface bridge print
```
### Step 3.5: If Everything Works - Exit Safe Mode
Press **Ctrl+X** again to confirm and save changes.
### Step 3.6: If Connection Lost
- Wait up to 10 minutes
- Router will auto-rollback to previous state
- Reconnect via WinBox (MAC address)
---
## Phase 4: Verification
### Step 4.1: Check All Settings
```routeros
:put "=== Bridge VLAN Filtering ==="
/interface bridge print where name=bridge
:put "=== IP Addresses ==="
/ip address print
:put "=== DHCP Server ==="
/ip dhcp-server print
:put "=== Internet Test ==="
/ping 8.8.8.8 count=3
```
**Expected:**
- vlan-filtering=yes on bridge
- IP 192.168.1.1/24 ONLY on vlan40-catchall
- DHCP server on vlan40-catchall
- Internet working
### Step 4.2: Test Client Connectivity
From a device on the network:
1. Disconnect and reconnect WiFi
2. Check if you get IP from 192.168.1.x range
3. Test internet access
---
## Phase 5: Add Additional VLANs (After VLAN40 is Stable)
Wait 24-48 hours to ensure VLAN40 is stable before adding more VLANs.
### VLAN Overview
| VLAN | Name | Subnet | Purpose | Assignment |
|------|------|--------|---------|------------|
| 10 | Management | 192.168.10.0/24 | Infrastructure | Port-based (ether4,5) |
| 20 | Trusted | 192.168.20.0/24 | Family devices | RADIUS |
| 25 | Kids | 192.168.25.0/24 | Kids devices | RADIUS |
| 30 | IoT | 192.168.30.0/24 | Smart home | RADIUS |
| 40 | Catch-All | 192.168.1.0/24 | Default/Unknown | Default |
### Step 5.1: Create VLAN 10 (Management)
```routeros
# Create VLAN interface
/interface vlan add interface=bridge name=vlan10-mgmt vlan-id=10
# Add IP
/ip address add address=192.168.10.1/24 interface=vlan10-mgmt
# Add to bridge VLAN table - ether4/5 untagged for Unraid
/interface bridge vlan add bridge=bridge vlan-ids=10 tagged=bridge untagged=ether4,ether5
# Update PVID on Unraid ports
/interface bridge port set [find interface=ether4] pvid=10
/interface bridge port set [find interface=ether5] pvid=10
# Remove ether4/5 from VLAN40
/interface bridge vlan set [find vlan-ids=40] untagged=ether2,ether3,wifi1,wifi2
# Create DHCP for VLAN10
/ip pool add name=pool-vlan10 ranges=192.168.10.100-192.168.10.200
/ip dhcp-server add address-pool=pool-vlan10 interface=vlan10-mgmt name=dhcp-vlan10 disabled=no
/ip dhcp-server network add address=192.168.10.0/24 gateway=192.168.10.1 dns-server=8.8.8.8
```
### Step 5.2: Add Static Leases for VLAN10
```routeros
/ip dhcp-server lease
add address=192.168.10.2 mac-address=18:FD:74:54:3D:BC comment="CAP XL ac" server=dhcp-vlan10
add address=192.168.10.3 mac-address=F4:1E:57:C9:BD:09 comment="CSS326" server=dhcp-vlan10
add address=192.168.10.20 mac-address=A8:B8:E0:02:B6:15 comment="Unraid" server=dhcp-vlan10
```
---
## Rollback Commands
### Emergency: Disable VLAN Filtering
```routeros
/interface bridge set bridge vlan-filtering=no
```
### Full Rollback: Restore Backup
```routeros
/system backup load name=before-vlan-v3
```
### Factory Reset (Last Resort)
Hold reset button while powering on until LEDs flash.
---
## Safe Mode Quick Reference
| Action | WinBox | CLI |
|--------|--------|-----|
| Enter Safe Mode | Ctrl+X | Ctrl+X |
| Exit & Save | Ctrl+X | Ctrl+X |
| Exit & Discard | Close WinBox | Ctrl+D |
| Auto-rollback | ~10 minutes | ~10 minutes |
**Important:** Safe Mode only protects while you're connected. If disconnected, changes rollback automatically.
---
## Checklist Before Enabling VLAN Filtering
- [ ] Backup saved and downloaded
- [ ] WinBox connected via MAC (not IP)
- [ ] VLAN interface created
- [ ] Bridge tagged in VLAN table
- [ ] All ports have correct PVID
- [ ] IP added to VLAN interface
- [ ] Safe Mode entered (Ctrl+X)
- [ ] Ready to run activation script
---
## Troubleshooting
### Lost Connection After Enabling Filtering
1. Wait 10 minutes for Safe Mode rollback
2. If no rollback: Connect via WinBox MAC discovery
3. Run: `/interface bridge set bridge vlan-filtering=no`
### DHCP Not Working
Check DHCP server interface:
```routeros
/ip dhcp-server print
```
Should show `interface=vlan40-catchall`
### Internet Not Working
Check NAT:
```routeros
/ip firewall nat print
```
Should have masquerade rule for WAN.
### Devices Not Getting IP
1. Check bridge VLAN table has ports as untagged
2. Check ports have correct PVID
3. Check DHCP pool has available addresses

View File

@@ -0,0 +1,340 @@
# VLAN Setup Complete - Session Summary
**Date:** 2026-01-31
**Status:** COMPLETED
**Backup:** `vlan-setup-complete-2026-01-31.backup` and `.rsc` on router
---
## Executive Summary
Successfully implemented VLAN network segmentation on MikroTik hAP ax³ with:
- Port-based VLAN assignment for wired infrastructure
- MAC-based dynamic VLAN assignment for WiFi devices via access-list
- CAPsMAN configured for CAP XL ac management
---
## Current Network Configuration
### Router Access
| Method | IP | Port | User | Notes |
|--------|-----|------|------|-------|
| WinBox | 192.168.10.1 | 8291 | xtrm | Primary management |
| WebFig | 192.168.10.1 | 80 | xtrm | Web interface |
| SSH (Mac) | 192.168.10.1 | **2222** | xtrm | Key: ~/.ssh/mikrotik_key |
| SSH (Unraid) | 192.168.10.1 | **2222** | unraid | Key: ~/.ssh/id_ed25519 |
| WinBox | 192.168.1.1 | 8291 | xtrm | Via VLAN 40 |
| WinBox | 192.168.20.1 | 8291 | xtrm | Via VLAN 20 |
**Important:** SSH is on port **2222**, not 22!
### VLAN Structure (Implemented)
| VLAN | Name | Subnet | Gateway | DHCP Pool | Status |
|------|------|--------|---------|-----------|--------|
| 10 | Management | 192.168.10.0/24 | 192.168.10.1 | .100-.200 | ✅ Working |
| 20 | Trusted | 192.168.20.0/24 | 192.168.20.1 | .100-.200 | ✅ Working |
| 25 | Kids | 192.168.25.0/24 | 192.168.25.1 | .100-.200 | ✅ Configured |
| 30 | IoT | 192.168.30.0/24 | 192.168.30.1 | .100-.200 | ✅ Configured |
| 40 | Catch-All | 192.168.1.0/24 | 192.168.1.1 | .10-.250 | ✅ Default |
### Port Assignments
```
HAP ax³ Ports:
├── ether1: WAN (ISP DHCP)
├── ether2: CAP XL ac → VLAN 10 (PVID=10)
├── ether3: CSS326 switch → VLAN 10 (PVID=10)
├── ether4: Unraid eth1 → VLAN 10 (PVID=10)
├── ether5: Unraid eth2 → VLAN 10 (PVID=10)
├── wifi1: XTRM (5GHz) → Tagged VLANs 20,25,30,40
└── wifi2: XTRM2 (2.4GHz) → Tagged VLANs 20,25,30,40
```
### Bridge VLAN Table
```routeros
# VLAN 10 - Management (port-based)
vlan-ids=10 tagged=bridge untagged=ether2,ether3,ether4,ether5
# VLAN 20 - Trusted (WiFi MAC-based)
vlan-ids=20 tagged=bridge,wifi1,wifi2
# VLAN 25 - Kids (WiFi MAC-based)
vlan-ids=25 tagged=bridge,wifi1,wifi2
# VLAN 30 - IoT (WiFi MAC-based)
vlan-ids=30 tagged=bridge,wifi1,wifi2
# VLAN 40 - Catch-All (WiFi default)
vlan-ids=40 tagged=bridge untagged=wifi1,wifi2
```
---
## WiFi Configuration
### SSIDs
| SSID | Band | Interface | Password | Security |
|------|------|-----------|----------|----------|
| XTRM | 5GHz | wifi1 | M0stW4nt3d@home | WPA2/WPA3 |
| XTRM2 | 2.4GHz | wifi2 | M0stW4nt3d@IoT | WPA2 |
### WiFi Datapath (Critical for VLAN)
```routeros
/interface wifi datapath
add name=dp-vlan bridge=bridge
/interface wifi configuration
set cfg-xtrm datapath=dp-vlan
set cfg-xtrm2 datapath=dp-vlan
```
### WiFi Access-List (MAC-based VLAN Assignment)
The access-list assigns VLANs based on client MAC address:
```routeros
/interface wifi access-list
# VLAN 20 - Trusted devices
add action=accept mac-address=AA:ED:8B:2A:40:F1 vlan-id=20 comment="Samsung S25 Ultra - Kaloyan"
add action=accept mac-address=CE:B8:11:EA:8D:55 vlan-id=20 comment="MacBook - Kaloyan"
add action=accept mac-address=BE:A7:95:87:19:4A vlan-id=20 comment="MacBook 5GHz - Kaloyan"
# VLAN 25 - Kids devices
add action=accept mac-address=F2:B8:14:61:C8:27 vlan-id=25 comment="iPhone - Dancho"
add action=accept mac-address=90:91:64:70:0D:86 vlan-id=25 comment="Notebook - Kimi"
add action=accept mac-address=2A:2B:BA:86:D4:AF vlan-id=25 comment="iPhone - Kimi"
# VLAN 30 - IoT devices
add action=accept mac-address=D0:E7:82:F7:65:DD vlan-id=30 comment="Chromecast"
add action=accept mac-address=94:27:70:1E:0C:EE vlan-id=30 comment="Bosch Oven"
add action=accept mac-address=C8:5C:CC:52:EA:53 vlan-id=30 comment="Xiaomi Air Purifier"
add action=accept mac-address=18:DE:50:5B:C8:A6 vlan-id=30 comment="Tuya Device 1"
add action=accept mac-address=38:1F:8D:04:6F:E4 vlan-id=30 comment="Tuya Device 2"
add action=accept mac-address=D4:AD:FC:BE:13:B0 vlan-id=30 comment="Intellirocks"
# Default - VLAN 40 for unknown devices (MUST be last!)
add action=accept vlan-id=40 comment="Default - VLAN40"
```
**Important:** The default rule (no MAC specified) must be LAST in the list!
---
## VLAN 10 Verified Devices
| IP | MAC | Device | Status |
|----|-----|--------|--------|
| 192.168.10.1 | 78:9A:18:2C:A5:48 | HAP ax³ (Gateway) | ✅ |
| 192.168.10.2 | 18:FD:74:54:3D:BC | CAP XL ac | ✅ |
| 192.168.10.3 | F4:1E:57:C9:BD:09 | CSS326 Switch | ✅ |
| 192.168.10.10 | 02:42:C0:A8:1F:04 | AdGuard (Unraid) | ✅ |
| 192.168.10.20 | A8:B8:E0:02:B6:15 | Unraid Server | ✅ Verified |
| 192.168.10.200 | 48:DA:35:6F:BE:50 | NanoKVM | ✅ |
---
## CAPsMAN Configuration
```routeros
/interface wifi capsman
set enabled=yes interfaces=wifi1,wifi2 package-path="" upgrade-policy=suggest-same-version
/interface wifi provisioning
add action=create-enabled master-configuration=cfg-xtrm name-format=identity slave-configurations=cfg-xtrm2 supported-bands=5ghz-ax
add action=create-enabled master-configuration=cfg-xtrm2 name-format=identity slave-configurations=cfg-xtrm supported-bands=2ghz-ax
```
---
## Critical Lessons Learned
### 1. VLAN Filtering Breaks IP on Bridge
When you enable `vlan-filtering=yes` on the bridge:
- IP address on the bridge interface **stops working**
- You **must** have IP on the VLAN interface instead
- Never have same IP on both bridge and VLAN interface simultaneously
### 2. Correct Order of Operations
```
1. Create VLAN interfaces
2. Add IPs to VLAN interfaces (can have temporary duplicate)
3. Configure bridge VLAN table
4. Set port PVIDs
5. Add VLAN interfaces to firewall interface lists (LAN)
6. Enable VLAN filtering
7. Remove IP from bridge (if any duplicate)
8. Move DHCP server to VLAN interface
```
### 3. WiFi VLAN Assignment
- **Do NOT use** `action=query-radius` without configured RADIUS users
- **Use** WiFi datapath with `bridge=bridge`
- **Use** access-list with `vlan-id=XX` for MAC-based assignment
- WiFi interfaces must be **tagged** in bridge VLAN table for dynamic VLANs
### 4. Firewall Interface Lists
After creating VLAN interfaces, add them to the LAN list:
```routeros
/interface list member add list=LAN interface=vlan10-mgmt
/interface list member add list=LAN interface=vlan20-trusted
/interface list member add list=LAN interface=vlan25-kids
/interface list member add list=LAN interface=vlan30-iot
/interface list member add list=LAN interface=vlan40-catchall
```
### 5. Safe Mode
- Enter with **Ctrl+X** in WinBox
- Changes auto-rollback if connection lost (~10 minutes)
- Exit and save with **Ctrl+X** again
---
## Useful Commands
### Verify VLAN Status
```routeros
/interface bridge print where name=bridge
/interface bridge vlan print detail
/interface bridge port print
/ip address print
```
### Check WiFi Clients and VLAN Assignment
```routeros
/interface wifi registration-table print
/interface wifi access-list print
```
### Check DHCP Leases per VLAN
```routeros
/ip dhcp-server lease print where server=dhcp-vlan10
/ip dhcp-server lease print where server=dhcp-vlan20
```
### Add New Device to Access-List
```routeros
/interface wifi access-list add action=accept mac-address=XX:XX:XX:XX:XX:XX vlan-id=20 comment="Device Name" place-before=[find comment="Default - VLAN40"]
```
### Emergency Rollback
```routeros
/interface bridge set bridge vlan-filtering=no
```
### Restore from Backup
```routeros
/system backup load name=vlan-setup-complete-2026-01-31
```
---
## Pending Tasks
1. **Configure CAP XL ac to join CAPsMAN**
- CAP is on VLAN 10 at 192.168.10.2
- Needs provisioning to extend WiFi coverage
2. **Configure CSS326 for VLAN Trunking**
- Switch is on VLAN 10 at 192.168.10.3
- Needs VLAN configuration for room distribution
3. **Add Remaining Devices to Access-List**
- As devices connect, add their MACs to appropriate VLANs
4. **Configure Inter-VLAN Firewall Rules**
- Management → All (full access)
- Trusted → IoT (control smart home)
- IoT → Internet only (isolated)
- Guest → Internet only (isolated)
5. **Test VLAN 25 (Kids) and VLAN 30 (IoT)**
- Connect devices and verify DHCP/internet
---
## Connection Commands Reference
### SSH to Unraid (VLAN 10)
```bash
ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422
```
### SSH to MikroTik (port 2222!)
From Mac:
```bash
ssh -i ~/.ssh/mikrotik_key -p 2222 xtrm@192.168.10.1
```
From Unraid:
```bash
ssh -p 2222 unraid@192.168.10.1
```
### Quick Status from Unraid
```bash
ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422 "docker ps -a --format 'table {{.Names}}\t{{.Status}}'"
```
---
## Backup Files on Router
| File | Size | Description |
|------|------|-------------|
| vlan-setup-complete-2026-01-31.backup | 177.6 KiB | Binary backup (full restore) |
| vlan-setup-complete-2026-01-31.rsc | 12.5 KiB | Script export (readable) |
**Download via:** WinBox → Files → Select file → Download
---
## Network Diagram (Current)
```
Internet
┌───────────────────────────────────────────────────────────────┐
│ HAP ax³ (192.168.10.1) │
│ RouterOS 7.21.1 │
│ │
│ VLAN 10: 192.168.10.0/24 (Management) │
│ VLAN 20: 192.168.20.0/24 (Trusted) │
│ VLAN 25: 192.168.25.0/24 (Kids) │
│ VLAN 30: 192.168.30.0/24 (IoT) │
│ VLAN 40: 192.168.1.0/24 (Catch-All/Default) │
│ │
│ ether2 ─┬─ CAP XL ac (192.168.10.2) │
│ ether3 ─┼─ CSS326 (192.168.10.3) ─── NanoKVM (.199) │
│ ether4 ─┼─ Unraid (192.168.10.20) │
│ ether5 ─┘ │
│ │
│ wifi1 (XTRM 5GHz) ──┬── VLAN 20/25/30/40 via access-list │
│ wifi2 (XTRM2 2.4GHz)─┘ │
└───────────────────────────────────────────────────────────────┘
```
---
## Session Timeline
1. **CAPsMAN Setup** - Configured WiFi profiles (cfg-xtrm, cfg-xtrm2) and security
2. **Research** - Studied MikroTik forums for correct VLAN approach
3. **VLAN Infrastructure** - Created VLANs 10, 20, 25, 30, 40 with DHCP
4. **Safe Mode Implementation** - Used atomic script for VLAN filtering
5. **WiFi VLAN** - Configured datapath and access-list for MAC-based assignment
6. **Verification** - Tested connectivity on all VLANs
7. **Backup** - Created `vlan-setup-complete-2026-01-31`
---
**Document Version:** 1.0
**Last Updated:** 2026-01-31

View File

@@ -0,0 +1,521 @@
# AdGuard Configuration Plan for VLAN Structure
**Created:** 2026-01-31
**Status:** IMPLEMENTED
**Prerequisites:** VLAN setup complete (doc 15)
**See Also:** [17-DNS-ADGUARD-FAILOVER.md](17-DNS-ADGUARD-FAILOVER.md) - Complete implementation with failover
---
## Overview
Configure AdGuard DNS filtering for the new VLAN-segmented network with:
- MikroTik container as primary DNS (172.17.0.2)
- Unraid AdGuard as secondary DNS (192.168.10.10)
- DNS redirect for all VLANs
- Different filtering policies per VLAN (Kids stricter)
---
## Current State
| Component | IP | Status |
|-----------|-----|--------|
| AdGuard (Unraid) | 192.168.10.10 | Running |
| AdGuard (MikroTik) | 172.17.0.2 | Not installed |
| adguardhome-sync | 172.18.0.27 | Running |
---
## Network Architecture (VLAN-Aware)
```
┌─────────────────────────────────────────────────────────────────────────┐
│ INTERNET │
│ │
│ Mobile/Remote ──► dns.xtrm-lab.org ──► WAN:853 (DoT) │
│ ──► WAN:8443 (DoH) │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ MikroTik hAP ax³ │
│ 192.168.10.1 │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ AdGuard Container │ │
│ │ 172.17.0.2 (primary) │ │
│ │ │ │
│ │ Ports: 53 (DNS), 80 (HTTP), 443 (HTTPS), 853 (DoT) │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────┴────────────────────────────────┐ │
│ │ DNS Redirect Rules │ │
│ │ │ │
│ │ VLAN 10 (192.168.10.0/24) ─► 172.17.0.2:53 Management │ │
│ │ VLAN 20 (192.168.20.0/24) ─► 172.17.0.2:53 Trusted │ │
│ │ VLAN 25 (192.168.25.0/24) ─► 172.17.0.2:53 Kids │ │
│ │ VLAN 30 (192.168.30.0/24) ─► 172.17.0.2:53 IoT │ │
│ │ VLAN 40 (192.168.1.0/24) ─► 172.17.0.2:53 Catch-All │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ Unraid (VLAN 10) │
│ 192.168.10.20 │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ AdGuard Container (secondary) │ │
│ │ 192.168.10.10 │ │
│ │ │ │
│ │ Upstream: MikroTik AdGuard (172.17.0.2) │ │
│ │ Failover: Quad9 DoH │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ adguardhome-sync │ │
│ │ 172.18.0.27 │ │
│ │ │ │
│ │ Syncs: MikroTik ◄─► Unraid (filters, rewrites, clients) │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
---
## Phase 1: MikroTik Container Setup
### 1.1 Create Container Infrastructure
```routeros
# Container mode (if not already enabled)
/system/device-mode/update container=yes
# Create veth interface
/interface veth add address=172.17.0.2/24 gateway=172.17.0.1 name=veth-adguard
# Add to bridge
/interface bridge port add bridge=bridge interface=veth-adguard
# Gateway IP for container network
/ip address add address=172.17.0.1/24 interface=veth-adguard
```
### 1.2 Create Container Mounts
```routeros
# Create USB directory structure first
/file print # verify usb1 exists
# Create 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
```
### 1.3 Pull and Create Container
```routeros
# Environment variables
/container envs add name=agh-env key=TZ value="Europe/Sofia"
# Pull image and create container
/container add remote-image=adguard/adguardhome:latest \
interface=veth-adguard \
root-dir=usb1/adguard/root \
mounts=agh-config,agh-work \
envlist=agh-env \
dns=8.8.8.8 \
logging=yes \
start-on-boot=yes \
name=adguardhome
# Wait for extraction (check status)
/container print
# Start when status shows "stopped" (not "extracting")
/container start [find name=adguardhome]
```
---
## Phase 2: NAT Rules for All VLANs
### 2.1 Exception Rules (MUST BE FIRST)
```routeros
# Allow AdGuard containers' own DNS queries (prevent loops)
/ip firewall nat add chain=dstnat action=accept protocol=udp \
src-address=172.17.0.0/24 dst-port=53 \
comment="[DNS] Allow MikroTik AdGuard outbound" place-before=0
/ip firewall nat add chain=dstnat action=accept protocol=udp \
src-address=192.168.10.10 dst-port=53 \
comment="[DNS] Allow Unraid AdGuard outbound" place-before=1
/ip firewall nat add chain=dstnat action=accept protocol=tcp \
src-address=192.168.10.10 dst-port=53 \
comment="[DNS] Allow Unraid AdGuard outbound TCP" place-before=2
```
### 2.2 VLAN DNS Redirect Rules
```routeros
# VLAN 10 - Management (192.168.10.0/24)
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=udp src-address=192.168.10.0/24 dst-port=53 \
comment="[DNS] VLAN10 Mgmt redirect"
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=tcp src-address=192.168.10.0/24 dst-port=53 \
comment="[DNS] VLAN10 Mgmt redirect TCP"
# VLAN 20 - Trusted (192.168.20.0/24)
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=udp src-address=192.168.20.0/24 dst-port=53 \
comment="[DNS] VLAN20 Trusted redirect"
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=tcp src-address=192.168.20.0/24 dst-port=53 \
comment="[DNS] VLAN20 Trusted redirect TCP"
# VLAN 25 - Kids (192.168.25.0/24)
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=udp src-address=192.168.25.0/24 dst-port=53 \
comment="[DNS] VLAN25 Kids redirect"
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=tcp src-address=192.168.25.0/24 dst-port=53 \
comment="[DNS] VLAN25 Kids redirect TCP"
# VLAN 30 - IoT (192.168.30.0/24)
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=udp src-address=192.168.30.0/24 dst-port=53 \
comment="[DNS] VLAN30 IoT redirect"
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=tcp src-address=192.168.30.0/24 dst-port=53 \
comment="[DNS] VLAN30 IoT redirect TCP"
# VLAN 40 - Catch-All (192.168.1.0/24)
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=udp src-address=192.168.1.0/24 dst-port=53 \
comment="[DNS] VLAN40 CatchAll redirect"
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 \
protocol=tcp src-address=192.168.1.0/24 dst-port=53 \
comment="[DNS] VLAN40 CatchAll redirect TCP"
```
### 2.3 Masquerade Rules for Return Traffic
```routeros
# Masquerade for all VLAN subnets to AdGuard
/ip firewall nat add chain=srcnat action=masquerade protocol=udp \
src-address=192.168.10.0/24 dst-address=172.17.0.2 dst-port=53 \
comment="[DNS] VLAN10 masquerade"
/ip firewall nat add chain=srcnat action=masquerade protocol=udp \
src-address=192.168.20.0/24 dst-address=172.17.0.2 dst-port=53 \
comment="[DNS] VLAN20 masquerade"
/ip firewall nat add chain=srcnat action=masquerade protocol=udp \
src-address=192.168.25.0/24 dst-address=172.17.0.2 dst-port=53 \
comment="[DNS] VLAN25 masquerade"
/ip firewall nat add chain=srcnat action=masquerade protocol=udp \
src-address=192.168.30.0/24 dst-address=172.17.0.2 dst-port=53 \
comment="[DNS] VLAN30 masquerade"
/ip firewall nat add chain=srcnat action=masquerade protocol=udp \
src-address=192.168.1.0/24 dst-address=172.17.0.2 dst-port=53 \
comment="[DNS] VLAN40 masquerade"
```
### 2.4 External Access (DoT/DoH)
```routeros
# DoT (DNS over TLS) - port 853
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=853 \
protocol=tcp in-interface=ether1 dst-port=853 \
comment="[DNS] DoT external"
# DoH (DNS over HTTPS) - port 8443 → 443
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=443 \
protocol=tcp in-interface=ether1 dst-port=8443 \
comment="[DNS] DoH external"
```
### 2.5 Web UI Access
```routeros
# AdGuard Web UI on port 3000 from Management VLAN
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=80 \
protocol=tcp dst-address=192.168.10.1 dst-port=3000 \
comment="[DNS] AdGuard Web UI"
```
---
## Phase 3: Firewall Filter Rules
```routeros
# Allow traffic to container network
/ip firewall filter add chain=input action=accept dst-address=172.17.0.0/24 \
comment="[Container] Allow to container network" place-before=0
/ip firewall filter add chain=input action=accept src-address=172.17.0.0/24 \
comment="[Container] Allow from container network" place-before=1
/ip firewall filter add chain=forward action=accept dst-address=172.17.0.0/24 \
comment="[Container] Forward to container network"
/ip firewall filter add chain=forward action=accept src-address=172.17.0.0/24 \
comment="[Container] Forward from container network"
```
---
## Phase 4: MikroTik DNS Settings
```routeros
# Point MikroTik's own DNS resolver to AdGuard container
/ip dns set servers=172.17.0.2 allow-remote-requests=yes
```
---
## Phase 5: AdGuard Initial Configuration
### 5.1 Access Web UI
After container starts, access: `http://192.168.10.1:3000`
### 5.2 Initial Setup Wizard
| Setting | Value |
|---------|-------|
| Admin Interface | All interfaces, port 80 |
| DNS Server | All interfaces, port 53 |
| Username | admin |
| Password | (set secure password) |
### 5.3 Upstream DNS
```
# Primary (encrypted)
https://dns.quad9.net/dns-query
# Fallback to Unraid AdGuard
192.168.10.10
```
### 5.4 Bootstrap DNS
```
9.9.9.9
149.112.112.112
```
### 5.5 TLS Configuration (for DoT/DoH)
| Setting | Value |
|---------|-------|
| Server Name | dns.xtrm-lab.org |
| Certificate Path | /opt/adguardhome/conf/fullchain.pem |
| Key Path | /opt/adguardhome/conf/privkey.pem |
**Certificate upload:**
```bash
# From Mac - copy certificates to MikroTik USB
scp -P 2222 /path/to/fullchain.pem xtrm@192.168.10.1:usb1/adguard/conf/
scp -P 2222 /path/to/privkey.pem xtrm@192.168.10.1:usb1/adguard/conf/
```
---
## Phase 6: Client Configuration per VLAN
### 6.1 DHCP Network Settings
Update each VLAN's DHCP to advertise AdGuard as DNS:
```routeros
/ip dhcp-server network
set [find address=192.168.10.0/24] dns-server=192.168.10.10
set [find address=192.168.20.0/24] dns-server=192.168.10.10
set [find address=192.168.25.0/24] dns-server=192.168.10.10
set [find address=192.168.30.0/24] dns-server=192.168.10.10
set [find address=192.168.1.0/24] dns-server=192.168.10.10
```
**Note:** We use 192.168.10.10 (Unraid AdGuard) as the advertised DNS because:
1. Clients can reach it directly on VLAN 10
2. The NAT redirect still captures all DNS traffic to 172.17.0.2
3. If redirect fails, clients fall back to Unraid AdGuard
---
## Phase 7: AdGuard Sync Configuration
### 7.1 Update adguardhome-sync on Unraid
Edit `/mnt/user/appdata/adguardhome-sync/adguardhome-sync.yaml`:
```yaml
origin:
url: http://172.17.0.2 # MikroTik AdGuard (via router internal)
username: admin
password: YOUR_PASSWORD
replicas:
- url: http://192.168.10.10 # Unraid AdGuard
username: admin
password: YOUR_PASSWORD
cron: "0 */30 * * * *" # Every 30 minutes
api:
port: 8080
features:
dns:
rewrites: true
filters: true
clients: true
services: true
```
### 7.2 Restart Sync Container
```bash
docker restart adguardhome-sync
```
---
## Phase 8: Kids VLAN Special Configuration (Optional)
For stricter filtering on VLAN 25 (Kids), you can:
### Option A: Separate AdGuard Client Profile
In AdGuard → Settings → Client Settings, add clients for Kids VLAN:
- Identifier: 192.168.25.0/24
- Name: Kids Devices
- Enable: SafeSearch, Block Adult Sites
- Custom filters: stricter blocklists
### Option B: Redirect to Different DNS (More Complex)
Create separate DNS redirect for VLAN 25 to a different filtering service.
---
## Verification Checklist
After implementation, verify:
- [ ] Container running: `/container print` shows "running"
- [ ] DNS resolution: `:resolve google.com server=172.17.0.2`
- [ ] VLAN 10 DNS: `nslookup google.com` from Unraid
- [ ] VLAN 20 DNS: Test from trusted device
- [ ] VLAN 25 DNS: Test from kids device
- [ ] VLAN 30 DNS: Test from IoT device
- [ ] VLAN 40 DNS: Test from catch-all device
- [ ] DoT external: `kdig @dns.xtrm-lab.org +tls google.com`
- [ ] DoH external: `curl https://dns.xtrm-lab.org:8443/dns-query?name=google.com`
- [ ] Web UI accessible: `http://192.168.10.1:3000`
- [ ] Sync working: Check adguardhome-sync logs
---
## Troubleshooting
### Container won't start
```routeros
# Check container status
/container print detail
# Check logs
:log print where topics~"container"
# Common fix: recreate container
/container remove [find name=adguardhome]
# Then repeat Phase 1.3
```
### DNS not redirecting
```routeros
# Check NAT rules are active
/ip firewall nat print where comment~"DNS"
# Test packet flow
/tool sniffer quick port=53
```
### Sync not working
```bash
# On Unraid, check sync logs
docker logs adguardhome-sync
# Verify connectivity
curl -u admin:password http://172.17.0.2/control/status
```
---
## Quick Reference Commands
```routeros
# Check AdGuard container
/container print where name=adguardhome
# Restart AdGuard
/container stop [find name=adguardhome]
/container start [find name=adguardhome]
# Test DNS
:resolve google.com server=172.17.0.2
# Check DNS NAT rules
/ip firewall nat print where comment~"DNS"
# Backup before changes
/system backup save name=pre-adguard-$(date)
```
---
## Files Location
| Item | Location |
|------|----------|
| MikroTik AdGuard Config | usb1/adguard/conf/AdGuardHome.yaml |
| MikroTik AdGuard Work | usb1/adguard/work/ |
| MikroTik TLS Certs | usb1/adguard/conf/*.pem |
| Unraid AdGuard Config | /mnt/user/appdata/adguardhome/ |
| Sync Config | /mnt/user/appdata/adguardhome-sync/ |
---
## Implementation Order
1. **Backup MikroTik** - `/system backup save name=pre-adguard`
2. **Phase 1** - Container setup (requires device mode update + reboot)
3. **Phase 2** - NAT rules (careful with order!)
4. **Phase 3** - Firewall filters
5. **Phase 4** - MikroTik DNS settings
6. **Test** - Verify DNS works
7. **Phase 5** - AdGuard web configuration
8. **Phase 6** - DHCP updates
9. **Phase 7** - Sync setup
10. **Phase 8** - Kids filtering (optional)
---
**Document Version:** 1.0
**Last Updated:** 2026-01-31

View File

@@ -0,0 +1,415 @@
# DNS Architecture with AdGuard Failover
**Created:** 2026-01-31
**Updated:** 2026-01-31
**Status:** Implemented
**Backup:** `dns-dual-failover-2026-01-31.backup`
---
## Overview
Dual AdGuard DNS setup with automatic failover. All DNS queries are filtered through AdGuard for ad-blocking, and if the primary (MikroTik) fails, traffic automatically switches to secondary (Unraid).
---
## Architecture
```
┌─────────────────────────────────────┐
│ INTERNET │
│ │
│ External clients (DoT/DoH) │
│ dns.xtrm-lab.org:853 (DoT) │
│ dns.xtrm-lab.org:8443 (DoH) │
└──────────────┬──────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ MikroTik hAP ax³ (192.168.10.1) │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ AdGuard Home (PRIMARY) │ │
│ │ Container: 172.17.0.2 │ │
│ │ Web UI: http://192.168.10.1:3000 │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Filters │ │ Blocklists │ │ Clients │ │ │
│ │ │ (synced) │ │ 143K rules │ │ (synced) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ Netwatch monitors every 10s │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ │ │
│ Container UP Container DOWN │
│ │ │ │
│ ▼ ▼ │
│ NAT → 172.17.0.2 NAT → 192.168.10.10 │
│ (MikroTik) (Unraid Failover) │
└──────────────────────────────────────────────────────────────────────────────┘
▲ ▲ ▲
│ │ │
NAT Redirect NAT Redirect NAT Redirect
│ │ │
┌───────┴───────┐ ┌────────┴────────┐ ┌────────┴────────┐
│ VLAN 10 │ │ VLAN 20/25 │ │ VLAN 30/40 │
│ Management │ │ Trusted/Kids │ │ IoT/CatchAll │
│ 192.168.10.x │ │ 192.168.20.x │ │ 192.168.30.x │
│ │ │ 192.168.25.x │ │ 192.168.1.x │
└───────────────┘ └─────────────────┘ └─────────────────┘
```
---
## AdGuard Instances
| Instance | Role | IP | Port | Web UI |
|----------|------|-----|------|--------|
| MikroTik | Primary | 172.17.0.2 | 53 | http://192.168.10.1:3000 |
| Unraid | Secondary/Failover | 192.168.10.10 | 3000 | http://192.168.10.10:3000 |
### Credentials (Same for Both)
| Username | Password |
|----------|----------|
| jazzymc | 7RqWElENNbZnPW |
---
## DNS Redirect Rules
All DNS queries (port 53) from any VLAN are intercepted and redirected:
| VLAN | Subnet | Redirected To |
|------|--------|---------------|
| 10 | 192.168.10.0/24 | 172.17.0.2:53 |
| 20 | 192.168.20.0/24 | 172.17.0.2:53 |
| 25 | 192.168.25.0/24 | 172.17.0.2:53 |
| 30 | 192.168.30.0/24 | 172.17.0.2:53 |
| 40 | 192.168.1.0/24 | 172.17.0.2:53 |
**Note:** Clients don't need any DNS configuration - even if they use 8.8.8.8, traffic is intercepted by NAT.
### NAT Rules on MikroTik
```routeros
# Exception rules (prevent loops) - MUST BE FIRST
/ip firewall nat
add chain=dstnat action=accept protocol=udp src-address=172.17.0.0/24 dst-port=53 comment="[DNS] Allow MikroTik AdGuard outbound"
add chain=dstnat action=accept protocol=udp src-address=192.168.10.10 dst-port=53 comment="[DNS] Allow Unraid AdGuard outbound"
# VLAN redirect rules
add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp src-address=192.168.10.0/24 dst-port=53 comment="[DNS] VLAN10 Mgmt redirect"
add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp src-address=192.168.20.0/24 dst-port=53 comment="[DNS] VLAN20 Trusted redirect"
add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp src-address=192.168.25.0/24 dst-port=53 comment="[DNS] VLAN25 Kids redirect"
add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp src-address=192.168.30.0/24 dst-port=53 comment="[DNS] VLAN30 IoT redirect"
add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp src-address=192.168.1.0/24 dst-port=53 comment="[DNS] VLAN40 CatchAll redirect"
# Masquerade for return traffic
add chain=srcnat action=masquerade protocol=udp src-address=192.168.10.0/24 dst-address=172.17.0.2 dst-port=53 comment="[DNS] VLAN10 masquerade"
# ... (similar for other VLANs)
```
---
## Automatic Failover
### How It Works (Dual Health Check)
Two independent Netwatch monitors trigger failover:
| Monitor | Type | What It Checks | Interval | Timeout |
|---------|------|----------------|----------|---------|
| Ping | simple | Container reachable | 10s | 3s |
| DNS | dns | DNS queries work | 30s | 10s |
**Either monitor failing triggers failover to Unraid.**
### Failure Scenarios Covered
| Scenario | Ping Check | DNS Check | Failover? |
|----------|------------|-----------|-----------|
| Container crashed | ✗ Fail | ✗ Fail | ✅ Yes |
| Container stopped | ✗ Fail | ✗ Fail | ✅ Yes |
| Network/routing issue | ✗ Fail | ✗ Fail | ✅ Yes |
| Upstream DNS unreachable | ✓ Pass | ✗ Fail | ✅ Yes |
| AdGuard overloaded | ✓ Pass | ✗ Fail | ✅ Yes |
| Everything working | ✓ Pass | ✓ Pass | ❌ No |
### Failover Timeline
| Event | Detection Time | Total Switchover |
|-------|----------------|------------------|
| Container crash (ping) | ~10-13 seconds | ~13-16 seconds |
| DNS failure (resolution) | ~30-40 seconds | ~33-43 seconds |
| Recovery | ~10-30 seconds | Automatic |
### Failover Scripts
```routeros
# dns-failover-down (runs when either check fails)
/system script add name=dns-failover-down dont-require-permissions=yes source={
:log warning "DNS Failover: Switching to Unraid"
/ip firewall nat set [find where comment~"VLAN" and comment~"redirect"] to-addresses=192.168.10.10 to-ports=3000
}
# dns-failover-up (runs when check recovers)
/system script add name=dns-failover-up dont-require-permissions=yes source={
:log info "DNS Failover: Switching back to MikroTik"
/ip firewall nat set [find where comment~"VLAN" and comment~"redirect"] to-addresses=172.17.0.2 to-ports=53
}
```
### Netwatch Configuration
```routeros
# Monitor 1: Ping check (fast crash detection)
/tool netwatch add type=simple host=172.17.0.2 interval=10s timeout=3s \
up-script=dns-failover-up down-script=dns-failover-down \
comment="AdGuard failover monitor"
# Monitor 2: DNS resolution check (functional verification)
/tool netwatch add type=dns host=google.com interval=30s timeout=10s \
up-script=dns-failover-up down-script=dns-failover-down \
comment="AdGuard DNS resolution check"
```
---
## Sync Configuration
Settings are synced from Unraid (source of truth) to MikroTik every 30 minutes.
### What Syncs
| Feature | Synced |
|---------|--------|
| Filter lists (blocklists) | ✅ |
| User rules (custom blocks/allows) | ✅ |
| Client settings (per-device rules) | ✅ |
| Services (blocked services) | ✅ |
| Rewrites (custom DNS entries) | ✅ |
| DNS server config | ❌ |
| DHCP settings | ❌ |
| Query logs/stats | ❌ |
### Sync Container
```yaml
# /mnt/user/appdata/adguard-sync/adguardhome-sync.yaml
cron: "*/30 * * * *"
runOnStart: true
origin:
url: http://192.168.10.10:3000
username: jazzymc
password: 7RqWElENNbZnPW
replicas:
- url: http://192.168.10.1:3000
username: jazzymc
password: 7RqWElENNbZnPW
features:
dns:
serverConfig: false
accessLists: true
rewrites: true
filters: true
clientSettings: true
services: true
```
**Note:** The sync container must be connected to both `dockerproxy` and `br0` networks to reach both AdGuard instances.
---
## Container Configuration (MikroTik)
### Container Details
| Setting | Value |
|---------|-------|
| Image | adguard/adguardhome:latest |
| Interface | veth-adguard |
| IP | 172.17.0.2/24 |
| Gateway | 172.17.0.1 |
| Root dir | usb1/adguard/root |
| Config mount | usb1/adguard/conf → /opt/adguardhome/conf |
| Work mount | usb1/adguard/work → /opt/adguardhome/work |
| Start on boot | Yes |
### Container Commands
```routeros
# Check status
/container print
# Start container
/container start 0
# Stop container
/container stop 0
# View logs
/log print where topics~"container"
```
---
## Upstream DNS
Both AdGuard instances use the same upstream:
| Upstream | Type |
|----------|------|
| https://dns.quad9.net/dns-query | Primary (DoH) |
| 9.9.9.9 | Bootstrap |
| 149.112.112.112 | Bootstrap secondary |
---
## Management
| Task | Where to Do It |
|------|----------------|
| Change blocklists | Unraid AdGuard (syncs to MikroTik) |
| Add custom rules | Unraid AdGuard |
| Add client settings | Unraid AdGuard |
| View query logs | MikroTik AdGuard (real-time) |
| Check failover status | MikroTik `/tool netwatch print` |
---
## Troubleshooting
### Check Failover Status
```routeros
/tool netwatch print
# Both monitors should show STATUS=up normally
# Monitor 0: Ping check
# Monitor 1: DNS resolution check
```
### Check Current DNS Target
```routeros
/ip firewall nat print where comment~"VLAN10 Mgmt redirect"
# to-addresses should be 172.17.0.2 (normal) or 192.168.10.10 (failover)
```
### View Failover Logs
```routeros
/log print where message~"Failover"
```
### Manual Failover Test
```routeros
# Stop container (triggers failover)
/container stop 0
# Wait 15 seconds, check NAT rules switched to 192.168.10.10
# Start container (triggers recovery)
/container start 0
# Wait 15 seconds, check NAT rules switched back to 172.17.0.2
```
### DNS Not Working
1. Check container is running: `/container print`
2. Check netwatch status: `/tool netwatch print`
3. Test DNS directly: `:resolve google.com server=172.17.0.2`
4. Check NAT rules: `/ip firewall nat print where comment~"DNS"`
5. **Check /32 routes exist:** `/ip route print where dst-address~"172.17.0.[23]"`
6. **Ping container:** `/ping 172.17.0.2 count=3`
### Container Reachable but DNS Fails
If ping works but DNS queries timeout:
1. Check container can reach upstream: Look for timeout errors in logs
2. Verify /32 routes: Missing routes cause ECMP issues
3. Check NAT masquerade: `/ip firewall nat print where comment~"Container"`
4. Verify routes:
```routeros
/ip route print where dst-address~"172.17"
# Should show /32 routes for each container IP
```
### Sync Not Working
```bash
# On Unraid
docker logs adguardhome-sync --tail 20
# Check connectivity
docker exec adguardhome-sync ping -c 2 192.168.10.10
docker exec adguardhome-sync ping -c 2 192.168.10.1
```
---
## Container Network Routing
### Important: /32 Host Routes Required
When running multiple containers on the same subnet (172.17.0.0/24), specific host routes are required to prevent ECMP routing issues:
```routeros
# Without these routes, return traffic may go to wrong container
/ip route add dst-address=172.17.0.2/32 gateway=veth-adguard comment="AdGuard container - specific route"
/ip route add dst-address=172.17.0.3/32 gateway=veth-tailscale comment="Tailscale container - specific route"
```
**Why this matters:** Each veth interface creates a /24 route. With multiple veth interfaces on the same subnet, RouterOS enables ECMP load balancing, sending return traffic to random interfaces.
---
## Backups
| Backup | Description |
|--------|-------------|
| `pre-adguard-2026-01-31` | Before AdGuard setup |
| `adguard-container-running-2026-01-31` | Container working, before NAT |
| `adguard-synced-2026-01-31` | After sync configured |
| `adguard-failover-complete-2026-01-31` | Single ping failover |
| `routing-fix-complete-2026-01-31` | After /32 routing fix |
| `dns-dual-failover-2026-01-31` | Dual health check (current) |
### Restore Command
```routeros
/system backup load name=dns-dual-failover-2026-01-31
```
---
## Quick Reference
### Normal Operation
- DNS queries → MikroTik AdGuard (172.17.0.2)
- Ad blocking active
- ~143,000 filter rules
### During Failover
- DNS queries → Unraid AdGuard (192.168.10.10)
- Ad blocking still active (same rules synced)
- Automatic, no manual intervention needed
### Recovery
- Automatic when container comes back up
- NAT rules switch back to MikroTik
- No DNS interruption for clients
---
**Document Version:** 1.1
**Last Updated:** 2026-01-31
**Changes:** Added dual health check (ping + DNS), documented /32 routing fix

View File

@@ -0,0 +1,224 @@
# MikroTik Tailscale Container Setup
**Created:** 2026-01-31
**Status:** Implemented
**Backup:** `tailscale-working-2026-01-31.backup`
---
## Overview
Tailscale VPN running as a container on MikroTik hAP ax³, providing remote access to the home network via the Tailscale mesh network.
---
## Architecture
```
┌─────────────────────────────────────────────────────────────────────┐
│ MikroTik hAP ax³ (192.168.10.1) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Container Network (172.17.0.0/24) │ │
│ │ │ │
│ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ AdGuard Home │ │ Tailscale │ │ │
│ │ │ 172.17.0.2 │ │ 172.17.0.3 │ │ │
│ │ │ veth-adguard │ │ veth-tailscale │ │ │
│ │ └─────────────────────┘ └─────────────────────────┘ │ │
│ │ │ │ │ │
│ │ └───────────┬───────────────┘ │ │
│ │ │ │ │
│ │ Gateway: 172.17.0.1 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ NAT Masquerade │
│ │ │
│ WAN (ether1) │
└──────────────────────────────┬──────────────────────────────────────┘
┌─────────────────────┐
│ Tailscale Network │
│ 100.x.x.x mesh │
│ │
│ Home Router IP: │
│ 100.74.219.35 │
└─────────────────────┘
```
---
## Container Details
| Setting | Value |
|---------|-------|
| Image | tailscale/tailscale:latest |
| Interface | veth-tailscale |
| Container IP | 172.17.0.3/24 |
| Gateway | 172.17.0.1 |
| Tailscale IP | 100.74.219.35 |
| Root dir | usb1/tailscale/root |
| State mount | usb1/tailscale → /var/lib/tailscale |
| DNS | 8.8.8.8 |
| Start on boot | Yes |
| Networking mode | Userspace (TS_USERSPACE=true) |
---
## Environment Variables
| Variable | Value | Purpose |
|----------|-------|---------|
| TS_AUTHKEY | tskey-auth-... | One-time auth key (used during setup) |
| TS_STATE_DIR | /var/lib/tailscale | Persistent state directory |
| TS_USERSPACE | true | Required for MikroTik containers (no /dev/net/tun) |
---
## Network Configuration
### veth Interface
```routeros
/interface veth add address=172.17.0.3/24 gateway=172.17.0.1 name=veth-tailscale
```
### Gateway IP on Interface
```routeros
/ip address add address=172.17.0.1/24 interface=veth-tailscale comment="Tailscale container gateway"
```
### NAT Masquerade for Internet Access
```routeros
/ip firewall nat add chain=srcnat action=masquerade src-address=172.17.0.0/24 out-interface-list=WAN comment="Container network NAT"
```
### Firewall Forward Rules
```routeros
/ip firewall filter add chain=forward action=accept dst-address=172.17.0.0/24 comment="[Container] Forward to container network"
/ip firewall filter add chain=forward action=accept src-address=172.17.0.0/24 comment="[Container] Forward from container network"
```
---
## Container Setup Commands
### Create Mounts
```routeros
/container mounts add list=ts-state src=usb1/tailscale dst=/var/lib/tailscale
```
### Create Environment Variables
```routeros
/container envs add list=ts-env key=TS_STATE_DIR value=/var/lib/tailscale
/container envs add list=ts-env key=TS_USERSPACE value=true
/container envs add list=ts-env key=TS_AUTHKEY value=<your-auth-key>
```
### Create Container
```routeros
/container add remote-image=tailscale/tailscale:latest interface=veth-tailscale \
root-dir=usb1/tailscale/root mountlists=ts-state envlists=ts-env \
dns=8.8.8.8 start-on-boot=yes logging=yes
```
---
## Management
### Check Container Status
```routeros
/container print
```
### View Logs
```routeros
/log print where topics~"container" and message~"tailscale"
```
### Start/Stop Container
```routeros
/container start [find name~"tailscale"]
/container stop [find name~"tailscale"]
```
---
## Troubleshooting
### Container Won't Start (Exit Status 1)
**Cause:** Missing /dev/net/tun device (default for Tailscale)
**Solution:** Enable userspace networking mode:
```routeros
/container envs add list=ts-env key=TS_USERSPACE value=true
```
### Can't Reach Internet from Container
**Cause:** Missing NAT masquerade or gateway IP
**Solution:**
1. Verify gateway IP on veth interface:
```routeros
/ip address print where interface=veth-tailscale
```
2. Verify NAT masquerade rule:
```routeros
/ip firewall nat print where src-address=172.17.0.0/24
```
### Container Not Connecting to Tailscale
1. Check DNS resolution works (logs should show no timeout)
2. Verify auth key is valid and not expired
3. Check firewall isn't blocking outbound HTTPS
---
## Tailscale Network Devices
| Tailscale IP | Device | Status |
|--------------|--------|--------|
| 100.74.219.35 | MikroTik hAP ax³ (container) | Online |
| 100.100.208.70 | xtrm-unraid | Online |
| 100.112.103.7 | hapax3 (old native install) | Offline |
| 100.75.93.123 | mikrotik-tailscale (previous container) | Offline |
---
## Important Notes
1. **Userspace Networking Required:** MikroTik containers don't have /dev/net/tun access, so TS_USERSPACE=true is mandatory
2. **Auth Key:** After initial authentication, the key is no longer needed - state is persisted in the mount
3. **Container Network:** Both AdGuard and Tailscale share the 172.17.0.0/24 network but have separate veth interfaces
4. **Accept Routes:** If subnet routing is needed, add TS_EXTRA_ARGS="--accept-routes" to environment
---
## Backups
| Backup | Description |
|--------|-------------|
| pre-tailscale-2026-01-31 | Before Tailscale setup |
| tailscale-working-2026-01-31 | Tailscale container running |
---
**Document Version:** 1.0
**Last Updated:** 2026-01-31

View File

@@ -0,0 +1,173 @@
# Device Migration Worksheet
**Last Updated:** 2026-02-01
**Purpose:** Planning worksheet for VLAN/IP reassignment
---
## All Devices by VLAN
### VLAN 10 - Management (Infrastructure)
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| HAP1 (hAP ax³) | 78:9A:18:2C:A5:48 | 192.168.10.1 | 10 | | |
| CAP XL ac | 18:FD:74:54:3D:BC | 192.168.10.2 | 10 | | |
| CSS326-24G-2S+ | F4:1E:57:C9:BD:09 | 192.168.10.3 | 10 | | |
| ZX1 (ZX-SWTGW218AS) | 1C:2A:A3:1E:78:67 | 192.168.10.4 | 10 | | |
| AdGuard Home (Unraid) | 02:42:C0:A8:1F:04 | 192.168.10.10 | 10 | | |
| XTRM-U (Unraid) | A8:B8:E0:02:B6:15 | 192.168.10.20 | 10 | | |
| NanoKVM | 48:DA:35:6F:BE:50 | 192.168.10.200 | 10 | | |
| AdGuard (MikroTik) | 46:D0:27:F7:1F:CA | 172.17.0.2 | 10 | | |
| Tailscale (MikroTik) | 0C:AB:39:8D:8C:FC | 172.17.0.3 | 10 | | |
---
### VLAN 20 - Trusted (Family Devices)
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| MacBook Air (Nora) | 82:6D:FB:D9:E0:47 | 192.168.20.10 | 20 | | |
| Samsung S25 Ultra (Kaloyan) | AA:ED:8B:2A:40:F1 | 192.168.20.11 | 20 | | |
| iPhone (Dancho) | F2:B8:14:61:C8:27 | 192.168.20.12 | 20 | | |
| MacBook Pro WiFi (Kaloyan) | 82:EC:EF:B5:F2:AF | 192.168.20.13 | 20 | | |
| Notebook (Kimi) | 90:91:64:70:0D:86 | 192.168.20.14 | 20 | | |
| iPhone (Kimi) | 2A:2B:BA:86:D4:AF | 192.168.20.15 | 20 | | |
| MacBook Pro LAN (Kaloyan) | 08:92:04:C6:07:C5 | 192.168.20.16 | 20 | | |
| Gaming PC (Kaloyan) | 1C:83:41:32:F3:AF | 192.168.20.17 | 20 | | |
| iPad (Compusbg) | A4:D1:D2:7B:52:BE | 192.168.20.18 | 20 | | |
---
### VLAN 25 - Kids Devices
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| iPhone (Dancho) | F2:B8:14:61:C8:27 | 192.168.20.12 | 25 | | |
| Notebook (Kimi) | 90:91:64:70:0D:86 | 192.168.20.14 | 25 | | |
| iPhone (Kimi) | 2A:2B:BA:86:D4:AF | 192.168.20.15 | 25 | | |
| iPad (Compusbg) | A4:D1:D2:7B:52:BE | 192.168.20.18 | 25 | | |
---
### VLAN 30 - IoT (Smart Home)
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| GREE Air Conditioner | 50:2C:C6:7A:55:39 | 192.168.30.10 | 30 | | |
| LG TV (LAN) | B0:37:95:79:AF:9B | 192.168.30.11 | 30 | | |
| LG TV (WiFi) | DC:03:98:6B:5A:3A | 192.168.30.12 | 30 | | |
| Chromecast | D0:E7:82:F7:65:DD | 192.168.30.13 | 30 | | |
| Roborock S7 Vacuum | B0:4A:39:3F:9A:14 | 192.168.30.14 | 30 | | |
| Bosch Smart Oven | 94:27:70:1E:0C:EE | 192.168.30.20 | 30 | | |
| Bosch Dishwasher | C8:D7:78:40:65:40 | 192.168.30.21 | 30 | | |
| Bosch Washer | C8:D7:78:D6:DC:FC | 192.168.30.22 | 30 | | |
| Tuya Smart Device | 18:DE:50:5B:C8:A6 | 192.168.30.31 | 30 | | |
| Xiaomi Smart Device | 38:1F:8D:04:6F:E4 | 192.168.30.32 | 30 | | |
| Tuya/Intellirocks Device | D4:AD:FC:BE:13:B0 | 192.168.30.33 | 30 | | |
| Xiaomi Air Purifier | C8:5C:CC:52:EA:53 | 192.168.30.39 | 30 | | |
---
### VLAN 35 - Cameras (Security)
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| Reolink Doorbell | 48:9E:9D:0E:16:F7 | 192.168.35.10 | 35 | | |
---
### VLAN 40 - Servers (Services)
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| HP LaserJet | 64:4E:D7:D8:43:3E | 192.168.40.19 | 40 | | |
---
### VLAN 50 - Guest (Isolated)
| Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|--------|-------------|------------|--------------|----------|--------|
| Apple Device (unknown) | AC:87:A3:77:8F:BD | 192.168.50.10 | 50 | | |
| Unknown Device (Privacy MAC) | 22:4C:7F:1D:85:8E | 192.168.50.11 | 50 | | |
| Unknown Device | D0:C9:07:92:1A:8E | 192.168.50.12 | 50 | | |
| Unknown Device | D0:C9:07:8C:C9:46 | 192.168.50.13 | 50 | | |
---
## Summary
| VLAN | Name | Subnet | Device Count |
|------|------|--------|--------------|
| 10 | Mgmt | 192.168.10.0/24 | 9 |
| 20 | Trusted | 192.168.20.0/24 | 9 |
| 25 | Kids | 192.168.25.0/24 | 4 |
| 30 | IoT | 192.168.30.0/24 | 12 |
| 35 | Cameras | 192.168.35.0/24 | 1 |
| 40 | Servers | 192.168.40.0/24 | 1 |
| 50 | Guest | 192.168.50.0/24 | 4 |
| **Total** | | | **40** |
---
## Flat List (All Devices)
| # | Device | MAC Address | Current IP | Current VLAN | New VLAN | New IP |
|---|--------|-------------|------------|--------------|----------|--------|
| 1 | HAP1 (hAP ax³) | 78:9A:18:2C:A5:48 | 192.168.10.1 | 10 | | |
| 2 | CAP XL ac | 18:FD:74:54:3D:BC | 192.168.10.2 | 10 | | |
| 3 | CSS326-24G-2S+ | F4:1E:57:C9:BD:09 | 192.168.10.3 | 10 | | |
| 4 | ZX1 (ZX-SWTGW218AS) | 1C:2A:A3:1E:78:67 | 192.168.10.4 | 10 | | |
| 5 | AdGuard Home (Unraid) | 02:42:C0:A8:1F:04 | 192.168.10.10 | 10 | | |
| 6 | XTRM-U (Unraid) | A8:B8:E0:02:B6:15 | 192.168.10.20 | 10 | | |
| 7 | NanoKVM | 48:DA:35:6F:BE:50 | 192.168.10.200 | 10 | | |
| 8 | AdGuard (MikroTik) | 46:D0:27:F7:1F:CA | 172.17.0.2 | 10 | | |
| 9 | Tailscale (MikroTik) | 0C:AB:39:8D:8C:FC | 172.17.0.3 | 10 | | |
| 10 | MacBook Air (Nora) | 82:6D:FB:D9:E0:47 | 192.168.20.10 | 20 | | |
| 11 | Samsung S25 Ultra (Kaloyan) | AA:ED:8B:2A:40:F1 | 192.168.20.11 | 20 | | |
| 12 | iPhone (Dancho) | F2:B8:14:61:C8:27 | 192.168.20.12 | 20/25 | | |
| 13 | MacBook Pro WiFi (Kaloyan) | 82:EC:EF:B5:F2:AF | 192.168.20.13 | 20 | | |
| 14 | Notebook (Kimi) | 90:91:64:70:0D:86 | 192.168.20.14 | 20/25 | | |
| 15 | iPhone (Kimi) | 2A:2B:BA:86:D4:AF | 192.168.20.15 | 20/25 | | |
| 16 | MacBook Pro LAN (Kaloyan) | 08:92:04:C6:07:C5 | 192.168.20.16 | 20 | | |
| 17 | Gaming PC (Kaloyan) | 1C:83:41:32:F3:AF | 192.168.20.17 | 20 | | |
| 18 | iPad (Compusbg) | A4:D1:D2:7B:52:BE | 192.168.20.18 | 20/25 | | |
| 19 | GREE Air Conditioner | 50:2C:C6:7A:55:39 | 192.168.30.10 | 30 | | |
| 20 | LG TV (LAN) | B0:37:95:79:AF:9B | 192.168.30.11 | 30 | | |
| 21 | LG TV (WiFi) | DC:03:98:6B:5A:3A | 192.168.30.12 | 30 | | |
| 22 | Chromecast | D0:E7:82:F7:65:DD | 192.168.30.13 | 30 | | |
| 23 | Roborock S7 Vacuum | B0:4A:39:3F:9A:14 | 192.168.30.14 | 30 | | |
| 24 | Bosch Smart Oven | 94:27:70:1E:0C:EE | 192.168.30.20 | 30 | | |
| 25 | Bosch Dishwasher | C8:D7:78:40:65:40 | 192.168.30.21 | 30 | | |
| 26 | Bosch Washer | C8:D7:78:D6:DC:FC | 192.168.30.22 | 30 | | |
| 27 | Tuya Smart Device | 18:DE:50:5B:C8:A6 | 192.168.30.31 | 30 | | |
| 28 | Xiaomi Smart Device | 38:1F:8D:04:6F:E4 | 192.168.30.32 | 30 | | |
| 29 | Tuya/Intellirocks Device | D4:AD:FC:BE:13:B0 | 192.168.30.33 | 30 | | |
| 30 | Xiaomi Air Purifier | C8:5C:CC:52:EA:53 | 192.168.30.39 | 30 | | |
| 31 | Reolink Doorbell | 48:9E:9D:0E:16:F7 | 192.168.35.10 | 35 | | |
| 32 | HP LaserJet | 64:4E:D7:D8:43:3E | 192.168.40.19 | 40 | | |
| 33 | Apple Device (unknown) | AC:87:A3:77:8F:BD | 192.168.50.10 | 50 | | |
| 34 | Unknown Device (Privacy MAC) | 22:4C:7F:1D:85:8E | 192.168.50.11 | 50 | | |
| 35 | Unknown Device | D0:C9:07:92:1A:8E | 192.168.50.12 | 50 | | |
| 36 | Unknown Device | D0:C9:07:8C:C9:46 | 192.168.50.13 | 50 | | |
---
## Notes
- Devices marked with `20/25` in Current VLAN are in both Trusted and Kids VLANs (kids devices with family access)
- MikroTik containers (AdGuard, Tailscale) use internal Docker IPs (172.17.0.x)
- Fill in "New VLAN" and "New IP" columns to plan migration
---
## HAP ax³ Port Assignments
| Port | Device | VLAN |
|------|--------|------|
| ether1 | ISP Gateway (WAN) | - |
| ether2 | CAP XL ac | 10 (trunk) |
| ether3 | CSS326-24G-2S+ | 10 (trunk) |
| ether4 | XTRM-U (Unraid) | 10 |
| ether5 | Dell Monitor LAN | 10 |

View File

@@ -0,0 +1,56 @@
# DNS Redirect Rules Backup
**Date:** 2026-01-27
**Reason:** Temporarily disabled during VLAN migration
**Status:** DISABLED - to be re-enabled after VLAN setup complete
## NAT Rules (dstnat)
| # | Comment | Chain | Action | Src Address | Dst Port | To Address | To Port |
|---|---------|-------|--------|-------------|----------|------------|---------|
| 3 | Allow MikroTik AdGuard outbound DNS | dstnat | accept | 172.17.0.0/24 | 53/udp | - | - |
| 25 | Allow Unraid AdGuard outbound DNS | dstnat | accept | 192.168.31.4 | 53/udp | - | - |
| 26 | Allow Unraid AdGuard outbound DNS TCP | dstnat | accept | 192.168.31.4 | 53/tcp | - | - |
| 27 | Redirect DNS to MikroTik AdGuard | dstnat | dst-nat | 192.168.31.0/24 | 53/udp | 172.17.0.2 | 53 |
| 28 | Redirect DNS to MikroTik AdGuard TCP | dstnat | dst-nat | 192.168.31.0/24 | 53/tcp | 172.17.0.2 | 53 |
| 30 | DNS over TLS (DoT) | dstnat | dst-nat | in-interface=eth1_WAN | 853/tcp | 172.17.0.2 | 853 |
| 31 | DNS over HTTPS (DoH) | dstnat | dst-nat | in-interface=eth1_WAN | 8443/tcp | 172.17.0.2 | 443 |
| 32 | Redirect VLAN DNS to AdGuard | dstnat | dst-nat | src-address-list=all-vlans | 53/udp | 172.17.0.2 | 53 |
| 33 | Redirect VLAN DNS to AdGuard TCP | dstnat | dst-nat | src-address-list=all-vlans | 53/tcp | 172.17.0.2 | 53 |
## NAT Rules (srcnat - masquerade)
| # | Comment | Chain | Action | Src Address | Dst Address | Dst Port |
|---|---------|-------|--------|-------------|-------------|----------|
| 8 | Masquerade DNS to MikroTik AdGuard | srcnat | masquerade | 192.168.31.0/24 | 172.17.0.2 | 53/udp |
| 9 | Masquerade DNS to MikroTik AdGuard TCP | srcnat | masquerade | 192.168.31.0/24 | 172.17.0.2 | 53/tcp |
| 34 | Masquerade VLAN DNS to AdGuard | srcnat | masquerade | src-address-list=all-vlans | 172.17.0.2 | 53/udp |
| 35 | Masquerade VLAN DNS to AdGuard TCP | srcnat | masquerade | src-address-list=all-vlans | 172.17.0.2 | 53/tcp |
## Filter Rules (forward - allow DNS)
| # | Comment | Chain | Action | Src Address List | Dst Address | Dst Port |
|---|---------|-------|--------|------------------|-------------|----------|
| 12 | VLAN: IoT to DNS | forward | accept | vlan-iot | 192.168.31.1 | 53/udp |
| 14 | VLAN: IoT to DNS TCP | forward | accept | vlan-iot | 192.168.31.1 | 53/tcp |
| 16 | VLAN: Cameras to DNS | forward | accept | vlan-cameras | 192.168.31.1 | 53/udp |
| 18 | VLAN: Guest to DNS | forward | accept | vlan-guest | 192.168.31.1 | 53/udp |
| 51 | VLAN: Kids to DNS | forward | accept | vlan-kids | 192.168.31.1 | 53/udp |
## Re-enable Commands
When ready to restore DNS redirect to AdGuard:
```routeros
# Enable NAT redirect rules
/ip firewall nat enable [find comment~"Redirect DNS" or comment~"Masquerade DNS"]
# Note: Filter rules (VLAN to DNS) should remain enabled - they just allow traffic
```
## Notes
- Rules 27, 28, 32, 33 are the main redirect rules that force DNS through AdGuard
- Rules 8, 9, 34, 35 are masquerade rules needed for AdGuard container to work
- Rules 3, 25, 26 allow AdGuard containers to make outbound DNS queries
- Filter rules 12, 14, 16, 18, 51 allow VLAN devices to reach DNS - these are OK to keep