at 21.11-pre 2.7 kB view raw
1{ config, lib, ... }: 2 3with lib; 4 5let 6 fileSystems = config.system.build.fileSystems ++ config.swapDevices; 7 encDevs = filter (dev: dev.encrypted.enable) fileSystems; 8 keyedEncDevs = filter (dev: dev.encrypted.keyFile != null) encDevs; 9 keylessEncDevs = filter (dev: dev.encrypted.keyFile == null) encDevs; 10 anyEncrypted = 11 fold (j: v: v || j.encrypted.enable) false encDevs; 12 13 encryptedFSOptions = { 14 15 options.encrypted = { 16 enable = mkOption { 17 default = false; 18 type = types.bool; 19 description = "The block device is backed by an encrypted one, adds this device as a initrd luks entry."; 20 }; 21 22 blkDev = mkOption { 23 default = null; 24 example = "/dev/sda1"; 25 type = types.nullOr types.str; 26 description = "Location of the backing encrypted device."; 27 }; 28 29 label = mkOption { 30 default = null; 31 example = "rootfs"; 32 type = types.nullOr types.str; 33 description = "Label of the unlocked encrypted device. Set <literal>fileSystems.&lt;name?&gt;.device</literal> to <literal>/dev/mapper/&lt;label&gt;</literal> to mount the unlocked device."; 34 }; 35 36 keyFile = mkOption { 37 default = null; 38 example = "/mnt-root/root/.swapkey"; 39 type = types.nullOr types.str; 40 description = '' 41 Path to a keyfile used to unlock the backing encrypted 42 device. At the time this keyfile is accessed, the 43 <literal>neededForBoot</literal> filesystems (see 44 <literal>fileSystems.&lt;name?&gt;.neededForBoot</literal>) 45 will have been mounted under <literal>/mnt-root</literal>, 46 so the keyfile path should usually start with "/mnt-root/". 47 ''; 48 }; 49 }; 50 }; 51in 52 53{ 54 55 options = { 56 fileSystems = mkOption { 57 type = with lib.types; attrsOf (submodule encryptedFSOptions); 58 }; 59 swapDevices = mkOption { 60 type = with lib.types; listOf (submodule encryptedFSOptions); 61 }; 62 }; 63 64 config = mkIf anyEncrypted { 65 assertions = map (dev: { 66 assertion = dev.encrypted.label != null; 67 message = '' 68 The filesystem for ${dev.mountPoint} has encrypted.enable set to true, but no encrypted.label set 69 ''; 70 }) encDevs; 71 72 boot.initrd = { 73 luks = { 74 devices = 75 builtins.listToAttrs (map (dev: { 76 name = dev.encrypted.label; 77 value = { device = dev.encrypted.blkDev; }; 78 }) keylessEncDevs); 79 forceLuksSupportInInitrd = true; 80 }; 81 postMountCommands = 82 concatMapStrings (dev: 83 "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n" 84 ) keyedEncDevs; 85 }; 86 }; 87}