Restrict Access to a Unix Domain Socket
A Unix domain socket is the most common way for a daemon to expose a local API:
the daemon binds a socket file, usually somewhere under /run or /var/run,
and clients connect to that path instead of a TCP port.
Your task
The deployd daemon runs as a systemd service
and listens on /run/deployd.sock. Sending it the DEPLOY command triggers a (simulated)
production deployment - clearly not something an unprivileged user should be able to do.
Right now, though, the socket is world-accessible.
Restrict access to /run/deployd.sock so that only root and members of the deploy group can connect to it.
The restriction must also survive a restart of deployd,
so that the socket is not left unprotected the next time the daemon comes back up.
Two user accounts are provided to check your work:
aliceis a member of thedeploygroup and must always be able to reach the socket.bobis a regular user and must always be refused access to the socket.
You can probe the socket as either user with the bundled client:
sudo -u alice deployctl PING
sudo -u bob deployctl PING
💡 Docker works exactly like this - the docker CLI talks to dockerd over /var/run/docker.sock.
Because a socket is just a file, anyone who can open it can control the daemon via its API.
That is why /var/run/docker.sock is owned by root:docker with mode 0660: only root
and members of the docker group can send API requests, while everyone else is denied access.
Getting the socket path permissions wrong is a real privilege-escalation risk.
Hint 1: A Unix domain socket is a file
A Unix domain socket has an owner, a group, and permission bits, exactly like a regular file. Inspect it:
ls -l /run/deployd.sock
stat /run/deployd.sock
Connecting to a stream Unix socket requires write permission on the socket file.
So to let only root and the deploy group members in, the socket needs the
right group owner and a mode that grants the group access while denying
"others" - the same root:docker, 0660 arrangement Docker uses.
Hint 2: How to make the protection stick
Changing the owner and mode of the live socket with chown/chmod works only
until deployd recreates the socket - which it does every time the service restarts.
More advanced daemons may have a way to specify the owner and permissions of the socket file
(e.g., dockerd has a -G flag for it), but deployd is a simple, bespoke daemon:
it takes no options and always recreates the socket with the same hard-coded 0666 permissions.
Assuming you cannot rewrite the daemon, the chown/chmod change has to be reapplied on every start.
Look at how the daemon is launched:
systemctl cat deployd.service
systemd can run an extra command right after a service starts. Find a [Service] directive that
does this (the key word is "post start"), and use it to re-own
and re-mode the socket each time deployd comes up. Then reload systemd and
restart the service so the change takes effect.