Watch
0
0
Fork
You've already forked hyperhive
0

swarm-controller: restrict its socket directory to nginx's access group

This commit is contained in:
atlas 2026-10-17 13:54:14 +02:00
commit 51cc093465
4 changed files with 63 additions and 16 deletions

View file

@ -93,8 +93,8 @@ queue, so both survive a restart.
## Why a unix socket, not a port
The hive-gateway's nginx is the only intended client and reaches the socket
through a bind-mount. A listener that is never bound to an address cannot be
The hive-gateway's nginx is the only intended client (`swarmctl` runs as root).
A listener that is never bound to an address cannot be
reached from off-host by mistake.
The socket path is `services.hyperhive.deploy.swarm-controller.socketPath`, default
@ -108,7 +108,12 @@ The socket is `0666`. It has to be: nginx runs as a different user and
sockets, and rests on the same argument — _"the bind source dir is per-agent on
host so blast radius is unchanged."_
What keeps that safe is that the directory holds **one** socket. So:
What keeps that safe is that the directory is `0750`, owned by the
`swarm-controller-clients` group, and holds **one** socket. nginx is in that
group through its unit's `SupplementaryGroups`; root bypasses mode bits, so
`swarmctl` needs no membership. Every other local user gets `EACCES` at the
directory. The group is not `swarm-controller`'s own, which also owns the
state directory. So:
> **Never point `socketPath` at a directory that carries anything else.**
> `/run/hyperhive` above all — it holds `host.sock`, the host **admin** socket.
@ -116,7 +121,9 @@ What keeps that safe is that the directory holds **one** socket. So:
> socket within its reach too.
nginx is a host service, so nothing narrows what it can reach except the
directory itself — that is the whole of the access control. A unit test pins
directory itself — that is the whole of the access control. The unit sets the
group with a root `ExecStartPre` (`chgrp`), because systemd chowns the runtime
directory to the unit's own group on every start. A unit test pins
the default path so a tidying edit fails instead of reviewing cleanly.
`RuntimeDirectoryPreserve=yes` and the daemon's stale-socket unlink on start are