systemd-analyze security --user SERVICE
is handy, but inaccurate. The analysis (on the version bundled with Ubuntu 22.04 “Jammy”) has a few items that are marked as not applicable to user services, but also recommends setting a few items that apparently cannot be set in a user service. Attempting to do so will fail to start the service, with a log that the capabilities could not be set (regardless of the specific option causing the error.)
This unfortunately restricts the following: CapabilityBoundingSet
, PrivateDevices
, ProtectClock
, ProtectKernelLogs
, and ProtectKernelModules
.
Using ProtectHostname
with RestrictNamespaces=true
logs a warning every time the service starts up, because the UTS namespace can’t be configured. It’s only a warning, which I think means that ProtectHostname
is redundant in this situation, so I took it out of the service. It’s more important to have clean logs than a good systemd-analyze security
score.
The list of capabilities I was able to set were: KeyringMode=private
, LockPersonality=true
, MemoryDenyWriteExecute=true
, NoNewPrivileges=true
, PrivateMounts=true
, PrivateTmp=true
, ProcSubset=pid
, ProtectControlGroups=true
, ProtectHome=read-only
, ProtectKernelTunables=true
, ProtectSystem=strict
, RestrictNamespaces=true
, RestrictRealtime=true
, RestrictSUIDSGID=true
, SystemCallArchitectures=native
, SystemCallFilter=@system-service
, UMask=077
, and:
RestrictAddressFamilies=
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
Note that this is tailored to the service I was configuring, an HTTP proxy written in Go. For instance, I wanted to run the binary and load its configuration file from ~/.local
, which prevented me from using a stronger setting for ProtectHome
. Likewise, I can’t really turn off networking, because it’s a network program.