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!