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"