blob: 81feb60611bff1ab86efee4713225d18b1882f15 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.local.boot.stack.luksExt4FscryptImpermanence;
in {
options.local.boot.stack.luksExt4FscryptImpermanence = {
enable = mkEnableOption "filesystem stack: whatever LUKS approach+ext4+impermanence with per-boot keys";
target = mkOption {
type = types.str;
};
};
# - boot device
# - some unknown fs, probably vfat
# - detached luks header file
#
# - toplevel device
# - headerless luks
# - /toplevel (ext4)
# - /toplevel/nix
# - /toplevel/persist
# - /toplevel/boot-archive.pub
# - /toplevel/boot-keys
# - /toplevel/boot-keys/2000-01-01T00:00:00-06:00.key.crypt (encrypted for /toplevel/boot-archive.pub)
# - /toplevel/boot-keys/...
# - /toplevel/boot-keys/last.key.crypt -> 2000-01-01T00:00:00-06:00.key.crypt
# - /toplevel/boots
# - /toplevel/boots/2000-01-01T00:00:00-06:00 (raw protector in last.key.crypt)
# - /toplevel/boots/...
# - /toplevel/boots/last -> 2000-01-01T00:00:00-06:00 (mounted as /)
config = mkIf cfg.enable {
boot.initrd.luks.devices.${cfg.target}.postOpenCommands = let
fscryptctl = "${pkgs.fscryptctl}/bin/fscryptctl";
in ''
# FIXME: posiblemente algunos --make-* son innecesarios a partir de aquí
mkdir -p /mnt-root /mnt-toplevel
mount -o noatime /dev/mapper/${cfg.target} /mnt-toplevel
mount --make-private /mnt-toplevel
boot_stamp="$(date -Is)"
root_from_toplevel="/mnt-toplevel/boots/$boot_stamp"
mkdir -p "$root_from_toplevel" /mnt-toplevel/boot-keys
chmod 700 /mnt-toplevel/boot-keys
head -c64 /dev/urandom >/boot-key
key_id=$(${fscryptctl} add_key /mnt-toplevel </boot-key)
${fscryptctl} set_policy "$key_id" "$root_from_toplevel"
(umask 077; test -f /mnt-toplevel/boot-archive.pub && \
${pkgs.openssl}/bin/openssl pkeyutl -encrypt \
-in /boot-key -pubin -inkey /mnt-toplevel/boot-archive.pub \
-out "/mnt-toplevel/boot-keys/$boot_stamp.key.crypt")
rm -f /boot-key
ln -Tsf "$boot_stamp" /mnt-toplevel/boots/last
ln -Tsf "$boot_stamp.key.crypt" /mnt-toplevel/boot-keys/last.key.crypt
mount --bind "$root_from_toplevel" /mnt-root
mount --make-shared /mnt-root
# mount --move es mala idea, ya que "moving a mount residing under a
# shared mount is unsupported"
mkdir -p /mnt-root/toplevel
mount --bind /mnt-toplevel /mnt-root/toplevel
mount --make-private /mnt-root/toplevel
umount /mnt-toplevel
'';
fileSystems = {
"/" = {
device = "none";
fsType = "ext4";
options = ["remount"];
};
"/nix" = {
device = "/persist/nix";
options = ["bind"];
};
"/persist" = {
device = "/toplevel/persist";
options = ["bind"];
neededForBoot = true;
};
};
local.boot = {
fscrypt.enable = true;
impermanence.enable = true;
};
};
}
|