tl;dr: if you don't care about the example and just want to know how the heck to interpret this tool, read the first couple paragraphs, and then skip to the last paragraph or two.
I think people have a deep misunderstanding of what `systemd-analyze security` does, and in particular are expecting it to be much more sophisticated than it is. Per systemd-analyze(1): > Note that this only analyzes the per-service security features > systemd itself implements. This means that any additional security > mechanisms applied by the service code itself are not accounted > for. The exposure level determined this way should not be > misunderstood: a high exposure level neither means that there is no > effective sandboxing applied by the service code itself, nor that > the service is actually vulnerable to remote or local attacks. The key takeaway from this is that the tool only considers security-related systemd service file directives (see systemd.exec(5)). It does NOT consider *anything* else like: * AppArmor or SELinux confinement * Service architecture (for example, whether it is composed of several mutually-distrusting daemons) * Service complexity * Whether the service does anything to confine itself, like dropping privileges after starting up as root * Service vulnerability mitigations (for example, being written in a memory-safe language, or being compiled with -fstack-protector-strong or something) and etc. I case you're not familiar with the directives `systemd-analyze security` looks at, basically what you need to know is that they can be turned on in a service's definition and systemd will automatically restrict the ability of the service's processes to do various things, like reading other services' temporary files, or mucking with kernel tunables. (These restrictions are imposed *on top of* any existing restrictions. For example if the service is not run as root it already can't muck with kernel tunables, so that systemd restriction does nothing unless the service either runs as root or can escalate privileges to root). As an example of how these work, take the default systemd service file for Apache httpd from my production Debian 10 machine: ``` % systemctl cat apache2.service # /lib/systemd/system/apache2.service [Unit] Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target Documentation=https://httpd.apache.org/docs/2.4/ [Service] Type=forking Environment=APACHE_STARTED_BY_SYSTEMD=true ExecStart=/usr/sbin/apachectl start ExecStop=/usr/sbin/apachectl stop ExecReload=/usr/sbin/apachectl graceful PrivateTmp=true Restart=on-abort [Install] WantedBy=multi-user.target ``` If I run `systemd-analyze security apache2.service`, I get a long detailed listing of things I could add to this unit file to improve the sandboxing that systemd applies to the service (I'm not including an example here because it's so long, but you can run this on any service to get something similar). The score given is 9.2 UNSAFE Now, Apache has absolutely no business writing to users' home directories, so let's say I want systemd to enforce that. (Normally it wouldn't have any business reading from home directories either except that on my system I have it set up to serve `/home/$USER/public_html` directories.) Apache also has no business writing to /usr, /boot, /etc, /sys, /proc. Moreover it does not need most of the devices in /dev. It would be nice, therefore, if it was not allowed to do these things if it ever gets compromised. So, what I can do is tell systemd to restrict these things. I create a systemd drop-in file (maybe with `systemctl edit apache2.service`) with the following content: ``` [Service] ProtectSystem=full ProtectHome=read-only PrivateDevices=true ProtectKernelTunables=true ProtectControlGroups=true ``` Now if I run `systemd-analyze security apache2.service` again, the reported score is 7.9 EXPOSED. So it went down 1.3 points because I added those sandboxing options, which as systemd-analyze(8) mentions, are the *only* things that systemd considers. Note in particular that systemd-analyze does *not* know or care that Apache drops privileges when it starts up and thus can't write to /usr et. al. anyway. So these options are useful for defense in depth hardening, but the only time they'll matter is if Apache is compromised, and *then* the attacker finds a way to escalate to root privileges. At that point the attacker will not be able to write to these directories despite having root. It's probably a good idea to turn these options on for lots and lots of services, because they're *so* easy to just put in the service file and they provide defense in depth. But `systemd-analyze security`'s warnings are much too scary. Instead of UNSAFE a better label honestly would be NEEDS A LOT OF WORK or something like that. Think of the tool as treating the service's code like a black box: it doesn't know anything about what goes on inside the service (in fact in the general case it is mathematically *impossible* for it to do so; see Rice's theorem[1]) so it works with what it knows, which is declarative systemd configuration. Another way to think about the scores are as an upper bound on danger, enforced by systemd/the Linux kernel. Hopefully this gives a sense of how better to interpret these warnings. -AJ [1]: https://en.wikipedia.org/wiki/Rice%27s_theorem -- You received this message because you are subscribed to the Google Groups "qubes-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/qubes-users/20200220070321.GA13833%40failover.strugee.net.
