firewall: use watch-outputs to track changes in zone->interface map
includes a horrible hack to work around (claimed (by me)) deficiencies in the nftables parser
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
nftables,
|
||||
writeFennel,
|
||||
anoia,
|
||||
svc,
|
||||
lua,
|
||||
output-template,
|
||||
lualinux,
|
||||
linotify,
|
||||
}:
|
||||
@@ -18,14 +21,18 @@ let
|
||||
inherit (lib.attrsets) mapAttrs' nameValuePair mapAttrsToList;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.lists) flatten;
|
||||
inherit (builtins) concatLists attrValues;
|
||||
inherit (liminix) outputRef;
|
||||
mkSet =
|
||||
family: name:
|
||||
nameValuePair "${name}-set-${family}" {
|
||||
kind = "set";
|
||||
inherit name family;
|
||||
type = "ifname";
|
||||
elements = map (s: "{{ output(${builtins.toJSON s}, \"ifname\", \"\") }}") zones.${name};
|
||||
};
|
||||
sets = (mapAttrs' (n: _: mkSet "ip" n) zones) // (mapAttrs' (n: _: mkSet "ip6" n) zones);
|
||||
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;
|
||||
ifwatch = writeFennel "ifwatch" {
|
||||
@@ -37,13 +44,26 @@ let
|
||||
mainFunction = "run";
|
||||
} ./ifwatch.fnl;
|
||||
watchArg = z: intfs: map (i: "${z}:${i}/.outputs") intfs;
|
||||
in
|
||||
longrun {
|
||||
name = "firewall";
|
||||
run = ''
|
||||
${script}
|
||||
PATH=${nftables}/bin:$PATH
|
||||
${ifwatch} ${concatStringsSep " " (flatten (mapAttrsToList watchArg zones))}
|
||||
'';
|
||||
finish = "${nftables}/bin/nft flush ruleset";
|
||||
service = longrun {
|
||||
inherit name;
|
||||
run = ''
|
||||
mkdir -p /run/${name}; in_outputs ${name}
|
||||
# exec > /dev/console 2>&1
|
||||
echo RESTARTING FIREWALL >/dev/console
|
||||
PATH=${nftables}/bin:${lua}/bin:$PATH
|
||||
${output-template}/bin/output-template '{{' '}}' < ${script} | lua -e 'for x in io.lines() do if not string.match(x, "elements = {%s+}") then print(x) end; end' > /run/${name}/fw.nft
|
||||
# cat /run/${name}/fw.nft > /dev/console
|
||||
nft -f /run/${name}/fw.nft
|
||||
while sleep 86400 ; do : ; done
|
||||
'';
|
||||
finish = "${nftables}/bin/nft flush ruleset";
|
||||
};
|
||||
in
|
||||
svc.secrets.subscriber.build {
|
||||
watch =
|
||||
concatLists
|
||||
(mapAttrsToList (_zone : services : map (s: outputRef s "ifname") services) zones);
|
||||
|
||||
inherit service;
|
||||
}
|
||||
|
@@ -13,12 +13,11 @@
|
||||
}:
|
||||
let
|
||||
inherit (liminix.services) oneshot longrun;
|
||||
inherit (builtins) length head toString;
|
||||
inherit (lib) unique optional optionals;
|
||||
inherit (builtins) map length head toString;
|
||||
inherit (lib) unique optional optionals concatStringsSep;
|
||||
inherit (service) name;
|
||||
|
||||
watched-services = unique (map (f: f "service") watch);
|
||||
paths = unique (map (f: f "path") watch);
|
||||
|
||||
restart-flag =
|
||||
{
|
||||
@@ -35,17 +34,11 @@ let
|
||||
}
|
||||
.${action};
|
||||
|
||||
watched-service =
|
||||
if length watched-services == 0 then
|
||||
null
|
||||
else if length watched-services == 1 then
|
||||
head watched-services
|
||||
else
|
||||
throw "cannot subscribe to more than one source service for secrets";
|
||||
|
||||
watcher =
|
||||
let
|
||||
name' = "restart-${name}";
|
||||
refs = concatStringsSep " "
|
||||
(map (s: "${s "service"}:${s "path"}") watch);
|
||||
in
|
||||
longrun {
|
||||
name = name';
|
||||
@@ -55,16 +48,16 @@ let
|
||||
if test -e $dir/notification-fd; then flag="-U"; else flag="-u"; fi
|
||||
${s6}/bin/s6-svwait $flag /run/service/${name} || exit
|
||||
PATH=${s6-rc}/bin:${s6}/bin:$PATH
|
||||
${watch-outputs}/bin/watch-outputs ${restart-flag} ${name} ${watched-service.name} ${lib.concatStringsSep " " paths}
|
||||
${watch-outputs}/bin/watch-outputs ${restart-flag} ${name} ${refs}
|
||||
'';
|
||||
};
|
||||
in
|
||||
service.overrideAttrs (o: {
|
||||
buildInputs = (lim.orEmpty o.buildInputs) ++ optional (watched-service != null) watcher;
|
||||
buildInputs = (lim.orEmpty o.buildInputs) ++ optional (watch != []) watcher;
|
||||
dependencies =
|
||||
(lim.orEmpty o.dependencies)
|
||||
++ optionals (watched-service != null) [
|
||||
watcher
|
||||
watched-service
|
||||
];
|
||||
# ++ optionals
|
||||
# (watch != [])
|
||||
# ([ watcher ] ++ watched-services);
|
||||
;
|
||||
})
|
||||
|
Reference in New Issue
Block a user