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