1 title: Hardening Services With Systemd 2 author: Daniel Moch 3 copyright: 2018, Daniel Moch 4 date: 2018-10-05 09:13:03 UTC-04:00 5 category: technology 6 description: More secure services are an out-of-the-box feature with Systemd 7 8 Systemd gets a lot of hate. There's a lot of heat and very little 9 light in those discussions, in my opinion, and I don't expect that 10 this post will change the mind of anyone who has already decided to 11 hate Systemd. My goal here is far more modest. I want to share a 12 feature of the new init system that I find really compelling, and that 13 I hadn't seen discussed pretty much anywhere: Systemd's native ability 14 to leverage the Linux kernel's namespacing features to run services in 15 a sandboxed environment. 16 17 [Linux namespaces](https://en.wikipedia.org/wiki/Linux_namespaces) are 18 the kernel feature that enables partitioning everything from 19 processes, to the filesystem, to the network stack. A process 20 operating in one namespace will have a different view of the system's 21 resources than a process operating in another namespace. Probably the 22 best known application of Linux namespaces are container platforms 23 such as [Docker](https://www.docker.com/). While Docker is ostensibly 24 a devops platform enabling rapid deployment of applications, the 25 underlying kernel namespace features can be applied to security as 26 well, allowing processes to be effectively partitioned off from one 27 another and, to varying degrees, the underlying system. That's what 28 folks mean when they talk about running a process or service in a 29 sandboxed environment. 30 31 So what if I'm a sysadmin who wants to run a service in a sandbox? 32 This would traditionally be done by setting up a 33 [chroot](https://wiki.archlinux.org/index.php/Change_root) 34 environment. But another option, one that offers a bit more 35 flexibility, would be to run the service in a mount namespace, and 36 then reconfigure the existing filesystem within the namespace to apply 37 least-privilege to data the services needs and hide data the service 38 doesn't need access to. 39 40 With Systemd, you can configure your service according to either of 41 the above scenarios by simply adding a couple of lines to the service 42 file. Say I want my service to run within a chroot located at 43 ``/srv/http``. Assuming the chroot is set up appropriately so that the 44 service has access to all of the data it needs within its folder 45 hierarchy, then all I need to do is add the line 46 ``RootDirectory=/srv/http`` to the ``[Service]`` section of the 47 Systemd service file. 48 49 The second scenario is a bit more interesting. Say I'm running a web 50 front-end for my Git service, and that my service needs access to 51 ``/dev/urandom`` ``/tmp`` and read-only access to ``/home/git``. 52 Systemd offers several options that allow you to do this in a way that 53 exposes little else to the service. Take the below service file: 54 55 ... 56 [Service] 57 PrivateDevices=yes 58 PrivateTmp=yes 59 ProtectHome=tmpfs 60 BindReadOnlyPaths=/home/git 61 ... 62 63 These options implicitly place the service within a mount namespace, 64 meaning we set up our file hierarchy however we like. In the above 65 example, ``PrivateDevices`` creates a private ``/dev`` structure that 66 only provides access to pseudo-devices like ``random`` ``null``, etc. 67 Critically, disk devices are not visible to the service when the 68 ``PrivateDevices`` option is used. Likewise, ``PrivateTmp`` creates a 69 ``/tmp`` folder that is empty except for what the service itself 70 writes. ``ProtectHome`` has a few options, but the ``tmpfs`` option, 71 according to the documentation, is designed for pairing with the 72 ``BindPaths/BindReadOnlyPaths`` options in order to selectively 73 provide access to folders within ``/home``. Since all we need there is 74 read-only access to the ``git`` user, that's exactly what we provide, 75 nothing more and nothing less. 76 77 This is all great, but it admittedly only provides mount namespacing 78 for the service. This is probably sufficient in most cases, but 79 Systemd does offer options for network and user namespacing. Readers 80 looking to utilize those, or looking for a comprehensive description 81 of the mount namespacing options, are encouraged to read the 82 [systemd.exec man 83 page](http://jlk.fjfi.cvut.cz/arch/manpages/man/core/systemd/systemd.exec.5.en).