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 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.<name?>.device</literal> to <literal>/dev/mapper/<label></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 = "File system location of keyfile. This unlocks the drive after the root has been mounted to <literal>/mnt-root</literal>.";
41 };
42 };
43 };
44in
45
46{
47
48 options = {
49 fileSystems = mkOption {
50 options = [encryptedFSOptions];
51 };
52 swapDevices = mkOption {
53 options = [encryptedFSOptions];
54 };
55 };
56
57 config = mkIf anyEncrypted {
58 assertions = map (dev: {
59 assertion = dev.encrypted.label != null;
60 message = ''
61 The filesystem for ${dev.mountPoint} has encrypted.enable set to true, but no encrypted.label set
62 '';
63 }) encDevs;
64
65 boot.initrd = {
66 luks = {
67 devices =
68 map (dev: { name = dev.encrypted.label; device = dev.encrypted.blkDev; } ) keylessEncDevs;
69 forceLuksSupportInInitrd = true;
70 };
71 postMountCommands =
72 concatMapStrings (dev: "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n") keyedEncDevs;
73 };
74 };
75}
76