From 27f5a7d5af79d92eda4207cd6b368b5ed100a385 Mon Sep 17 00:00:00 2001 From: Kaloyan Danchev Date: Tue, 3 Nov 2026 23:03:47 +0200 Subject: [PATCH] docs: Tailscale SSH ACL set to accept Tailnet SSH policy changed from the default action:"check" to accept. The effective policy is now a single rule covering all tailnet nodes, with no expiry and port forwarding allowed, so the per-device ~12h grants and the browser re-auth prompt are gone. Verified unattended with BatchMode=yes: a plain command, a -L forward returning HTTP 302, and the Herdr fallback leg. Records the trade-off: check acted as a second factor, so a compromised tailnet device now reaches root on Unraid without a further step. Co-Authored-By: Claude Opus 5 --- docs/09-TAILSCALE-VPN.md | 13 +++++++++---- docs/14-HERDR-REMOTE-MACHINES.md | 23 ++++++++++++----------- docs/CHANGELOG.md | 5 +++++ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/09-TAILSCALE-VPN.md b/docs/09-TAILSCALE-VPN.md index 982547d..c991fba 100644 --- a/docs/09-TAILSCALE-VPN.md +++ b/docs/09-TAILSCALE-VPN.md @@ -262,10 +262,15 @@ ssh root@xtrm-unraid.tailf789e1.ts.net 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 tailnet SSH ACL was switched from the default `action: "check"` to +`accept` on 2026-11-03, so this needs no browser re-auth and works unattended. +Before the change the policy minted ~12 h grants per device and prompted when +they lapsed. The effective policy is now a single rule: accept for all tailnet +nodes, with local and remote port forwarding and agent forwarding allowed. + +The trade-off: `check` acted as a second factor, so a compromised tailnet device +now reaches root on Unraid without a further step. Acceptable here because every +node in the tailnet is the owner's own hardware. ### The other path — via the MikroTik subnet router diff --git a/docs/14-HERDR-REMOTE-MACHINES.md b/docs/14-HERDR-REMOTE-MACHINES.md index 911359b..0ffc1d1 100644 --- a/docs/14-HERDR-REMOTE-MACHINES.md +++ b/docs/14-HERDR-REMOTE-MACHINES.md @@ -81,22 +81,23 @@ failed first attempt would consume stdin and corrupt the retry. It costs about 245 ms on the success path. `HERDR_VIA_TARGET=lan|ts` forces a leg for testing; both were verified 2026-11-03. -The fallback leg inherits the tailnet ACL caveat below: with the default -`action: "check"` it works until the grant lapses, then wants a browser -re-auth. Setting that rule to `accept` for `autogroup:self` makes the fallback -fully unattended. +The fallback leg is fully unattended since the tailnet SSH ACL was set to +`accept` on 2026-11-03. Verified the same day with `BatchMode=yes`: a plain +command, a `-L` port forward (HTTP 302 from the Unraid web UI) and the Herdr leg +itself all ran without a prompt. ## Why the LAN address is the primary and not the Tailscale IP `--via` requires a transport that passes bytes untouched and **asks nothing**. -Tailscale SSH on `100.100.208.69` sits behind the default tailnet ACL -`action: "check"`, which demands browser re-authentication each period — fine -interactively, fatal for a long-lived Herdr connection. +When this was set up, Tailscale SSH sat behind the default tailnet ACL +`action: "check"`, which demanded browser re-authentication every ~12 h — fine +interactively, fatal for a long-lived Herdr connection. That ACL was changed to +`accept` on 2026-11-03, so either address would now serve. -Key auth on `192.168.10.20:422` asks nothing, and from outside the LAN it still -travels over Tailscale via the MikroTik subnet router (see -`docs/09-TAILSCALE-VPN.md`). Changing that ACL rule to `accept` for -`autogroup:self` would make the `100.x` address usable here too. +The LAN address stays primary anyway: key auth on `192.168.10.20:422` depends on +nothing but the SSH key, while Tailscale SSH depends on the tailnet policy +staying permissive. From outside the LAN it still travels over Tailscale via the +MikroTik subnet router (see `docs/09-TAILSCALE-VPN.md`), so there is no loss. ## Reboot persistence diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index cbcad8a..7660626 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,6 +13,11 @@ - **[SERVICE]** Exit node advertised from Unraid as a fallback to the hAP, and approved in the Tailscale admin console the same day. The tailnet now has two exit nodes: `mikrotik-tailscale` (100.74.219.35, primary) and `xtrm-unraid` (100.100.208.69, fallback). Neither has been exercised in anger from the Mac — without `--exit-node-allow-lan-access` an exit node cuts the client's own LAN access. - Detail, including the root-only `AllowTcpForwarding` behaviour in Unraid's stock sshd config, in `docs/09-TAILSCALE-VPN.md`. +### Network: Tailscale SSH ACL set to accept +- **[NETWORK]** Tailnet SSH policy changed from Tailscale's default `action: "check"` to `accept` for `autogroup:member` -> `autogroup:self`. Before the change the control plane minted ~12 h per-device grants and prompted for browser re-auth when they lapsed, which would stall any unattended connection. Effective policy is now a single rule: accept for all 10 tailnet nodes, no expiry, with local and remote port forwarding and agent forwarding allowed. +- **[NETWORK]** Verified unattended with `BatchMode=yes`: a plain command over Tailscale SSH, a `-L` port forward (HTTP 302 from the Unraid web UI) and the Herdr fallback leg all ran without a prompt. +- Trade-off recorded in the docs: `check` acted as a second factor, so a compromised tailnet device now reaches root on Unraid without a further step. Accepted because every node in the tailnet is owner-controlled hardware. + ### Tooling: Unraid registered as a Herdr (hc) machine - **[SERVICE]** Unraid added to Herdr as the machine `unraid` (`hc` 0.1.17 on the remote). `herdr-core machine add` had been failing with `core did not start within 5 s`: `hc` puts its core socket under `XDG_RUNTIME_DIR`, which on Unraid is `/run/user/0` — a directory elogind creates and destroys per login session, so the socket disappeared the moment the session that started the core ended. The core kept running with an unlinked socket, and `core.log` stayed empty because the failure is client side. - **[SERVICE]** Fixed from the Mac only, via `~/.local/bin/herdr-via-unraid`, a `--via` transport that exports `XDG_RUNTIME_DIR=/var/run/herdr-rt` on every connection. Nothing on the server was changed. Uses key auth on 192.168.10.20:422 rather than Tailscale SSH, because `--via` needs a transport that asks nothing and the default tailnet ACL `check` would demand periodic browser re-auth.