Watch
0
0
Fork
You've already forked hyperhive
0

nix: move the egress firewall options under deploy.hive-controller.egress

This commit is contained in:
damocles 2026-11-14 18:38:47 +01:00 • committed by mara
commit 7468aa4cff

View file

@ -36,6 +36,7 @@
}:
let
cfg = config.services.hyperhive.network;
egressCfg = config.services.hyperhive.deploy.hive-controller.egress;
nft = lib.getExe pkgs.nftables;
br = cfg.bridgeName;
@ -49,7 +50,7 @@ let
# pool and carrying the mark; the `output` chain DNATs those connections to
# squid. `egress_ech.rs` derives the pool address from the agent's and
# `egress-whois` maps it back, so the pool is the one defined there.
intercept = cfg.egress.intercept;
intercept = egressCfg.intercept;
refuseEch = intercept.enable && intercept.refuseEch;
relayPool = "198.18.0.0/15";
relayMark = "0x45434800";
@ -69,8 +70,8 @@ let
pinEnvironment = {
HIVE_EGRESS_BRIDGE = br;
}
// lib.optionalAttrs (cfg.egress.intercept.unrestrictedFile != null) {
HIVE_EGRESS_UNRESTRICTED = toString cfg.egress.intercept.unrestrictedFile;
// lib.optionalAttrs (egressCfg.intercept.unrestrictedFile != null) {
HIVE_EGRESS_UNRESTRICTED = toString egressCfg.intercept.unrestrictedFile;
};
leaseScript = pkgs.writeShellScript "hive-egress-lease" ''
export PATH=${lib.makeBinPath [ pkgs.nftables ]}
@ -96,7 +97,7 @@ let
# connect at once (to a TCP socket an ICMP error is a soft error, and the
# connect would stall); anything else gets ICMP admin-prohibited. A rule that
# refuses is therefore a pair: one for TCP, one for the rest.
isReject = cfg.egress.forward == "reject";
isReject = egressCfg.forward == "reject";
logPrefix = if isReject then "hive-egress-reject" else "hive-egress-would-drop";
refuse = {
tcp = "meta l4proto tcp";
@ -153,7 +154,7 @@ let
iifname "${br}" meta nfproto ipv4 ether saddr @direct_mac return
iifname "${br}" meta nfproto ipv4 fib daddr type local return
iifname "${br}" meta nfproto ipv4 fib daddr oifname { "${br}", "${meshInterface}" } return
iifname "${br}" meta nfproto ipv4 tcp dport 80 counter redirect to :${toString cfg.egress.intercept.httpPort}
iifname "${br}" meta nfproto ipv4 tcp dport 80 counter redirect to :${toString egressCfg.intercept.httpPort}
iifname "${br}" meta nfproto ipv4 tcp dport 443 counter redirect to :${
toString (if refuseEch then intercept.relayPort else intercept.httpsPort)
}
@ -220,7 +221,7 @@ let
# packet its port cannot log (over its rate, or the set is full) falls to the
# unmetered line, which has one budget for all ports. It logs
# packets, not flows: the bridge hook has no connection tracking.
spoofVerdict = if cfg.egress.antiSpoof == "drop" then "drop" else "accept";
spoofVerdict = if egressCfg.antiSpoof == "drop" then "drop" else "accept";
bridgeTable = ''
table bridge hive_egress {
set port_mac { type ifname . ether_addr; }
@ -283,8 +284,8 @@ let
${lib.optionalString refuseEch ''iifname "${br}" ip saddr ${relayPool} counter drop''}
}
set direct_mac { type ether_addr; }
${lib.optionalString cfg.egress.intercept.enable interceptChain}
${lib.optionalString (cfg.egress.forward != "accept") forwardChain}
${lib.optionalString egressCfg.intercept.enable interceptChain}
${lib.optionalString (egressCfg.forward != "accept") forwardChain}
}
${bridgeTable}
@ -305,7 +306,7 @@ let
ruleset = pkgs.writeText "hive-egress.nft" cfg.egress.ruleset;
in
{
options.services.hyperhive.network.egress.forward = lib.mkOption {
options.services.hyperhive.deploy.hive-controller.egress.forward = lib.mkOption {
type = lib.types.enum [
"accept"
"log"
@ -333,7 +334,7 @@ in
'';
};
options.services.hyperhive.network.egress.antiSpoof = lib.mkOption {
options.services.hyperhive.deploy.hive-controller.egress.antiSpoof = lib.mkOption {
type = lib.types.enum [
"drop"
"log"
@ -362,7 +363,7 @@ in
'';
};
options.services.hyperhive.network.egress.intercept = {
options.services.hyperhive.deploy.hive-controller.egress.intercept = {
enable = lib.mkEnableOption "the redirect of the agents' web traffic into squid's intercept ports";
httpPort = lib.mkOption {
@ -479,10 +480,10 @@ in
'';
}
{
assertion = cfg.egress.forward != "reject" || cfg.egress.intercept.enable;
assertion = egressCfg.forward != "reject" || egressCfg.intercept.enable;
message = ''
services.hyperhive.network.egress.forward = "reject" needs
services.hyperhive.network.egress.intercept.enable = true:
services.hyperhive.deploy.hive-controller.egress.forward = "reject" needs
services.hyperhive.deploy.hive-controller.egress.intercept.enable = true:
without the intercept nothing redirects the agents' web traffic into
squid, and the reject would refuse all of it.
Enable the intercept (hive-squid.nix does on a hive controller host),
@ -620,11 +621,11 @@ in
# A pass also refills `direct_mac`, so a change of the unrestricted list
# takes effect at once instead of at the next tick of the timer.
systemd.paths.hive-egress-direct = lib.mkIf (cfg.egress.intercept.unrestrictedFile != null) {
systemd.paths.hive-egress-direct = lib.mkIf (egressCfg.intercept.unrestrictedFile != null) {
description = "Watch the unrestricted agents list for the egress intercept exemptions";
wantedBy = [ "paths.target" ];
pathConfig = {
PathChanged = toString cfg.egress.intercept.unrestrictedFile;
PathChanged = toString egressCfg.intercept.unrestrictedFile;
Unit = "hive-egress-pin.service";
};
};