diff --git a/nix/host-modules/swarm-controller.nix b/nix/host-modules/swarm-controller.nix index 90c2ca67..9c8b1fca 100644 --- a/nix/host-modules/swarm-controller.nix +++ b/nix/host-modules/swarm-controller.nix @@ -508,8 +508,7 @@ in StateDirectoryMode = "0750"; # Nothing here needs a writable filesystem, real privileges, or a - # view of the rest of the machine; the daemon reads its socket path - # from config and serves. + # view of the rest of the machine. PrivateTmp = true; ProtectSystem = "strict"; ProtectHome = true; @@ -518,8 +517,27 @@ in ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; + + # `AF_UNIX` for the socket this daemon serves on, plus what its + # outbound clients need: it mints authelia tokens and calls the forge + # over HTTPS (`auth.rs`, `forge.rs`) and reaches the queue over NATS + # (`main.rs`, `status.rs`). `AF_NETLINK` because glibc's + # `getaddrinfo` opens a netlink socket to enumerate local addresses + # before it will return one. + # + # ⚠️ This list is a CLAIM ABOUT WHAT THE DAEMON DOES, so it goes stale + # the moment the daemon grows a client — and it goes stale in the + # worst available way: a blocked family makes `socket()` return + # EAFNOSUPPORT, i.e. "Address family not supported by protocol", so + # the error names the protocol and never the sandbox that refused it. + # This was `AF_UNIX`-only while the daemon merely served its socket; + # all three clients above arrived later, and the restriction was not + # revisited. Add the family when you add the client. RestrictAddressFamilies = [ "AF_UNIX" + "AF_INET" + "AF_INET6" + "AF_NETLINK" ]; };