diff options
author | Maciej Krüger <mkg20001@gmail.com> | 2023-03-27 19:52:19 +0200 |
---|---|---|
committer | Maciej Krüger <mkg20001@gmail.com> | 2023-08-28 00:40:20 +0200 |
commit | 55213b54f0ebb96250021a8788e36126174ca8a7 (patch) | |
tree | c0399e5605ae6a309c312d050323b1c56c681f30 /nixos/modules/services/networking/nftables.nix | |
parent | 5f300ad70cbbb7192f5a86795c37ed99d70ab545 (diff) | |
download | nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.tar nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.tar.gz nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.tar.bz2 nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.tar.lz nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.tar.xz nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.tar.zst nixlib-55213b54f0ebb96250021a8788e36126174ca8a7.zip |
nixos/nftables: save deletions to file and run them afterwards
Co-authored-by: duament
Diffstat (limited to 'nixos/modules/services/networking/nftables.nix')
-rw-r--r-- | nixos/modules/services/networking/nftables.nix | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/nixos/modules/services/networking/nftables.nix b/nixos/modules/services/networking/nftables.nix index b238f09df2f3..2107448131ec 100644 --- a/nixos/modules/services/networking/nftables.nix +++ b/nixos/modules/services/networking/nftables.nix @@ -85,6 +85,22 @@ in networking.nftables.flushRuleset = mkEnableOption (lib.mdDoc "Flush the entire ruleset on each reload."); + networking.nftables.extraDeletions = mkOption { + type = types.lines; + default = ""; + example = '' + # this makes deleting a non-existing table a no-op instead of an error + table inet some-table; + + delete table inet some-table; + ''; + description = + lib.mdDoc '' + Extra deletion commands to be run on every firewall start, reload + and after stopping the firewall. + ''; + }; + networking.nftables.ruleset = mkOption { type = types.lines; default = ""; @@ -134,6 +150,10 @@ in lib.mdDoc '' The ruleset to be used with nftables. Should be in a format that can be loaded using "/bin/nft -f". The ruleset is updated atomically. + Note that if the tables should be cleaned first, either: + - networking.nftables.flushRuleset = true; needs to be set (flushes all tables) + - networking.nftables.extraDeletions needs to be set + - or networking.nftables.tables can be used, which will clean up the table automatically ''; }; networking.nftables.rulesetFile = mkOption { @@ -218,15 +238,36 @@ in reloadIfChanged = true; serviceConfig = let enabledTables = filterAttrs (_: table: table.enable) cfg.tables; + deletionsScript = pkgs.writeScript "nftables-deletions" '' + #! ${pkgs.nftables}/bin/nft -f + ${if cfg.flushRuleset then "flush ruleset" + else concatStringsSep "\n" (mapAttrsToList (_: table: '' + table ${table.family} ${table.name} + delete table ${table.family} ${table.name} + '') enabledTables)} + ${cfg.extraDeletions} + ''; + deletionsScriptVar = "/var/lib/nftables/deletions.nft"; + ensureDeletions = pkgs.writeShellScript "nftables-ensure-deletions" '' + touch ${deletionsScriptVar} + chmod +x ${deletionsScriptVar} + ''; + saveDeletionsScript = pkgs.writeShellScript "nftables-save-deletions" '' + cp ${deletionsScript} ${deletionsScriptVar} + ''; + cleanupDeletionsScript = pkgs.writeShellScript "nftables-cleanup-deletions" '' + rm ${deletionsScriptVar} + ''; rulesScript = pkgs.writeTextFile { name = "nftables-rules"; executable = true; text = '' #! ${pkgs.nftables}/bin/nft -f - ${optionalString cfg.flushRuleset "flush ruleset"} + # previous deletions, if any + include "${deletionsScriptVar}" + # current deletions + include "${deletionsScript}" ${concatStringsSep "\n" (mapAttrsToList (_: table: '' - table ${table.family} ${table.name} - delete table ${table.family} ${table.name} table ${table.family} ${table.name} { ${table.content} } @@ -237,6 +278,7 @@ in ''; checkPhase = lib.optionalString cfg.checkRuleset '' cp $out ruleset.conf + sed 's|include "${deletionsScriptVar}"||' -i ruleset.conf ${cfg.preCheckRuleset} export NIX_REDIRECTS=/etc/protocols=${pkgs.buildPackages.iana-etc}/etc/protocols:/etc/services=${pkgs.buildPackages.iana-etc}/etc/services LD_PRELOAD="${pkgs.buildPackages.libredirect}/lib/libredirect.so ${pkgs.buildPackages.lklWithFirewall.lib}/lib/liblkl-hijack.so" \ @@ -246,13 +288,11 @@ in in { Type = "oneshot"; RemainAfterExit = true; - ExecStart = rulesScript; - ExecReload = rulesScript; - ExecStop = "${pkgs.nftables}/bin/nft ${ - if cfg.flushRuleset then "flush ruleset" - else escapeShellArg (concatStringsSep "; " ( - mapAttrsToList (_: table: "delete table ${table.family} ${table.name}") enabledTables - ))}"; + ExecStart = [ ensureDeletions rulesScript ]; + ExecStartPost = saveDeletionsScript; + ExecReload = [ rulesScript saveDeletionsScript ]; + ExecStop = [ deletionsScriptVar cleanupDeletionsScript ]; + StateDirectory = "nftables"; }; }; }; |