liminix-fork/pkgs/firewallgen/default.nix

58 lines
1.5 KiB
Nix

{
nftables
, writeScript
, lib
} :
name : ruleset :
let
inherit (lib.strings) concatStringsSep splitString hasInfix substring;
inherit (lib.lists) groupBy;
inherit (lib.attrsets) mapAttrsToList nameValuePair;
inherit (builtins) map listToAttrs replaceStrings head tail;
indentLines = offset : lines :
if lines == []
then ""
else
let
line = head lines;
isOpen = hasInfix "{" line;
isClose = hasInfix "}" line;
offset' = offset +
(if isOpen then 4 else 0) +
(if isClose then -4 else 0);
padding = offset: substring 0 offset " ";
in
if (isClose && !isOpen)
then
(padding offset') + line + "\n" + indentLines offset' (tail lines)
else
(padding offset) + line + "\n" + indentLines offset' (tail lines);
indent = text : indentLines 0 (splitString "\n" text);
dochain = { name, type, family, rules, policy ? null, hook ? null } : ''
chain ${name} {
${if hook != null
then "type ${type} hook ${hook}; policy ${policy};"
else ""
}
${concatStringsSep "\n" rules}
}
'';
dotable = family : chains : ''
table ${family} ${family} {
${concatStringsSep "\n" (map dochain chains)}
}
'';
categorise = chains :
groupBy
({ family, ... } : family)
(mapAttrsToList (n : v : v // { name = n; }) chains);
in writeScript name ''
#!${nftables}/sbin/nft -cf
flush ruleset
${indent (concatStringsSep "\n" (mapAttrsToList dotable (categorise ruleset)))}
''