From 4c589b8d0c083a85bd41fb2a4ef7782623aac9ff Mon Sep 17 00:00:00 2001 From: kurogeek Date: Wed, 16 Sep 2026 08:30:14 +0000 Subject: [PATCH] router: allow SSH on the staging port The staging uplink is in no VLAN zone and was fully default-deny; admit TCP 22 on it so the box is reachable from the old LAN before the mgmt VLAN or the mesh are up. Everything else on the port stays closed. --- modules/clan/router/firewall.nix | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/clan/router/firewall.nix b/modules/clan/router/firewall.nix index 4555fcb..f41b0a8 100644 --- a/modules/clan/router/firewall.nix +++ b/modules/clan/router/firewall.nix @@ -3,6 +3,7 @@ # other VLANs -> DNS/DHCP on the router + WAN (if allowWan); no inter-VLAN # WAN (ppp0) -> nothing inbound beyond established/related # mesh -> admin SSH + metrics scrapes (same trust boundary as the fleet) +# staging -> admin SSH only (pre-cutover uplink into the old LAN) { settings }: { lib, ... }: let @@ -26,14 +27,20 @@ in filterForward = true; trustedInterfaces = [ "vlan-mgmt" ]; - # Non-mgmt VLANs may only talk to the router's DNS and DHCP. - interfaces = lib.genAttrs nonMgmtIfs (_: { - allowedTCPPorts = [ 53 ]; - allowedUDPPorts = [ - 53 - 67 - ]; - }); + # Non-mgmt VLANs may only talk to the router's DNS and DHCP; the staging + # uplink (old LAN, pre-cutover) gets admin SSH so the box can be reached + # before the mgmt VLAN or the mesh are up. + interfaces = + lib.genAttrs nonMgmtIfs (_: { + allowedTCPPorts = [ 53 ]; + allowedUDPPorts = [ + 53 + 67 + ]; + }) + // lib.optionalAttrs (cfg.stagingPort != null) { + ${cfg.stagingPort}.allowedTCPPorts = [ 22 ]; + }; extraInputRules = '' ip6 saddr ${cfg.mesh.subnet} tcp dport 22 accept comment "admin ssh over the mesh"