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.
This commit is contained in:
Eelco Dolstra 2016-05-25 13:23:32 +02:00
parent bf2aaeb0f6
commit 845c9b50bf
4 changed files with 29 additions and 30 deletions

View file

@ -9,21 +9,21 @@
<para>NixOS supports file systems that are encrypted using
<emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example,
here is how you create an encrypted Ext4 file system on the device
<filename>/dev/sda2</filename>:
<filename>/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d</filename>:
<screen>
$ cryptsetup luksFormat /dev/sda2
$ cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d
WARNING!
========
This will overwrite data on /dev/sda2 irrevocably.
This will overwrite data on /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d irrevocably.
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ***
Verify passphrase: ***
$ cryptsetup luksOpen /dev/sda2 crypted
Enter passphrase for /dev/sda2: ***
$ cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted
Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
$ mkfs.ext4 /dev/mapper/crypted
</screen>
@ -33,7 +33,7 @@ as <filename>/</filename>, add the following to
<filename>configuration.nix</filename>:
<programlisting>
boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ];
boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
fileSystems."/".device = "/dev/mapper/crypted";
</programlisting>

View file

@ -5,7 +5,7 @@ with lib;
let
luks = config.boot.initrd.luks;
openCommand = { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: ''
openCommand = name': { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: assert name' == name; ''
# Wait for luksRoot to appear, e.g. if on a usb drive.
# XXX: copied and adapted from stage-1-init.sh - should be
# available as a function.
@ -192,9 +192,8 @@ let
''}
'';
isPreLVM = f: f.preLVM;
preLVM = filter isPreLVM luks.devices;
postLVM = filter (f: !(isPreLVM f)) luks.devices;
preLVM = filterAttrs (n: v: v.preLVM) luks.devices;
postLVM = filterAttrs (n: v: !v.preLVM) luks.devices;
in
{
@ -228,31 +227,31 @@ in
};
boot.initrd.luks.devices = mkOption {
default = [ ];
example = literalExample ''[ { name = "luksroot"; device = "/dev/sda3"; preLVM = true; } ]'';
default = { };
example = { "luksroot".device = "/dev/disk/by-uuid/430e9eff-d852-4f68-aa3b-2fa3599ebe08"; };
description = ''
The list of devices that should be decrypted using LUKS before trying to mount the
root partition. This works for both LVM-over-LUKS and LUKS-over-LVM setups.
The devices are decrypted to the device mapper names defined.
Make sure that initrd has the crypto modules needed for decryption.
The encrypted disk that should be opened before the root
filesystem is mounted. Both LVM-over-LUKS and LUKS-over-LVM
setups are sypported. The unencrypted devices can be accessed as
<filename>/dev/mapper/<replaceable>name</replaceable></filename>.
'';
type = types.listOf types.optionSet;
type = types.loaOf types.optionSet;
options = {
options = { name, ... }: { options = {
name = mkOption {
visible = false;
default = name;
example = "luksroot";
type = types.str;
description = "Named to be used for the generated device in /dev/mapper.";
description = "Name of the unencrypted device in <filename>/dev/mapper</filename>.";
};
device = mkOption {
example = "/dev/sda2";
example = "/dev/disk/by-uuid/430e9eff-d852-4f68-aa3b-2fa3599ebe08";
type = types.str;
description = "Path of the underlying block device.";
description = "Path of the underlying encrypted block device.";
};
header = mkOption {
@ -289,6 +288,7 @@ in
'';
};
# FIXME: get rid of this option.
preLVM = mkOption {
default = true;
type = types.bool;
@ -394,7 +394,7 @@ in
};
};
};
}; };
};
boot.initrd.luks.yubikeySupport = mkOption {
@ -408,7 +408,7 @@ in
};
};
config = mkIf (luks.devices != []) {
config = mkIf (luks.devices != {}) {
# actually, sbp2 driver is the one enabling the DMA attack, but this needs to be tested
boot.blacklistedKernelModules = optionals luks.mitigateDMAAttacks
@ -463,8 +463,8 @@ in
''}
'';
boot.initrd.preLVMCommands = concatMapStrings openCommand preLVM;
boot.initrd.postDeviceCommands = concatMapStrings openCommand postLVM;
boot.initrd.preLVMCommands = concatStrings (mapAttrsToList openCommand preLVM);
boot.initrd.postDeviceCommands = concatStrings (mapAttrsToList openCommand postLVM);
environment.systemPackages = [ pkgs.cryptsetup ];
};

View file

@ -465,7 +465,7 @@ in
});
swapDevices = mkVMOverride [ ];
boot.initrd.luks.devices = mkVMOverride [];
boot.initrd.luks.devices = mkVMOverride {};
# Don't run ntpd in the guest. It should get the correct time from KVM.
services.ntp.enable = false;

View file

@ -363,8 +363,7 @@ in {
# XXX: Currently, generate-config doesn't detect LUKS yet.
extraConfig = ''
boot.kernelParams = lib.mkAfter [ "console=tty0" ];
boot.initrd.luks.devices = lib.singleton {
name = "cryptroot";
boot.initrd.luks.devices.cryptroot = {
device = "/dev/vda3";
preLVM = true;
};