From 3bb82c2ac68fbb4ef04b0a350c1a072b019970cc Mon Sep 17 00:00:00 2001 From: "quentin@aristote.fr" Date: Sun, 21 May 2023 17:14:39 +0200 Subject: config: networking: firewall: use flowtables --- config/networking/default.nix | 6 +- config/networking/services/firewall/default.nix | 42 +++++++--- config/networking/services/firewall/ruleset.nix | 105 +++++++++++++++--------- 3 files changed, 103 insertions(+), 50 deletions(-) (limited to 'config/networking') diff --git a/config/networking/default.nix b/config/networking/default.nix index eb189eb..3751a02 100644 --- a/config/networking/default.nix +++ b/config/networking/default.nix @@ -51,8 +51,10 @@ in { enable = true; ssh.enable = true; networks = { - lan = { - interface = "enp4s0"; + lan = let device = "enp4s0"; + in { + inherit device; + interface = device; subnet = "192.168.1"; machines = { livebox = { address = "192.168.1.1"; }; diff --git a/config/networking/services/firewall/default.nix b/config/networking/services/firewall/default.nix index 878e7cc..b76174a 100644 --- a/config/networking/services/firewall/default.nix +++ b/config/networking/services/firewall/default.nix @@ -1,7 +1,7 @@ { config, lib, ... }: let - # { any } -> (string -> any -> [ string ]) -> string + # { any } -> (string -> any -> string) -> string mapAttrsStrings = attrs: f: lib.concatStrings (lib.mapAttrsToList f attrs); bracket = title: content: '' @@ -15,16 +15,36 @@ in { networking = { nftables = { enable = true; - ruleset = mapAttrsStrings - (import ./ruleset.nix config.personal.networking.networks) - (family: tables: - mapAttrsStrings tables (tableName: chains: - bracket "table ${family} ${tableName}" (mapAttrsStrings chains - (chainName: chain: - bracket "chain ${chainName}" (lib.optionalString (chain ? base) - (with chain.base; '' - type ${type} hook ${hook} priority ${priority}; policy ${policy}; - '') + chain.rules))))); + ruleset = mapAttrsStrings (import ./ruleset.nix { + inherit lib; + nets = config.personal.networking.networks; + }) (family: tables: + mapAttrsStrings tables (tableName: + { flowtables, chains, ... }: + bracket "table ${family} ${tableName}" ( + mapAttrsStrings flowtables + (flowtableName: flowtable: + bracket "flowtable ${flowtableName}" (with flowtable; + '' + hook ${hook} priority ${priority}; devices = { ${ + lib.concatStringsSep ", " devices + } }; + '' + lib.optionalString offload '' + flags offload; + '' + ) + ) + + mapAttrsStrings chains (chainName: chain: + bracket "chain ${chainName}" ( + lib.optionalString (chain ? base) (with chain.base; '' + type ${type} hook ${hook} priority ${priority}; policy ${policy}; + '') + + chain.rules + ) + ) + ) + ) + ); }; firewall.enable = lib.mkForce false; }; diff --git a/config/networking/services/firewall/ruleset.nix b/config/networking/services/firewall/ruleset.nix index b3e75c7..65ef981 100644 --- a/config/networking/services/firewall/ruleset.nix +++ b/config/networking/services/firewall/ruleset.nix @@ -1,6 +1,21 @@ -{ lan, wan, iot, ... }: +{ lib, nets }: let + makeTable = args: + { + chains = { }; + flowtables = { }; + sets = { }; + maps = { }; + objects = { }; + } // args; + makeFlowtable = args: + { + hook = "ingress"; + priority = "filter"; + devices = [ ]; + offload = false; + } // args; makeBaseChain = type: hook: { priority ? type, policy ? "drop", rules ? "" }: { base = { inherit type hook priority policy; }; @@ -53,54 +68,70 @@ let }; in { ip = { - filter = { - wan_in.rules = with rulesCommon; dns + dhcp + ssh; - iot_in.rules = with rulesCommon; dns + dhcp; - input = makeBaseChain "filter" "input" { - rules = with rulesCommon; - conntrack + ping + '' - meta iifname vmap { lo : accept \ - , ${lan.interface} : drop \ - , ${wan.interface} : goto wan_in \ - , ${iot.interface} : goto iot_in } - ''; + filter = makeTable { + flowtables = { + default = makeFlowtable { + devices = lib.mapAttrsToList (_: { device, ... }: device) nets; + }; }; - forward = makeBaseChain "filter" "forward" { - rules = with rulesCommon; - conntrack + '' - meta oifname ${lan.interface} accept - ''; + chains = { + wan_in.rules = with rulesCommon; dns + dhcp + ssh; + iot_in.rules = with rulesCommon; dns + dhcp; + input = makeBaseChain "filter" "input" { + rules = with rulesCommon; + conntrack + ping + '' + meta iifname vmap { lo : accept \ + , ${nets.lan.interface} : drop \ + , ${nets.wan.interface} : goto wan_in \ + , ${nets.iot.interface} : goto iot_in } + ''; + }; + forward = makeBaseChain "filter" "forward" { + rules = with rulesCommon; + '' + ip protocol { udp, tcp } flow add @default + '' + conntrack + '' + meta oifname ${nets.lan.interface} accept + ''; + }; }; }; - nat = { - postrouting = makeBaseChain "nat" "postrouting" { - priority = "srcnat"; - policy = "accept"; - rules = '' - meta oifname ${lan.interface} snat to ${lan.machines.self.address} - ''; + nat = makeTable { + chains = { + postrouting = makeBaseChain "nat" "postrouting" { + priority = "srcnat"; + policy = "accept"; + rules = '' + meta oifname ${nets.lan.interface} \ + snat to ${nets.lan.machines.self.address} + ''; + }; }; }; }; ip6 = { - global6 = { - input = makeBaseChain "filter" "input" { }; - forward = makeBaseChain "filter" "forward" { }; + global6 = makeTable { + chains = { + input = makeBaseChain "filter" "input" { }; + forward = makeBaseChain "filter" "forward" { }; + }; }; }; bridge = { - filter = { - wan_wan.rules = with rulesCommon; syncthing + kdeconnect; - forward = makeBaseChain "filter" "forward" { - rules = with rulesCommon; - conntrack + '' - ether type vmap { ip6 : drop, arp : accept } - '' + ping + '' - meta ibrname . meta obrname vmap \ - { ${wan.interface} . ${wan.interface} : goto wan_wan } - ''; + filter = makeTable { + chains = { + wan_wan.rules = with rulesCommon; syncthing + kdeconnect; + forward = makeBaseChain "filter" "forward" { + rules = with rulesCommon; + conntrack + '' + ether type vmap { ip6 : drop, arp : accept } + '' + ping + '' + meta ibrname . meta obrname vmap \ + { ${nets.wan.interface} . ${nets.wan.interface} : goto wan_wan } + ''; + }; }; }; }; -- cgit v1.2.3