Commit Graph
2 Commits
Author SHA1 Message Date
vh 959a743256 feat(fv): invert the watchdog to break-glass; fv-ml1 off the mesh
Operator's design, and a better one. Once the FV SNAT rules landed, fv-ml1's
mesh membership was redundant for routing and its only remaining value was as a
second way in. Keeping it enrolled bought a standing second door; joining on
demand buys the same recovery path without one.

  normal    tailscaled stopped + disabled; fleet reached via the gateway SNAT
  fault     nh3-dev / nh3-docker unreachable while the WAN is up
  action    start tailscaled + tailscale up -> reachable at its 100.64.x address

fv-ml1 is now off the mesh and its node record deleted. Verified it still
reaches NH3, ESH, Anaheim, Irvine and the internet on the SNAT path alone, then
the break-glass fired on cue (counted 1..4, joined at 5 as 100.64.0.10),
answered ping and ssh from nh3-dev, and was closed again cleanly.

No auto-leave, deliberately: once open the door stays open until a human runs
systemctl disable --now tailscaled. A watchdog that re-closes on recovery flaps,
and a flapping recovery path is down exactly when someone finally looks. It also
skips entirely when already on the mesh, which is what makes it idempotent after
firing.

The question exposed a hole worth more than the redesign. The stored rejoin key
was one of the 2026-09-12 FV cutover keys, expiring 2026-09-19 -- a break-glass
credential that dies in four days and fails silently at the only moment it
matters. Replaced with a dedicated 1-year reusable key (headscale ID 8, expires
2027-09-15), vaulted as fv-ml1/headscale-breakglass-key, root:600 on the host.

That also closes the standing self-join risk rather than trading it: the two
stale reusable keys (IDs 5, 6) are expired, so the mesh now has exactly one live
reusable key -- purpose-built, on a host we control -- instead of two orphans
nobody owned.

Rejoin uses --accept-routes=false and the reason is in the script: on 2026-09-14
tailscale up --accept-routes on this box accepted its OWN subnet from the
gateway and black-holed it. That happened with a human watching; here it runs
unattended, during an incident, on a box already in trouble.
2026-09-15 01:02:16 -07:00
vh 8c8559b8ec feat(fv): mesh dead-man's switch on fv-ml1; partial progress on FV cross-site routing
WATCHDOG (done, proven). fv-mesh-watchdog probes two independent anchors every
minute and, after 5 consecutive failures, puts Tailscale back to known-good:
accept-routes off, re-up against headscale with a stored key. It touches
nothing else — a watchdog with a wide remit is a second way to lose the box.

Two anchors that cannot share a failure mode: a plain-internet one and a
mesh-only one. If BOTH fail the site uplink is down, Tailscale cannot fix that,
and it deliberately does nothing — thrashing tailscaled during an ISP outage
turns a wait into an incident. Disable file at /etc/fv-watchdog.disable for
planned work.

Proven by positive control, not assumed: counter incremented 1..4 without
acting, fired the restore at 5 (tailscale up ran, tailscaled restarted), and
reset to 0 once the real anchor returned. fv-ml1 stayed reachable throughout.

This exists because a  on fv-ml1 black-holed it
from its own LAN earlier the same day: it accepted 10.251.0.0/16 from the
gateway — its OWN subnet — and routed the local network through the tunnel.

FV CROSS-SITE ROUTING (partial). Two changes landed, the path is still broken:

  1. acceptSubnetRoutes 0 -> 1 on the FV gateway's tailscale plugin, via
     settings/set + service/reconfigure (the documented apply, not a reboot).
     The GATEWAY now has 10.0/16, 10.100/16 and 10.250/16 in its routing table
     and reaches NH3 and ESH itself. It could not before.

  2. Remote-site MASQUERADE rules on nh3-scale. The existing jump matched only
     -s 100.64.0.0/10, so traffic from another site's LAN never entered
     MESH-EXIT and kept its original source; an NH3 host then replied via its
     own LAN router instead of back through nh3-scale, making the path
     asymmetric. The rule is confirmed firing (counter increments on FV
     traffic) but does not complete the path.

Still failing: fv-ml1 -> NH3/ESH LAN addresses. Mesh addresses work perfectly
from fv-ml1 (100.64.0.1, 100.64.0.4), Anaheim works over the metro link, and
the FV firewall log shows the outbound passing on tailscale0 with
src=10.251.50.54 and no reply ever returning. The remaining gap is forwarded
FV-LAN traffic specifically, not the gateway's own.

Full regression sweep clean: nh3-dev, ana-docker and esh-docker-vm all reach
all four sites plus the internet.
2026-09-15 00:25:55 -07:00