I think I like systemd's
DynamicUser feature (under the right circumstances)
Our Prometheus metrics system involves
a lot of daemons that do things like generate metrics, both official
daemons and various
third party ones. Many of these
daemons and the things they do are essentially stateless, because
they can be and it makes
I was recently setting up such a daemon (a new one) on my office
workstation, and as part of that I wanted to pick a UID for it to
run as. I consider this particular daemon slightly more risky than
usual, so I didn't want to go with either
root (it doesn't need
that much power) or the '
prometheus' user, which is not root but
does wind up owning things like the Prometheus metrics data storage.
At about the time I was looking through my
/etc/passwd to try to
find a user that I was comfortable with and that would work, a
little light went on in my mind and I remembered that systemd
services can use dynamic users.
Stateless daemons with no special permissions requirements are an
ideal match for dynamic users, because basically I just want a
generic non-root user. The user doesn't need to have any special
privileges, and it doesn't need a stable UID or GID because it will
never have anything on disk (or at least, not outside of brief uses
/tmp). Systemd making these UIDs and GIDs up on the fly saves
me the effort of creating one or more new users, and as you can
see, having to explicitly create new users is enough annoyance that
I might not do it at all.
(The other advantage of dynamic users here is that if I decide to stop using a daemon, I'm not left with a stray user and group to clean up at some indefinite point in the future.)
.service file from a '
User=' line to '
basically just worked. After a daemon restart, the daemon was running
happily under its new unique UID with everything working fine. The
daemons I converted had no problems running other programs or making
network connections, either.
You don't have to restrict a
DynamicUser service to standard Unix
'regular UID' permissions (well, somewhat less than that, since
systemd adds extra restrictions). I run Prometheus's Blackbox
exporter as a
non-root user but explicitly augment its capabilities with
CAP_NET_RAW so that it can send and receive ICMP packets:
[Service] [...] CapabilityBoundingSet=CAP_NET_RAW AmbientCapabilities=CAP_NET_RAW
This still works fine with it converted from '
After this positive experience, I'm probably going to start making
more use of '
DynamicUser=yes'. If a stateless thing doesn't have
to run as root, switching it to using a dynamic user is both pretty
trivial and a bit more secure.
(Systemd theoretically supports dynamic users for services with some state, but there can be problems with that.)