From 65878135776e1a1955b7d6b8887448b5d46df674 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Thu, 6 Feb 2025 11:57:06 +0000 Subject: [PATCH] WIP add zones to firewall module - zones are an attrset of name -> [interface-service] - the firewall will create empty "ifname" sets for each zone name in each address family (ip, ip6) - then watch the interface services, and add the "ifname" outputs to the corresponding sets when they appear This commit only adds the empty sets --- examples/rotuer.nix | 4 ++++ modules/firewall/default-rules.nix | 16 ---------------- modules/firewall/default.nix | 10 ++++++++++ modules/firewall/service.nix | 28 ++++++++++++++++++++++------ modules/profiles/gateway.nix | 4 ++++ 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/examples/rotuer.nix b/examples/rotuer.nix index 1d2a726..78251e2 100644 --- a/examples/rotuer.nix +++ b/examples/rotuer.nix @@ -69,6 +69,10 @@ in rec { firewall = { enable = true; rules = secrets.firewallRules; + zones = { + lan = [ config.services.int ]; + wan = [ config.services.wan ] ; + }; }; wireless.networks = { # EDIT: if you have more or fewer wireless radios, here is where diff --git a/modules/firewall/default-rules.nix b/modules/firewall/default-rules.nix index e8ee4d0..dcb62aa 100644 --- a/modules/firewall/default-rules.nix +++ b/modules/firewall/default-rules.nix @@ -3,13 +3,6 @@ let accept = expr : "${expr} accept"; mcast-scope = 8; allow-incoming = false; - - ifname-set = family : name : ifnames : { - kind = "set"; - inherit family name; - type = "ifname"; - elements = ifnames; - }; in { bogons-ip6 = { type = "filter"; @@ -248,13 +241,4 @@ in { ]; }; - lan-set-ip = ifname-set "ip" "lan" [ "int" ]; - wan-set-ip = ifname-set "ip" "wan" [ "ppp0" ]; - dmz-set-ip = ifname-set "ip" "dmz" [ ]; - guest-set-ip = ifname-set "ip" "guest" [ ]; - - lan-set-ip6 = ifname-set "ip6" "lan" [ "int" ]; - wan-set-ip6 = ifname-set "ip6" "wan" [ "ppp0" ]; - dmz-set-ip6 = ifname-set "ip6" "dmz" [ ]; - guest-set-ip6 = ifname-set "ip6" "guest" [ ]; } diff --git a/modules/firewall/default.nix b/modules/firewall/default.nix index 539eba5..03ff1d9 100644 --- a/modules/firewall/default.nix +++ b/modules/firewall/default.nix @@ -60,6 +60,16 @@ in description = "firewall ruleset"; default = {}; }; + zones = mkOption { + type = types.attrsOf (types.listOf liminix.lib.types.service); + default = {}; + example = lib.literalExpression '' + { + lan = with config.hardware.networkInterfaces; [ int ]; + wan = [ config.services.ppp0 ]; + } + ''; + }; rules = mkOption { type = types.attrsOf types.attrs; # we could usefully tighten this a bit :-) default = import ./default-rules.nix; diff --git a/modules/firewall/service.nix b/modules/firewall/service.nix index 9bb022f..ca8431e 100644 --- a/modules/firewall/service.nix +++ b/modules/firewall/service.nix @@ -4,12 +4,28 @@ , firewallgen , nftables }: -{ rules, extraRules }: +{ rules, extraRules, zones }: let - inherit (liminix.services) oneshot; - script = firewallgen "firewall.nft" (lib.recursiveUpdate rules extraRules); -in oneshot { + inherit (liminix.services) longrun ; # oneshot; + inherit (lib.attrsets) mapAttrs' nameValuePair; + mkSet = family : name : + nameValuePair + "${name}-set-${family}" + { + kind = "set"; + inherit name family; + type = "ifname"; + }; + sets = (mapAttrs' (n : _ : mkSet "ip" n) zones) // + (mapAttrs' (n : _ : mkSet "ip6" n) zones); + allRules = lib.recursiveUpdate extraRules (lib.recursiveUpdate (builtins.trace sets sets) rules); + script = firewallgen "firewall1.nft" allRules; + +in longrun { name = "firewall"; - up = script; - down = "${nftables}/bin/nft flush ruleset"; + run = '' + ${script} + while : ; do sleep 86400 ; done + ''; + finish = "${nftables}/bin/nft flush ruleset"; } diff --git a/modules/profiles/gateway.nix b/modules/profiles/gateway.nix index ef6eca6..1e0ae48 100644 --- a/modules/profiles/gateway.nix +++ b/modules/profiles/gateway.nix @@ -48,6 +48,9 @@ in { firewall = { enable = mkEnableOption "firewall"; rules = mkOption { type = types.attrsOf types.attrs; }; + zones = mkOption { + type = types.attrsOf (types.listOf liminix.lib.types.service); + }; }; wan = { @@ -143,6 +146,7 @@ in { services.firewall = mkIf cfg.firewall.enable (svc.firewall.build { extraRules = cfg.firewall.rules; + inherit (cfg.firewall) zones; }); services.resolvconf = oneshot rec {