From e5e76871bbd77b4101991126d47ef8808d3a4b22 Mon Sep 17 00:00:00 2001 From: XTRM-Unraid Date: Sun, 25 Jan 2026 15:33:34 +0200 Subject: [PATCH] Add Tailscale container and bridge setup - Added mikrotik-containers-bridge-setup.rsc for shared container networking - Added mikrotik-tailscale-setup.rsc for Tailscale container - Added docs/10-MIKROTIK-TAILSCALE.md with full documentation - Both containers now use containers-br bridge (172.17.0.1/24) - AdGuard: 172.17.0.2, Tailscale: 172.17.0.3 --- docs/00-CHANGELOG.md | 8 + docs/10-MIKROTIK-TAILSCALE.md | 146 +++++++++++++++++++ scripts/mikrotik-containers-bridge-setup.rsc | 43 ++++++ scripts/mikrotik-tailscale-setup.rsc | 65 +++++++++ 4 files changed, 262 insertions(+) create mode 100644 docs/10-MIKROTIK-TAILSCALE.md create mode 100644 scripts/mikrotik-containers-bridge-setup.rsc create mode 100644 scripts/mikrotik-tailscale-setup.rsc diff --git a/docs/00-CHANGELOG.md b/docs/00-CHANGELOG.md index dc633d0..e53e8f8 100644 --- a/docs/00-CHANGELOG.md +++ b/docs/00-CHANGELOG.md @@ -94,3 +94,11 @@ For detailed history before 2026-01-17, see archived changelogs: - Fix: Removed and recreated container, added mountlists, restarted - AdGuard config preserved (on separate mount) - Documented fix in 09-MIKROTIK-ADGUARD-DOT-DOH.md +- [CONTAINERS] Created container bridge (containers-br) for shared networking + - Both AdGuard and Tailscale containers now use the same bridge + - Added NAT masquerade for container outbound traffic +- [SERVICE] Tailscale container installed and running + - Image: tailscale/tailscale:latest + - IP: 172.17.0.3/24 on veth-tailscale + - State persisted to usb1/tailscale/state + - Userspace mode enabled diff --git a/docs/10-MIKROTIK-TAILSCALE.md b/docs/10-MIKROTIK-TAILSCALE.md new file mode 100644 index 0000000..ae2a342 --- /dev/null +++ b/docs/10-MIKROTIK-TAILSCALE.md @@ -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 diff --git a/scripts/mikrotik-containers-bridge-setup.rsc b/scripts/mikrotik-containers-bridge-setup.rsc new file mode 100644 index 0000000..017ab59 --- /dev/null +++ b/scripts/mikrotik-containers-bridge-setup.rsc @@ -0,0 +1,43 @@ +# MikroTik Container Bridge Setup Script +# Created: 2026-01-25 +# Repository: https://git.xtrm-lab.org/jazzymc/infrastructure +# +# Run this FIRST before setting up containers +# Creates shared bridge for all containers + +#------------------------------------------------------------ +# Variables +#------------------------------------------------------------ +:local bridgeName "containers-br" +:local bridgeIP "172.17.0.1" +:local bridgeNet "172.17.0.0/24" +:local wanInterface "eth1_WAN" + +#------------------------------------------------------------ +# 1. Create bridge for containers +#------------------------------------------------------------ +/interface bridge add name=$bridgeName + +#------------------------------------------------------------ +# 2. Add IP address to bridge +#------------------------------------------------------------ +/ip address add address=$bridgeIP/24 interface=$bridgeName + +#------------------------------------------------------------ +# 3. Firewall - Allow container network traffic +#------------------------------------------------------------ +# Input chain +/ip firewall filter add chain=input action=accept dst-address=$bridgeNet comment="Allow container network" +/ip firewall filter add chain=input action=accept src-address=$bridgeNet comment="Allow from container network" + +# Forward chain +/ip firewall filter add chain=forward action=accept dst-address=$bridgeNet comment="Allow to container network" +/ip firewall filter add chain=forward action=accept src-address=$bridgeNet comment="Allow from container network" + +#------------------------------------------------------------ +# 4. NAT - Masquerade for container outbound traffic +#------------------------------------------------------------ +/ip firewall nat add chain=srcnat action=masquerade src-address=$bridgeNet out-interface=$wanInterface comment="Container outbound NAT" + +:log info "Container bridge setup complete" +:log info "Bridge: $bridgeName with IP $bridgeIP/24" diff --git a/scripts/mikrotik-tailscale-setup.rsc b/scripts/mikrotik-tailscale-setup.rsc new file mode 100644 index 0000000..24f161a --- /dev/null +++ b/scripts/mikrotik-tailscale-setup.rsc @@ -0,0 +1,65 @@ +# MikroTik Tailscale Setup Script +# Created: 2026-01-25 +# Repository: https://git.xtrm-lab.org/jazzymc/infrastructure +# +# Prerequisites: +# - RouterOS 7.4+ with container package +# - USB storage mounted as usb1 +# - Container mode enabled: /system/device-mode/update container=yes +# - containers-br bridge already exists (from adguard setup) + +#------------------------------------------------------------ +# Variables +#------------------------------------------------------------ +:local containerName "tailscale" +:local containerImage "tailscale/tailscale:latest" +:local vethName "veth-tailscale" +:local containerIP "172.17.0.3" +:local gatewayIP "172.17.0.1" +:local containerBridge "containers-br" + +#------------------------------------------------------------ +# 1. Create veth interface +#------------------------------------------------------------ +/interface veth add name=$vethName address=$containerIP/24 gateway=$gatewayIP + +#------------------------------------------------------------ +# 2. Add veth to container bridge +#------------------------------------------------------------ +/interface bridge port add bridge=$containerBridge interface=$vethName + +#------------------------------------------------------------ +# 3. Create container mount for state persistence +#------------------------------------------------------------ +/container/mounts/add list=ts-state src=usb1/tailscale/state dst=/var/lib/tailscale + +#------------------------------------------------------------ +# 4. 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 + +#------------------------------------------------------------ +# 5. Create container +#------------------------------------------------------------ +/container/add remote-image=$containerImage interface=$vethName \ + root-dir=usb1/tailscale/root logging=yes start-on-boot=yes \ + dns=8.8.8.8 name=$containerName + +# Wait for image extraction +:log info "Waiting for Tailscale image extraction..." +:delay 60s + +#------------------------------------------------------------ +# 6. Add mountlists and envlists to container +#------------------------------------------------------------ +/container/set [find name=$containerName] mountlists=ts-state envlists=ts-env + +#------------------------------------------------------------ +# 7. Start container +#------------------------------------------------------------ +/container/start [find name=$containerName] + +:log info "Tailscale container started" +:log info "Check logs for authentication URL: :log print where message~\"login.tailscale\""