Systemd provides many hardening options for units. systemd-analyze security provides a nice overview for all services and their exposure level:
What do those levels mean and how can we improve it? Let’s take a closer look (Screenshot of my already tuned unit):
This detail view provides information about all hardening options supported *by your used systemd version*. https://www.freedesktop.org/software/systemd/man/systemd.exec.html and https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html are good entrypoints for the systemd documentation. But keep in mind that the website documents the current systemd version. If you are on legacy operating systems like Debian or CentOS, the website probably lists options that your systemd doesn’t yet support.
Hardening a service
Cerebro is a java service. It provides a webinterface to manage elasticsearch clusters. If configured properly, it doesn’t need to write anything and only logs to stdout. That provides us plenty of hardening options. I ended up with the following unit:
[Unit]
Description=Cerebro, an ElasticSearch web admin tool
Wants=elasticsearch.service
[Service]
SuccessExitStatus=143
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/"
WorkingDirectory=/opt/cerebro/cerebro-0.9.4
ExecStart=/usr/local/bin/cerebro -Dhttp.address=127.0.0.1
PrivateTmp=true
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
PrivateDevices=true
RestrictNamespaces=uts ipc pid user cgroup
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ProtectClock=true
RestrictSUIDSGID=true
PrivateUsers=true
ProtectHostname=true
ProtectProc=invisible
# only works because service is accessed an ssh tunnel
IPAddressDeny=any
IPAddressAllow=localhost
User=cerebro
Group=cerebro
UMask=077
[Install]
WantedBy=multi-user.target
What does it all do? Basically:
- Do only allow access from localhost (because the service is accessed via an ssh tunnel / a reverse proxy)
- Run with a dedicated user, that has no write access (except for a private /tmp directory)
- Only provide a minimal set of special filesystems (/dev, /proc, /sys), in readonly
The different hardening options lowered the initial exposure level from 9.6 to 3.9
Pingback: systemd unit hardening followup | the world needs more puppet!