commit 65878135776e1a1955b7d6b8887448b5d46df674
parent 1d780de0f1cc8146d7de55b35c04db2390b14b21
Author: Daniel Barlow <dan@telent.net>
Date: Thu, 6 Feb 2025 11:57:06 +0000
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
Diffstat:
5 files changed, 40 insertions(+), 22 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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 {