diff options
Diffstat (limited to 'sys/boot/stack')
| -rw-r--r-- | sys/boot/stack/btrfs-toplevel-multidrive.nix | 99 | ||||
| -rw-r--r-- | sys/boot/stack/default.nix | 6 | ||||
| -rw-r--r-- | sys/boot/stack/luks-ext4-fscrypt-impermanence.nix | 98 |
3 files changed, 203 insertions, 0 deletions
diff --git a/sys/boot/stack/btrfs-toplevel-multidrive.nix b/sys/boot/stack/btrfs-toplevel-multidrive.nix new file mode 100644 index 0000000..52db865 --- /dev/null +++ b/sys/boot/stack/btrfs-toplevel-multidrive.nix @@ -0,0 +1,99 @@ +{ + config, + lib, + ... +}: +with lib; let + cfg = config.local.boot.stack.btrfsToplevelMultidrive; +in { + options.local.boot.stack.btrfsToplevelMultidrive = { + enable = mkEnableOption "filesystem stack: persistent btrfs toplevel with optional hdd drive"; + + toplevel = { + device = mkOption { + type = types.str; + }; + + ssd = mkOption { + type = types.bool; + }; + + snapshot = mkOption { + type = types.bool; + default = false; + }; + + root = mkOption { + type = types.str; + }; + + pivot = mkOption { + type = types.str; + default = "/"; + }; + }; + + secondary = { + device = mkOption { + type = types.str; + }; + + ssd = mkOption { + type = types.bool; + }; + + snapshot = mkOption { + type = types.bool; + default = false; + }; + + home = mkOption { + type = types.str; + }; + + pivot = mkOption { + type = types.str; + default = "/"; + }; + }; + }; + + config = mkIf cfg.enable { + local.btrfs = { + mounts = { + "/" = { + inherit (cfg.toplevel) device ssd; + subvol = cfg.toplevel.root; + }; + + "/toplevel" = { + inherit (cfg.toplevel) device ssd; + subvol = cfg.toplevel.pivot; + }; + + #FIXME: Este nombre es legacy + "/hdd" = { + inherit (cfg.secondary) device ssd; + subvol = cfg.secondary.pivot; + }; + + "/home" = { + inherit (cfg.secondary) device ssd; + subvol = cfg.secondary.home; + }; + }; + + snapper = + optionalAttrs cfg.toplevel.snapshot + { + root = "/"; + } + // optionalAttrs cfg.secondary.snapshot { + home = "/home"; + }; + }; + + # Asegura que /hdd sea descifrado antes de intentar montar /home + fileSystems."/home".depends = ["/hdd"]; + }; +} diff --git a/sys/boot/stack/default.nix b/sys/boot/stack/default.nix new file mode 100644 index 0000000..ff211e6 --- /dev/null +++ b/sys/boot/stack/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./btrfs-toplevel-multidrive.nix + ./luks-ext4-fscrypt-impermanence.nix + ]; +} diff --git a/sys/boot/stack/luks-ext4-fscrypt-impermanence.nix b/sys/boot/stack/luks-ext4-fscrypt-impermanence.nix new file mode 100644 index 0000000..81feb60 --- /dev/null +++ b/sys/boot/stack/luks-ext4-fscrypt-impermanence.nix @@ -0,0 +1,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; + }; + }; +} |
