boot.initrd.luks.devices: Change into an attribute set

This allows setting options for the same LUKS device in different
modules. For example, the auto-generated hardware-configuration.nix
can contain

boot.initrd.luks.devices.crypted.device = "/dev/disk/...";

while configuration.nix can add

boot.initrd.luks.devices.crypted.allowDiscards = true;

Also updated the examples/docs to use /disk/disk/by-uuid instead of
/dev/sda, since we shouldn't promote the use of the latter.

+29 -30
+6 -6
nixos/doc/manual/configuration/luks-file-systems.xml
··· 9 <para>NixOS supports file systems that are encrypted using 10 <emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example, 11 here is how you create an encrypted Ext4 file system on the device 12 - <filename>/dev/sda2</filename>: 13 14 <screen> 15 - $ cryptsetup luksFormat /dev/sda2 16 17 WARNING! 18 ======== 19 - This will overwrite data on /dev/sda2 irrevocably. 20 21 Are you sure? (Type uppercase yes): YES 22 Enter LUKS passphrase: *** 23 Verify passphrase: *** 24 25 - $ cryptsetup luksOpen /dev/sda2 crypted 26 - Enter passphrase for /dev/sda2: *** 27 28 $ mkfs.ext4 /dev/mapper/crypted 29 </screen> ··· 33 <filename>configuration.nix</filename>: 34 35 <programlisting> 36 - boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ]; 37 fileSystems."/".device = "/dev/mapper/crypted"; 38 </programlisting> 39
··· 9 <para>NixOS supports file systems that are encrypted using 10 <emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example, 11 here is how you create an encrypted Ext4 file system on the device 12 + <filename>/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d</filename>: 13 14 <screen> 15 + $ cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d 16 17 WARNING! 18 ======== 19 + This will overwrite data on /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d irrevocably. 20 21 Are you sure? (Type uppercase yes): YES 22 Enter LUKS passphrase: *** 23 Verify passphrase: *** 24 25 + $ cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted 26 + Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: *** 27 28 $ mkfs.ext4 /dev/mapper/crypted 29 </screen> ··· 33 <filename>configuration.nix</filename>: 34 35 <programlisting> 36 + boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d"; 37 fileSystems."/".device = "/dev/mapper/crypted"; 38 </programlisting> 39
+21 -21
nixos/modules/system/boot/luksroot.nix
··· 5 let 6 luks = config.boot.initrd.luks; 7 8 - openCommand = { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: '' 9 # Wait for luksRoot to appear, e.g. if on a usb drive. 10 # XXX: copied and adapted from stage-1-init.sh - should be 11 # available as a function. ··· 192 ''} 193 ''; 194 195 - isPreLVM = f: f.preLVM; 196 - preLVM = filter isPreLVM luks.devices; 197 - postLVM = filter (f: !(isPreLVM f)) luks.devices; 198 199 in 200 { ··· 228 }; 229 230 boot.initrd.luks.devices = mkOption { 231 - default = [ ]; 232 - example = literalExample ''[ { name = "luksroot"; device = "/dev/sda3"; preLVM = true; } ]''; 233 description = '' 234 - The list of devices that should be decrypted using LUKS before trying to mount the 235 - root partition. This works for both LVM-over-LUKS and LUKS-over-LVM setups. 236 - 237 - The devices are decrypted to the device mapper names defined. 238 - 239 - Make sure that initrd has the crypto modules needed for decryption. 240 ''; 241 242 - type = types.listOf types.optionSet; 243 244 - options = { 245 246 name = mkOption { 247 example = "luksroot"; 248 type = types.str; 249 - description = "Named to be used for the generated device in /dev/mapper."; 250 }; 251 252 device = mkOption { 253 - example = "/dev/sda2"; 254 type = types.str; 255 - description = "Path of the underlying block device."; 256 }; 257 258 header = mkOption { ··· 289 ''; 290 }; 291 292 preLVM = mkOption { 293 default = true; 294 type = types.bool; ··· 394 }; 395 }; 396 397 - }; 398 }; 399 400 boot.initrd.luks.yubikeySupport = mkOption { ··· 408 }; 409 }; 410 411 - config = mkIf (luks.devices != []) { 412 413 # actually, sbp2 driver is the one enabling the DMA attack, but this needs to be tested 414 boot.blacklistedKernelModules = optionals luks.mitigateDMAAttacks ··· 463 ''} 464 ''; 465 466 - boot.initrd.preLVMCommands = concatMapStrings openCommand preLVM; 467 - boot.initrd.postDeviceCommands = concatMapStrings openCommand postLVM; 468 469 environment.systemPackages = [ pkgs.cryptsetup ]; 470 };
··· 5 let 6 luks = config.boot.initrd.luks; 7 8 + openCommand = name': { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: assert name' == name; '' 9 # Wait for luksRoot to appear, e.g. if on a usb drive. 10 # XXX: copied and adapted from stage-1-init.sh - should be 11 # available as a function. ··· 192 ''} 193 ''; 194 195 + preLVM = filterAttrs (n: v: v.preLVM) luks.devices; 196 + postLVM = filterAttrs (n: v: !v.preLVM) luks.devices; 197 198 in 199 { ··· 227 }; 228 229 boot.initrd.luks.devices = mkOption { 230 + default = { }; 231 + example = { "luksroot".device = "/dev/disk/by-uuid/430e9eff-d852-4f68-aa3b-2fa3599ebe08"; }; 232 description = '' 233 + The encrypted disk that should be opened before the root 234 + filesystem is mounted. Both LVM-over-LUKS and LUKS-over-LVM 235 + setups are sypported. The unencrypted devices can be accessed as 236 + <filename>/dev/mapper/<replaceable>name</replaceable></filename>. 237 ''; 238 239 + type = types.loaOf types.optionSet; 240 241 + options = { name, ... }: { options = { 242 243 name = mkOption { 244 + visible = false; 245 + default = name; 246 example = "luksroot"; 247 type = types.str; 248 + description = "Name of the unencrypted device in <filename>/dev/mapper</filename>."; 249 }; 250 251 device = mkOption { 252 + example = "/dev/disk/by-uuid/430e9eff-d852-4f68-aa3b-2fa3599ebe08"; 253 type = types.str; 254 + description = "Path of the underlying encrypted block device."; 255 }; 256 257 header = mkOption { ··· 288 ''; 289 }; 290 291 + # FIXME: get rid of this option. 292 preLVM = mkOption { 293 default = true; 294 type = types.bool; ··· 394 }; 395 }; 396 397 + }; }; 398 }; 399 400 boot.initrd.luks.yubikeySupport = mkOption { ··· 408 }; 409 }; 410 411 + config = mkIf (luks.devices != {}) { 412 413 # actually, sbp2 driver is the one enabling the DMA attack, but this needs to be tested 414 boot.blacklistedKernelModules = optionals luks.mitigateDMAAttacks ··· 463 ''} 464 ''; 465 466 + boot.initrd.preLVMCommands = concatStrings (mapAttrsToList openCommand preLVM); 467 + boot.initrd.postDeviceCommands = concatStrings (mapAttrsToList openCommand postLVM); 468 469 environment.systemPackages = [ pkgs.cryptsetup ]; 470 };
+1 -1
nixos/modules/virtualisation/qemu-vm.nix
··· 465 }); 466 467 swapDevices = mkVMOverride [ ]; 468 - boot.initrd.luks.devices = mkVMOverride []; 469 470 # Don't run ntpd in the guest. It should get the correct time from KVM. 471 services.ntp.enable = false;
··· 465 }); 466 467 swapDevices = mkVMOverride [ ]; 468 + boot.initrd.luks.devices = mkVMOverride {}; 469 470 # Don't run ntpd in the guest. It should get the correct time from KVM. 471 services.ntp.enable = false;
+1 -2
nixos/tests/installer.nix
··· 363 # XXX: Currently, generate-config doesn't detect LUKS yet. 364 extraConfig = '' 365 boot.kernelParams = lib.mkAfter [ "console=tty0" ]; 366 - boot.initrd.luks.devices = lib.singleton { 367 - name = "cryptroot"; 368 device = "/dev/vda3"; 369 preLVM = true; 370 };
··· 363 # XXX: Currently, generate-config doesn't detect LUKS yet. 364 extraConfig = '' 365 boot.kernelParams = lib.mkAfter [ "console=tty0" ]; 366 + boot.initrd.luks.devices.cryptroot = { 367 device = "/dev/vda3"; 368 preLVM = true; 369 };