3
0
Fork 0
forked from mirrors/nixpkgs
nixpkgs/nixos/modules/system/boot
aszlig ac64ce9945
nixos: Add 'chroot' options to systemd.services
Currently, if you want to properly chroot a systemd service, you could
do it using BindReadOnlyPaths=/nix/store (which is not what I'd call
"properly", because the whole store is still accessible) or use a
separate derivation that gathers the runtime closure of the service you
want to chroot. The former is the easier method and there is also a
method directly offered by systemd, called ProtectSystem, which still
leaves the whole store accessible. The latter however is a bit more
involved, because you need to bind-mount each store path of the runtime
closure of the service you want to chroot.

This can be achieved using pkgs.closureInfo and a small derivation that
packs everything into a systemd unit, which later can be added to
systemd.packages. That's also what I did several times[1][2] in the
past.

However, this process got a bit tedious, so I decided that it would be
generally useful for NixOS, so this very implementation was born.

Now if you want to chroot a systemd service, all you need to do is:

  {
    systemd.services.yourservice = {
      description = "My Shiny Service";
      wantedBy = [ "multi-user.target" ];

      chroot.enable = true;
      serviceConfig.ExecStart = "${pkgs.myservice}/bin/myservice";
    };
  }

If more than the dependencies for the ExecStart* and ExecStop* (which
btw. also includes "script" and {pre,post}Start) need to be in the
chroot, it can be specified using the chroot.packages option. By
default (which uses the "full-apivfs"[3] confinement mode), a user
namespace is set up as well and /proc, /sys and /dev are mounted
appropriately.

In addition - and by default - a /bin/sh executable is provided as well,
which is useful for most programs that use the system() C library call
to execute commands via shell. The shell providing /bin/sh is dash
instead of the default in NixOS (which is bash), because it's way more
lightweight and after all we're chrooting because we want to lower the
attack surface and it should be only used for "/bin/sh -c something".

Prior to submitting this here, I did a first implementation of this
outside[4] of nixpkgs, which duplicated the "pathSafeName" functionality
from systemd-lib.nix, just because it's only a single line.

However, I decided to just re-use the one from systemd here and
subsequently made it available when importing systemd-lib.nix, so that
the systemd-chroot implementation also benefits from fixes to that
functionality (which is now a proper function).

Unfortunately, we do have a few limitations as well. The first being
that DynamicUser doesn't work in conjunction with tmpfs, because it
already sets up a tmpfs in a different path and simply ignores the one
we define. We could probably solve this by detecting it and try to
bind-mount our paths to that different path whenever DynamicUser is
enabled.

The second limitation/issue is that RootDirectoryStartOnly doesn't work
right now, because it only affects the RootDirectory option and not the
individual bind mounts or our tmpfs. It would be helpful if systemd
would have a way to disable specific bind mounts as well or at least
have some way to ignore failures for the bind mounts/tmpfs setup.

Another quirk we do have right now is that systemd tries to create a
/usr directory within the chroot, which subsequently fails. Fortunately,
this is just an ugly error and not a hard failure.

[1]: https://github.com/headcounter/shabitica/blob/3bb01728a0237ad5e7/default.nix#L43-L62
[2]: https://github.com/aszlig/avonc/blob/dedf29e092481a33dc/nextcloud.nix#L103-L124
[3]: The reason this is called "full-apivfs" instead of just "full" is
     to make room for a *real* "full" confinement mode, which is more
     restrictive even.
[4]: https://github.com/aszlig/avonc/blob/92a20bece4df54625e/systemd-chroot.nix

Signed-off-by: aszlig <aszlig@nix.build>
2019-03-14 19:14:01 +01:00
..
loader boot/raspberrypi: replace deprecated configuration option 2019-02-08 11:36:09 -08:00
binfmt.nix nixos/binfmt: Initial binfmt_msc support. 2018-02-18 12:42:17 -05:00
coredump.nix manual: Clarify that limits.conf doesn't apply to systemd services. (#40267) 2018-05-12 17:44:57 +02:00
emergency-mode.nix nixos: tmp on tmpfs option 2014-07-30 16:19:26 +02:00
grow-partition.nix Fix kernel crash caused by absent root device 2018-05-12 02:55:33 +03:00
initrd-network.nix Merge pull request #47665 from erikarvstedt/initrd-improvements 2019-01-06 21:48:26 -06:00
initrd-ssh.nix nixos/initrd: improve descriptions 2018-10-02 17:38:06 +02:00
kernel.nix kernel: fix boot.consoleLogLevel description 2018-04-17 10:45:30 +09:00
kernel_config.nix linux: ability to merge structured configs 2019-01-28 09:06:33 +09:00
kexec.nix nixos/kexec: Fix typo in meta.platforms 2018-09-28 17:44:42 +02:00
luksroot.nix nixos/luksroot: Fix typo Verifiying -> Verifying 2019-01-08 15:45:02 -05:00
modprobe.nix modprobe activation: Order after specialfs 2018-02-05 21:04:40 +01:00
networkd.nix nixos/networkd: do not require gateway for routes 2018-09-07 02:23:12 +03:00
pbkdf2-sha512.c Update to the Yubikey PBA 2014-02-08 14:59:52 +01:00
plymouth.nix nixos/plymouth: multi-user.target wants plymouth-quit-wait.service 2018-05-04 16:06:57 +02:00
resolved.nix [bot] nixos/*: remove unused arguments in lambdas 2018-07-20 20:56:59 +00:00
shutdown.nix Don't run hwclock if /dev/rtc doesn't exist 2014-05-05 16:47:51 +02:00
stage-1-init.sh Merge pull request #42183 from kisik21/master 2019-01-17 07:42:32 +00:00
stage-1.nix nixos: add preferLocalBuild=true; on derivations for config files 2019-02-22 20:11:27 +01:00
stage-2-init.sh nixos/stage-2: create empty machine-id at boot 2018-09-30 10:45:35 -07:00
stage-2.nix systemd: ensure fsck Requires/After links are created in mount units 2018-08-28 17:12:49 +02:00
systemd-lib.nix nixos: Add 'chroot' options to systemd.services 2019-03-14 19:14:01 +01:00
systemd-nspawn.nix nixos/systemd-nspawn: accept all Exec and Files options 2018-12-08 14:41:37 +01:00
systemd-unit-options.nix nixos/systemd: add StartLimitIntervalSec to unit config 2019-01-28 00:29:43 +00:00
systemd.nix Merge pull request #56012 from matix2267/logind-lid-switch-external-power 2019-02-22 20:55:46 +01:00
timesyncd.nix [bot] nixos/*: remove unused arguments in lambdas 2018-07-20 20:56:59 +00:00
tmp.nix nixos: tmp on tmpfs option 2014-07-30 16:19:26 +02:00