Watch
0
0
Fork
You've already forked hyperhive
0

swarm-authelia: run in its own network namespace

Refs #4815
This commit is contained in:
atlas 2026-10-21 21:26:13 +02:00 • committed by mara
commit 220b51d0a3
12 changed files with 204 additions and 105 deletions

View file

@ -171,7 +171,7 @@ let
# Every service container at once: the services-only host plus the CI
# runner. The CI runner, the review classifier, the builder, the claude login
# minter, the metrics store and the homeserver are the six containers on a
# minter, the metrics store, the homeserver and authelia are the seven containers on a
# netns of their own.
serviceContainersWithCi = hive {
deploy.hive-controller.enable = false;
@ -599,7 +599,7 @@ let
let
shared = lib.filter (c: !c.privateNetwork) (lib.attrValues serviceContainers);
in
lib.length shared == 7
lib.length shared == 6
&& lib.all (
c: !c.config.networking.firewall.enable && !c.config.networking.resolvconf.enable
) shared;
@ -694,6 +694,51 @@ let
&& unit.serviceConfig.Group == "gateway-nginx"
&& lib.elem dir unit.serviceConfig.ReadWritePaths;
}
{
# On the bridge by DHCP, with all three listeners on sockets: nothing
# the bridge can dial. Every vhost location that forwards goes through
# one of the sockets, except the internal authz subrequest, which is
# `https://`. The main, bridge and metrics locations are named so an
# empty filter can't pass.
name = "authelia runs on a netns of its own and the gateway reaches all three listeners over sockets";
ok =
let
host = serviceContainersWithCi;
net = host.services.hyperhive.network;
c = host.containers.swarm-authelia;
dir = "/run/swarm-authelia";
sock = n: "${dir}/${n}.sock";
locs = host.services.nginx.virtualHosts.${host.services.hyperhive.swarm.authelia.domain}.locations;
forwarded = lib.filter (p: p != null && !(lib.hasPrefix "https://" p)) (
map (l: l.proxyPass) (lib.attrValues locs)
);
inner = c.config;
settings = inner.services.authelia.instances.swarm.settings;
unit = inner.systemd.services.authelia-swarm;
bridge = inner.systemd.services.swarm-authelia-bridge;
nginxGid = host.ids.gids.nginx;
in
c.privateNetwork
&& c.hostBridge == net.bridgeName
&& c.hostAddress == null
&& c.localAddress == null
&& inner.networking.interfaces.eth0.useDHCP
&& inner.networking.firewall.enable
&& settings.server.address == "unix://${sock "authelia"}?umask=0007"
&& settings.telemetry.metrics.address == "unix://${sock "metrics"}?umask=0007"
&& bridge.environment.SWARM_AUTHELIA_BRIDGE_SOCKET == sock "bridge"
&& !(bridge.environment ? SWARM_AUTHELIA_BRIDGE_BIND)
&& locs."/".proxyPass == "http://unix:${sock "authelia"}:/"
&& locs."/bridge/".proxyPass == "http://unix:${sock "bridge"}:/"
&& locs."= /metrics".proxyPass == "http://unix:${sock "metrics"}:/"
&& lib.all (lib.hasPrefix "http://unix:${dir}/") forwarded
&& c.bindMounts.${dir}.hostPath == dir
&& builtins.elem "d ${dir} 0770 root ${toString nginxGid} - -" host.systemd.tmpfiles.rules
&& inner.users.groups.gateway-nginx.gid == nginxGid
&& unit.serviceConfig.Group == "gateway-nginx"
&& bridge.serviceConfig.Group == "gateway-nginx"
&& lib.elem dir unit.serviceConfig.ReadWritePaths;
}
{
# The DynamicUser layout keeps the history under /var/lib/private; the
# static user's StateDirectory is the plain path. The move runs as its