Skip to content

v1.0.20

Choose a tag to compare

@github-actions github-actions released this 24 May 07:10
· 29 commits to main since this release

v1.0.20 — IPv6 enablement + 4.9 reconcile + watchdog fixes

The kill switch now blocks IPv6 leaks alongside IPv4, the masquerade fixes cover both families, and the plugin now closes a silent IPv6 failure mode that hit pre-4.9 fw3 routers acting as Tailscale exit nodes.

IPv6

  • Kill switch covers IPv6. Both iif br-lan and iif br-guest rules at priority 5280 install for IPv4 AND IPv6, with unreachable default in table 100 for both families. Verified zero leak on tailscaled death on AXT1800 4.8.4 fw4 and MT3000 4.9.0 fw3.
  • masq6 on tailscale0. Without IPv6 masquerade on the Tailscale zone, forwarded LAN/guest IPv6 enters the exit-node tunnel with an unrecognized Tailscale ULA source and gets dropped. Now set automatically alongside the existing masq (IPv4).
  • Exit-node-server IPv6 SNAT backstop. When advertising as a Tailscale exit node on pre-4.9 firmware, the plugin now ensures wan.masq6=1 as a defense-in-depth safety net. Tailscale's own ts-postrouting IPv6 chain is empty on iptables-based firmware (verified empirically — likely a Tailscale-side iptables-backend gap), so IPv6 egress for tailnet clients using this router as an exit node depends entirely on GL's wan.masq6 setting. GL generally sets this on its own; the plugin guarantees it in case GL's defaults vary by model or firmware variant. A sidecar UCI flag (wan_masq6_set_by_plugin) tracks ownership so teardown only undoes what we set — user or GL-set values are never trampled. On firmware 4.9+ the plugin defers entirely; GL owns this surface.
  • Status reporting fixed. get_config's kill_switch_fw_active and masquerade_active now report true only when BOTH families are configured — a torn install no longer falsely reports full protection.

Robustness

  • Watchdog idempotent teardown. The Tailscale-disabled check now fires on any poll where TS is off AND KS rules are still installed, replacing the prior transition-based check. Catches the fast 1→0→1 sequence (TS disabled and re-enabled inside the same 5-second poll window) that the old logic silently missed, leaving the KS rules orphaned. Verified empirically on AXT1800 4.8.3 2026-04-25.
  • GL 4.9 Custom Exit Node reconcile. When firmware 4.9 sets tailscale.settings.exit_node_ip but the daemon's ExitNodeID is still empty (table 52 has no default route, traffic exits the WAN), the plugin now runs tailscale set --exit-node=<ip> to reconcile. Gated by a value-snapshot (last_seen_exit_node_ip): only fires when the watched value actually changes since the previous reapply, so unrelated GL UCI commits don't trigger a wrong reconcile on a stale exit-node IP.
  • Masquerade deferral on 4.9+. GL firmware 4.9 owns the IP Masquerading toggle natively under the Tailscale page's NAT section. The plugin no longer fights GL's setting on 4.9+ — ensure_masquerade() is gated on pre-4.9, and pkg/prerm skips deleting tailscale0.masq/masq6 on 4.9+ so we don't trample GL's state during uninstall.

Minor

  • Cache-busting on the injected JS. The body filter now stamps ?v=<version> on the <script> tag URL so browsers re-fetch ts-fix.js after a plugin upgrade. Removes the "stale version badge until a hard refresh" annoyance.

Known limitation on firmware 4.9+

On 4.9+ the plugin no longer overrides GL's masquerade settings. If you have both IP Masquerading and Allow Remote Access LAN turned off on the Tailscale page, GL may leave the tailscale0 zone without IPv6 masquerade, in which case LAN-side IPv6 will not traverse the exit-node tunnel. Enable either setting and IPv6 works. The kill switch still protects on 4.9 regardless of masquerade state.

Closes

  • #11 (j0hnsmith) — IPv6 kill switch

Full Changelog: v1.0.19...v1.0.20