From 72c8ed038946850d345db13f30e259a368d7c3c5 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Mon, 19 Aug 2019 02:08:46 +0200 Subject: [PATCH 1/4] systemd: build with cryptsetup and cryptsetup-generators There's a circular dependency to systemd via cryptsetup and lvm2 (systemd -> cryptsetup -> lvm2 -> udev=systemd). However, cryptsetup only really needs the devmapper component shipped with lvm2. So build `pkgs.cryptsetup` with a lvm2 that doesn't come with udev. --- nixos/modules/system/boot/systemd.nix | 2 +- pkgs/os-specific/linux/systemd/default.nix | 4 +++- pkgs/top-level/all-packages.nix | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 86bd81d781a8..b0828a923de6 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -25,7 +25,7 @@ let "nss-lookup.target" "nss-user-lookup.target" "time-sync.target" - #"cryptsetup.target" + "cryptsetup.target" "sigpwr.target" "timers.target" "paths.target" diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index a76156a985ce..440c7de204ee 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -9,6 +9,7 @@ , patchelf , substituteAll , getent +, cryptsetup, lvm2 , buildPackages , perl , withSelinux ? false, libselinux @@ -30,6 +31,7 @@ let gnupg-minimal = gnupg.override { zlib = null; bzip2 = null; }; + in stdenv.mkDerivation { version = "245.6"; pname = "systemd"; @@ -89,7 +91,7 @@ in stdenv.mkDerivation { ]; buildInputs = [ linuxHeaders libcap curl.dev kmod xz pam acl - /* cryptsetup */ libuuid glib libgcrypt libgpgerror libidn2 + cryptsetup libuuid glib libgcrypt libgpgerror libidn2 pcre2 ] ++ stdenv.lib.optional withKexectools kexectools ++ stdenv.lib.optional withLibseccomp libseccomp ++ diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index d835916f0edc..3ec347782129 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -16931,7 +16931,11 @@ in criu = callPackage ../os-specific/linux/criu { }; - cryptsetup = callPackage ../os-specific/linux/cryptsetup { }; + cryptsetup = callPackage ../os-specific/linux/cryptsetup { + # cryptsetup only really needs the devmapper component of cryptsetup + # but itself is used as a library in systemd (=udev) + lvm2 = lvm2.override { udev = null; }; + }; cramfsswap = callPackage ../os-specific/linux/cramfsswap { }; From 0a41d69968cc6fe19493ec9f06c166066bcfcd45 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Tue, 14 May 2019 01:20:56 +0200 Subject: [PATCH 2/4] systemd: substituteInPlace paths to mkswap and mke2fs (used in new cryptsetup-generator.c) --- pkgs/os-specific/linux/systemd/default.nix | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index 440c7de204ee..3535b97e4faa 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -1,5 +1,5 @@ -{ stdenv, lib, fetchFromGitHub, fetchpatch, pkgconfig, intltool, gperf, libcap -, curl, kmod, gnupg, gnutar, xz, pam, acl, libuuid, m4, utillinux, libffi +{ stdenv, lib, fetchFromGitHub, pkgconfig, intltool, gperf, libcap +, curl, kmod, gnupg, gnutar, xz, pam, acl, libuuid, m4, e2fsprogs, utillinux, libffi , glib, kbd, libxslt, coreutils, libgcrypt, libgpgerror, libidn2, libapparmor , audit, lz4, bzip2, pcre2 , linuxHeaders ? stdenv.cc.libc.linuxHeaders @@ -178,12 +178,28 @@ in stdenv.mkDerivation { export LC_ALL="en_US.UTF-8"; # FIXME: patch this in systemd properly (and send upstream). # already fixed in f00929ad622c978f8ad83590a15a765b4beecac9: (u)mount - for i in src/remount-fs/remount-fs.c src/core/mount.c src/core/swap.c src/fsck/fsck.c units/emergency.service.in units/rescue.service.in src/journal/cat.c src/shutdown/shutdown.c src/nspawn/nspawn.c src/shared/generator.c units/systemd-logind.service.in units/systemd-nspawn@.service.in; do + for i in \ + src/core/mount.c \ + src/core/swap.c \ + src/cryptsetup/cryptsetup-generator.c \ + src/fsck/fsck.c \ + src/journal/cat.c \ + src/nspawn/nspawn.c \ + src/remount-fs/remount-fs.c \ + src/shared/generator.c \ + src/shutdown/shutdown.c \ + units/emergency.service.in \ + units/rescue.service.in \ + units/systemd-logind.service.in \ + units/systemd-nspawn@.service.in; \ + do test -e $i substituteInPlace $i \ --replace /usr/bin/getent ${getent}/bin/getent \ + --replace /sbin/mkswap ${lib.getBin utillinux}/sbin/mkswap \ --replace /sbin/swapon ${lib.getBin utillinux}/sbin/swapon \ --replace /sbin/swapoff ${lib.getBin utillinux}/sbin/swapoff \ + --replace /sbin/mke2fs ${lib.getBin e2fsprogs}/sbin/mke2fs \ --replace /sbin/fsck ${lib.getBin utillinux}/sbin/fsck \ --replace /bin/echo ${coreutils}/bin/echo \ --replace /bin/cat ${coreutils}/bin/cat \ From 29941db6bd333964145921a92c045c74b8bf4cb8 Mon Sep 17 00:00:00 2001 From: Arian van Putten Date: Mon, 13 May 2019 14:35:02 +0200 Subject: [PATCH 3/4] systemd-cryptsetup-generator: remove This package previously did override the systemd package, and instructed ninja, systemd's previous build system, to only build the cryptsetup-specific systemd generators (plus some manual rpath massaging, as ninja install wasn't used). Afterwards, users were expected to add this package to their `systemd.generator-packages` (or since https://github.com/NixOS/nixpkgs/pull/65376/files `systemd.packages`) NixOS module options, so systemd will use these generators. As the previous commit added cryptsetup support directly to the systemd package (and pkgs.systemd now already ships the cryptsetup generators), we don't need another package shipping the same generators. --- .../linux/systemd/cryptsetup-generator.nix | 34 ------------------- pkgs/top-level/aliases.nix | 1 + pkgs/top-level/all-packages.nix | 3 -- 3 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 pkgs/os-specific/linux/systemd/cryptsetup-generator.nix diff --git a/pkgs/os-specific/linux/systemd/cryptsetup-generator.nix b/pkgs/os-specific/linux/systemd/cryptsetup-generator.nix deleted file mode 100644 index 3fd8ff07f425..000000000000 --- a/pkgs/os-specific/linux/systemd/cryptsetup-generator.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ systemd, cryptsetup }: - -systemd.overrideAttrs (p: { - version = p.version; - name = "systemd-cryptsetup-generator-${p.version}"; - - buildInputs = p.buildInputs ++ [ cryptsetup ]; - outputs = [ "out" ]; - - buildPhase = '' - ninja systemd-cryptsetup systemd-cryptsetup-generator - ''; - - # As ninja install is not used here, the rpath needs to be manually fixed. - # Otherwise the resulting binary doesn't properly link against systemd-shared.so - postFixup = '' - for prog in `find $out -type f -executable`; do - (patchelf --print-needed $prog | grep 'libsystemd-shared-.*\.so' > /dev/null) && ( - patchelf --set-rpath `patchelf --print-rpath $prog`:"$out/lib/systemd" $prog - ) || true - done - # test it's OK - "$out"/lib/systemd/systemd-cryptsetup - ''; - - installPhase = '' - mkdir -p $out/lib/systemd/ - cp systemd-cryptsetup $out/lib/systemd/systemd-cryptsetup - cp src/shared/*.so $out/lib/systemd/ - - mkdir -p $out/lib/systemd/system-generators/ - cp systemd-cryptsetup-generator $out/lib/systemd/system-generators/systemd-cryptsetup-generator - ''; -}) diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 5bc4021ea087..8737435654a1 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -546,6 +546,7 @@ mapAliases ({ surf-webkit2 = surf; # added 2017-04-02 sup = throw "deprecated in 2019-09-10: abandoned by upstream"; system_config_printer = system-config-printer; # added 2016-01-03 + systemd-cryptsetup-generator = throw "systemd-cryptsetup-generator is now included in the systemd package"; # added 2020-07-12 systemd_with_lvm2 = throw "obsolete, enabled by default via the lvm module"; # added 2020-07-12 systool = sysfsutils; # added 2018-04-25 tahoelafs = tahoe-lafs; # added 2018-03-26 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 3ec347782129..9f84636129e4 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -17994,9 +17994,6 @@ in }; udev = systemd; # TODO: move to aliases.nix - # standalone cryptsetup generator for systemd - systemd-cryptsetup-generator = callPackage ../os-specific/linux/systemd/cryptsetup-generator.nix { }; - systemd-wait = callPackage ../os-specific/linux/systemd-wait { }; sysvinit = callPackage ../os-specific/linux/sysvinit { }; From eb58711edf7b8a41c3b86c6099258c49a563b518 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Wed, 5 Aug 2020 01:34:12 +0200 Subject: [PATCH 4/4] nixosTests.systemd: test cryptsetup support This creates and opens a luks volume, puts its passphrase into a keyfile and writes a /etc/crypttab. It then reboots the machine, and verifies systemd parsed /etc/crypttab properly, and was able to unlock the volume with the keyfile provided (as we try to mount it). The memorySize of the VM had to be bumped, as luksFormat would otherwise run out of memory. --- nixos/tests/systemd.nix | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/nixos/tests/systemd.nix b/nixos/tests/systemd.nix index a653932fb37c..9d21f9158f3c 100644 --- a/nixos/tests/systemd.nix +++ b/nixos/tests/systemd.nix @@ -4,7 +4,10 @@ import ./make-test-python.nix ({ pkgs, ... }: { machine = { lib, ... }: { imports = [ common/user-account.nix common/x11.nix ]; - virtualisation.emptyDiskImages = [ 512 ]; + virtualisation.emptyDiskImages = [ 512 512 ]; + virtualisation.memorySize = 1024; + + environment.systemPackages = [ pkgs.cryptsetup ]; fileSystems = lib.mkVMOverride { "/test-x-initrd-mount" = { @@ -144,5 +147,25 @@ import ./make-test-python.nix ({ pkgs, ... }: { assert "RuntimeWatchdogUSec=30s" in output assert "RebootWatchdogUSec=10m" in output assert "KExecWatchdogUSec=5m" in output + + # Test systemd cryptsetup support + with subtest("systemd successfully reads /etc/crypttab and unlocks volumes"): + # create a luks volume and put a filesystem on it + machine.succeed( + "echo -n supersecret | cryptsetup luksFormat -q /dev/vdc -", + "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vdc foo", + "mkfs.ext3 /dev/mapper/foo", + ) + + # create a keyfile and /etc/crypttab + machine.succeed("echo -n supersecret > /var/lib/luks-keyfile") + machine.succeed("chmod 600 /var/lib/luks-keyfile") + machine.succeed("echo 'luks1 /dev/vdc /var/lib/luks-keyfile luks' > /etc/crypttab") + + # after a reboot, systemd should unlock the volume and we should be able to mount it + machine.shutdown() + machine.succeed("systemctl status systemd-cryptsetup@luks1.service") + machine.succeed("mkdir -p /tmp/luks1") + machine.succeed("mount /dev/mapper/luks1 /tmp/luks1") ''; })