at 24.11-pre 3.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.boot.initrd.clevis; 7 systemd = config.boot.initrd.systemd; 8 supportedFs = [ "zfs" "bcachefs" ]; 9in 10{ 11 meta.maintainers = with maintainers; [ julienmalka camillemndn ]; 12 meta.doc = ./clevis.md; 13 14 options = { 15 boot.initrd.clevis.enable = mkEnableOption "Clevis in initrd"; 16 17 18 boot.initrd.clevis.package = mkOption { 19 type = types.package; 20 default = pkgs.clevis; 21 defaultText = "pkgs.clevis"; 22 description = "Clevis package"; 23 }; 24 25 boot.initrd.clevis.devices = mkOption { 26 description = "Encrypted devices that need to be unlocked at boot using Clevis"; 27 default = { }; 28 type = types.attrsOf (types.submodule ({ 29 options.secretFile = mkOption { 30 description = "Clevis JWE file used to decrypt the device at boot, in concert with the chosen pin (one of TPM2, Tang server, or SSS)."; 31 type = types.path; 32 }; 33 })); 34 }; 35 36 boot.initrd.clevis.useTang = mkOption { 37 description = "Whether the Clevis JWE file used to decrypt the devices uses a Tang server as a pin."; 38 default = false; 39 type = types.bool; 40 }; 41 42 }; 43 44 config = mkIf cfg.enable { 45 46 # Implementation of clevis unlocking for the supported filesystems are located directly in the respective modules. 47 48 49 assertions = (attrValues (mapAttrs 50 (device: _: { 51 assertion = (any (fs: fs.device == device && (elem fs.fsType supportedFs)) config.system.build.fileSystems) || (hasAttr device config.boot.initrd.luks.devices); 52 message = '' 53 No filesystem or LUKS device with the name ${device} is declared in your configuration.''; 54 }) 55 cfg.devices)); 56 57 58 warnings = 59 if cfg.useTang && !config.boot.initrd.network.enable && !config.boot.initrd.systemd.network.enable 60 then [ "In order to use a Tang pinned secret you must configure networking in initrd" ] 61 else [ ]; 62 63 boot.initrd = { 64 extraUtilsCommands = mkIf (!systemd.enable) '' 65 copy_bin_and_libs ${pkgs.jose}/bin/jose 66 copy_bin_and_libs ${pkgs.curl}/bin/curl 67 copy_bin_and_libs ${pkgs.bash}/bin/bash 68 69 copy_bin_and_libs ${pkgs.tpm2-tools}/bin/.tpm2-wrapped 70 mv $out/bin/{.tpm2-wrapped,tpm2} 71 cp {${pkgs.tpm2-tss},$out}/lib/libtss2-tcti-device.so.0 72 73 copy_bin_and_libs ${cfg.package}/bin/.clevis-wrapped 74 mv $out/bin/{.clevis-wrapped,clevis} 75 76 for BIN in ${cfg.package}/bin/clevis-decrypt*; do 77 copy_bin_and_libs $BIN 78 done 79 80 for BIN in $out/bin/clevis{,-decrypt{,-null,-tang,-tpm2}}; do 81 sed -i $BIN -e 's,${pkgs.bash},,' -e 's,${pkgs.coreutils},,' 82 done 83 84 sed -i $out/bin/clevis-decrypt-tpm2 -e 's,tpm2_,tpm2 ,' 85 ''; 86 87 secrets = lib.mapAttrs' (name: value: nameValuePair "/etc/clevis/${name}.jwe" value.secretFile) cfg.devices; 88 89 systemd = { 90 extraBin = mkIf systemd.enable { 91 clevis = "${cfg.package}/bin/clevis"; 92 curl = "${pkgs.curl}/bin/curl"; 93 }; 94 95 storePaths = mkIf systemd.enable [ 96 cfg.package 97 "${pkgs.jose}/bin/jose" 98 "${pkgs.curl}/bin/curl" 99 "${pkgs.tpm2-tools}/bin/tpm2_createprimary" 100 "${pkgs.tpm2-tools}/bin/tpm2_flushcontext" 101 "${pkgs.tpm2-tools}/bin/tpm2_load" 102 "${pkgs.tpm2-tools}/bin/tpm2_unseal" 103 ]; 104 }; 105 }; 106 }; 107}