Approved in the Tailscale admin console, so xtrm-unraid now shows as "offers exit node" and appears in tailscale exit-node list. The tailnet has two exit nodes: mikrotik-tailscale (primary) and xtrm-unraid (fallback). Neither has been exercised from the Mac. Noted that without --exit-node-allow-lan-access an exit node cuts the client's own LAN access, which would break an SSH session routed over Tailscale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
11 KiB
MikroTik Tailscale Container Setup
Last Updated: 2026-02-06
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
/interface veth add address=172.17.0.3/24 gateway=172.17.0.1 name=veth-tailscale
Gateway IP on Interface
/ip address add address=172.17.0.1/24 interface=veth-tailscale comment="Tailscale container gateway"
NAT Masquerade for Internet Access
/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
/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
/container mounts add list=ts-state src=usb1/tailscale dst=/var/lib/tailscale
Create Environment Variables
/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
/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
/container print
View Logs
/log print where topics~"container" and message~"tailscale"
Start/Stop Container
/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:
/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:
- Verify gateway IP on veth interface:
/ip address print where interface=veth-tailscale
- Verify NAT masquerade rule:
/ip firewall nat print where src-address=172.17.0.0/24
Container Not Connecting to Tailscale
- Check DNS resolution works (logs should show no timeout)
- Verify auth key is valid and not expired
- 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.69 | xtrm-unraid (Unraid plugin, offers exit node) | Online |
| 100.100.208.70 | xtrm-unraid (old node, deleted 2026-11-03) | Removed |
| 100.112.103.7 | hapax3 (old native install) | Offline |
| 100.75.93.123 | mikrotik-tailscale (previous container) | Offline |
Important Notes
-
Userspace Networking Required: MikroTik containers don't have /dev/net/tun access, so TS_USERSPACE=true is mandatory
-
Auth Key: After initial authentication, the key is no longer needed - state is persisted in the mount
-
Container Network: Both AdGuard and Tailscale share the 172.17.0.0/24 network but have separate veth interfaces
-
Accept Routes: If subnet routing is needed, add TS_EXTRA_ARGS="--accept-routes" to environment
Unraid Tailscale Plugin Node — 2026-11-03
The Unraid server runs its own Tailscale node via the Tailscale plugin (not a container), separate from the MikroTik container documented above. It had been logged out since roughly May 2026 and was re-enrolled on 2026-11-03.
| Item | Value |
|---|---|
| Tailscale IP | 100.100.208.69 |
| MagicDNS name | xtrm-unraid.tailf789e1.ts.net |
| Daemon | /usr/local/sbin/tailscaled 1.96.2, -tun tailscale1 |
| State dir | /boot/config/plugins/tailscale/state (survives reboot) |
| Previous IP | 100.100.208.70 — stale node deleted, so a new IP was issued |
Prefs set
| Pref | Value | Reason |
|---|---|---|
--advertise-routes |
none | The old 192.168.31.0/24 advertisement was dropped. That subnet is only the macvlan shim (br0-shim holds 192.168.31.250/32 with one host route to 192.168.31.4) — nothing reachable lives there. |
| LAN subnet routing | not advertised | The MikroTik container is primary for 192.168.10.0/24, .20, .25, .30. A second advertiser for a subnet Unraid itself sits on would create a routing conflict. |
--advertise-exit-node |
on | Redundant with the hAP today, kept as a fallback on the 24/7 box. Approved in the admin console 2026-11-03 — shows as offers exit node and appears in tailscale exit-node list. |
--accept-routes |
false | Critical. Unraid is on 192.168.10.0/24; accepting the hAP's route for its own subnet would loop. This is why tailscale status reports the health warning "Some peers are advertising routes but --accept-routes is false" — expected here, not a fault. |
--accept-dns |
false | Keeps local AdGuard resolution intact (Unraid AdGuard is config master). |
--ssh |
on | Tailscale SSH. Needed — see the sshd caveat below. |
SSH over Tailscale — the sshd caveat
/etc/ssh/sshd_config on Unraid binds explicitly and has no wildcard:
Port 422
ListenAddress 192.168.10.20 # br0
ListenAddress 192.168.31.250 # br0-shim
So sshd does not listen on 100.100.208.69. Port 422 on the Tailscale IP is
closed and stays closed unless a ListenAddress is added — which needs a go
script, because Unraid regenerates this file per interface at every boot.
Access on the Tailscale IP is served by Tailscale SSH on port 22, handled by
tailscaled itself and authenticated by tailnet identity rather than by an SSH
key:
# direct, independent of the MikroTik subnet router
ssh root@100.100.208.69
ssh root@xtrm-unraid.tailf789e1.ts.net
# port forward — verified 2026-11-03 (Unraid web UI returned HTTP 302)
ssh -N -L 18089:127.0.0.1:80 root@100.100.208.69
The default tailnet ACL uses action: "check", so the first connection in each
period opens a browser re-auth prompt. Fine interactively, but it will stall an
unattended tunnel; switching that rule to accept for autogroup:self in the
admin console removes the prompt.
The other path — via the MikroTik subnet router
Independent of the Unraid node and still working:
ssh -i ~/.ssh/id_ed25519_unraid -p 422 -N -L 18088:127.0.0.1:80 root@192.168.10.20
Forwarding works here only because Unraid's stock sshd config denies it globally and re-enables it for root alone:
AllowTcpForwarding no # limetech - disallow forwarding but see below
...
Match Group root
AllowTcpForwarding yes # limetech - permit only root SSH tunneling
Any non-root account added later will not be able to open tunnels.
Exit node
Approved 2026-11-03. The tailnet now has two exit nodes:
| IP | Node |
|---|---|
100.74.219.35 |
mikrotik-tailscale (primary) |
100.100.208.69 |
xtrm-unraid (fallback, 24/7 box) |
Select one with tailscale set --exit-node=xtrm-unraid. Not exercised in anger
yet — note that without --exit-node-allow-lan-access an exit node cuts the
client's own LAN access, which will break an SSH session that is itself routed
over Tailscale.