diff --git a/docs/pfi/headscale-mesh-plan.md b/docs/pfi/headscale-mesh-plan.md index caae0c1..be2b8ac 100644 --- a/docs/pfi/headscale-mesh-plan.md +++ b/docs/pfi/headscale-mesh-plan.md @@ -296,3 +296,20 @@ persistent — not done. consume one (so the routers can't be used to test egress; use the laptop/iPad). Replaces the nh3-dev SOCKS5 residential-egress proxy — retire that once confirmed on real clients. + +## 2026-09-06 — selective masquerade applied (supersedes the SNAT-reversal note above) + +Restored `--snat-subnet-routes=false` (NoSNAT=true) on all three routers AND added a +persistent selective-masquerade rule, so BOTH properties now hold: exit nodes work (internet +egress masqueraded) and site-to-site keeps the original host source. + +Per router: `/usr/local/sbin/mesh-exit-masq.sh` + `mesh-exit-masq.service` (oneshot, After +tailscaled, enabled). Rule = a `MESH-EXIT` nat chain jumped from POSTROUTING for +`-s 100.64.0.0/10 -o eth0`: RETURN for 10/8, 172.16/12, 192.168/16, 100.64/10 (source +preserved), MASQUERADE the rest (real internet). ⚠ nf_tables iptables forbids multiple `-d` +in one rule — hence the chain-with-RETURNs shape, not a single `! -d ... ! -d ...` rule. + +Verified: nh3-docker→ana-docker seen at colo as **10.100.50.40** (real host, preserved); +nh3-dev via ana-scale exit → egress **38.120.12.42** (colo), via nh3-scale → 70.230.226.88 +(NH3). Persistent across CT reboot via the systemd unit. `tailscale set --operator` NOT set; +drive nh3-dev's tailscale via `ssh infra-ops@10.100.10.50 sudo tailscale ...`. diff --git a/persistent-memory.d/2026-09-06-headscale-cutover.md b/persistent-memory.d/2026-09-06-headscale-cutover.md index 4850ef2..bc1fc0d 100644 --- a/persistent-memory.d/2026-09-06-headscale-cutover.md +++ b/persistent-memory.d/2026-09-06-headscale-cutover.md @@ -27,7 +27,7 @@ follow-ups in `docs/pfi/headscale-mesh-plan.md` § CUTOVER EXECUTED. Headlines: ## Exit nodes (2026-09-06, operator-requested) All three routers advertise+serve exit nodes (approved). Clients pick location: `tailscale set --exit-node=nh3-scale|esh-scale|ana-scale`. NH3 = residential egress -(70.230.226.88) → replaces the nh3-dev SOCKS5 proxy. ⚠ Enabling exit nodes REQUIRED flipping -`--snat-subnet-routes=true` (reversed the source-preserving NoSNAT); cross-site traffic now -shows the router IP as source. A node advertising an exit node can't consume one — test from +(70.230.226.88) → replaces the nh3-dev SOCKS5 proxy. Exit nodes + source preservation BOTH work via a selective-masquerade rule (NoSNAT kept true; +`mesh-exit-masq.service` per router masquerades only internet-bound exit traffic, RETURNs fleet +dests). Verified: colo sees real NH3 host; nh3-dev via colo exit → egress 38.120.12.42. A node advertising an exit node can't consume one — test from the laptop/iPad, not the routers.