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.
66 lines
2.2 KiB
Nix
66 lines
2.2 KiB
Nix
# Router firewall/NAT policy (nftables). Trust model:
|
|
# mgmt VLAN -> trusted: router services, all VLANs, WAN
|
|
# 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
|
|
cfg = settings;
|
|
|
|
vlanIfs = lib.mapAttrsToList (name: _: "vlan-${name}") cfg.vlans;
|
|
wanVlanIfs = lib.mapAttrsToList (name: _: "vlan-${name}") (
|
|
lib.filterAttrs (_: vlan: vlan.allowWan) cfg.vlans
|
|
);
|
|
nonMgmtIfs = lib.filter (i: i != "vlan-mgmt") vlanIfs;
|
|
in
|
|
{
|
|
networking.nftables.enable = true;
|
|
|
|
# SSH reachable only from the mgmt VLAN (trusted) and the mesh — never
|
|
# from the WAN or the other VLANs.
|
|
services.openssh.openFirewall = false;
|
|
|
|
networking.firewall = {
|
|
enable = true;
|
|
filterForward = true;
|
|
trustedInterfaces = [ "vlan-mgmt" ];
|
|
|
|
# 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"
|
|
ip6 saddr ${cfg.mesh.subnet} tcp dport 4000 accept comment "blocky metrics scrape from control"
|
|
'';
|
|
|
|
extraForwardRules = ''
|
|
tcp flags syn tcp option maxseg size set rt mtu comment "MSS clamp for PPPoE mtu 1492"
|
|
iifname "vlan-mgmt" accept comment "mgmt reaches all VLANs and the WAN"
|
|
'';
|
|
};
|
|
|
|
# networking.nat both masquerades and opens forward-to-WAN for exactly its
|
|
# internalInterfaces — so this list, not a rule of our own, is where
|
|
# `allowWan` is enforced. Listing every VLAN here would silently let
|
|
# allowWan = false VLANs out.
|
|
networking.nat = {
|
|
enable = true;
|
|
externalInterface = "ppp0";
|
|
internalInterfaces = wanVlanIfs;
|
|
};
|
|
}
|