Skip to content

Commit

Permalink
Add full disk encryption to image module
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbaur committed Jan 5, 2024
1 parent e4b26c5 commit 1118a78
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 16 deletions.
7 changes: 4 additions & 3 deletions checks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ inputs:
inputs.nixpkgs.lib.mapAttrs
(_: pkgs: {
inherit (pkgs.callPackage ./tests/image.nix { })
image-simple-immutable
image-simple-mutable
# image-luks-encrypted
image-immutable
image-mutable
image-unencrypted
image-tpm2-encrypted
;
})
inputs.self.legacyPackages
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 27 additions & 4 deletions nixos-modules/image/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ let

maxUsrSize = cfg.immutableMaxSize;
maxUsrHashSize = maxUsrSize / 8;

encrypt = if cfg.encrypt then (if cfg.hasTpm2 then "tpm2" else "key-file") else "none";
in
{
options.custom.image = with lib; {
Expand All @@ -19,6 +21,8 @@ in

hasTpm2 = mkEnableOption "TODO";

encrypt = mkEnableOption "TODO" // { default = true; };

mutableNixStore = mkEnableOption "TODO";

postImageCommands = mkOption {
Expand Down Expand Up @@ -81,6 +85,10 @@ in

# Tell systemd to not automount anything on /usr. We don't
# actually have a /usr mount in our fstab...
#
# TODO(jared): we should be using the SD_GPT_FLAG_NO_AUTO partition flag
# to indicate that the partition should not be auto-mounted. See
# https://uapi-group.org/specifications/specs/discoverable_partitions_specification/#partition-attribute-flags
"mount.usr=fstab"
];

Expand Down Expand Up @@ -150,7 +158,13 @@ in
repart.device = cfg.primaryDisk;
};

availableKernelModules = [ "dm-verity" ] ++ lib.optional cfg.mutableNixStore "overlay";
availableKernelModules = [
"dm_verity"

# systemd-repart wants to use loop devices for doing "online" partition
# creation
"loop"
] ++ lib.optional cfg.mutableNixStore "overlay";
};

systemd.repart.partitions = {
Expand Down Expand Up @@ -193,18 +207,27 @@ in
Format = "btrfs";
FactoryReset = true;
MakeDirectories = lib.mkIf cfg.mutableNixStore (toString [ "/nix/.rw-store/store" "/nix/.rw-store/work" ]);
# TODO(jared): doesn't work?
# Encrypt = if cfg.hasTpm2 then "tpm2" else "off";
Encrypt = encrypt;
};
};

boot.initrd.luks.devices.root = lib.mkIf cfg.encrypt {
device = "/dev/disk/by-partlabel/${config.systemd.repart.partitions."30-root".Label}";
crypttabExtraOpts = lib.optional cfg.hasTpm2 "tpm2-device=auto";
tryEmptyPassphrase = !cfg.hasTpm2;
};

# enable zram by default since we don't create any swap partitions
zramSwap.enable = lib.mkDefault true;

fileSystems."/" = {
device = "/dev/disk/by-partlabel/${config.systemd.repart.partitions."30-root".Label}";
fsType = config.systemd.repart.partitions."30-root".Format;
options = [ "compress=zstd" "noatime" "defaults" ];
device =
if cfg.encrypt then
"/dev/mapper/root"
else
"/dev/disk/by-partlabel/${config.systemd.repart.partitions."30-root".Label}";
};
fileSystems."/nix/.ro-store" = {
device = "/dev/mapper/usr";
Expand Down
8 changes: 5 additions & 3 deletions nixos-modules/image/image.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
}:

let
iniFormat = formats.ini { };

seed = "39c4020e-af73-434a-93e4-7e37fdcc7f96";

bootPartition = partitions."10-boot" // { };
Expand Down Expand Up @@ -50,9 +52,9 @@ let
systemdArchitecture = builtins.replaceStrings [ "_" ] [ "-" ] stdenv.hostPlatform.linuxArch;
closure = closureInfo { rootPaths = [ toplevel ]; };

bootPartitionConfig = (formats.ini { }).generate "10-boot.conf" { Partition = bootPartition; };
dataPartitionConfig = (formats.ini { }).generate "20-usr-a.conf" { Partition = dataPartition; };
hashPartitionConfig = (formats.ini { }).generate "20-usr-a-hash.conf" { Partition = hashPartition; };
bootPartitionConfig = iniFormat.generate "10-boot.conf" { Partition = bootPartition; };
dataPartitionConfig = iniFormat.generate "20-usr-a.conf" { Partition = dataPartition; };
hashPartitionConfig = iniFormat.generate "20-usr-a-hash.conf" { Partition = hashPartition; };
in
stdenv.mkDerivation {
name = "nixos-image-${imageName}";
Expand Down
10 changes: 7 additions & 3 deletions tests/image.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let
# Make the qemu-vm.nix module use what is found under
# `config.fileSystems`.
virtualisation.fileSystems = lib.mkForce { };
virtualisation.useDefaultFilesystems = false;

custom.image = {
enable = true;
Expand Down Expand Up @@ -68,6 +69,8 @@ lib.mapAttrs'
# Set NIX_DISK_IMAGE so that the qemu script finds the right disk image.
os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
machine.start(allow_reboot=True)
bootctl_status = machine.succeed("bootctl status")
def disk_size(partlabel):
Expand Down Expand Up @@ -99,9 +102,10 @@ lib.mapAttrs'
'';
}))
{
simple-immutable = { };
simple-mutable = { custom.image.mutableNixStore = true; };
luks-encrypted = {
immutable = { };
mutable = { custom.image.mutableNixStore = true; };
unencrypted = { custom.image.encrypt = false; };
tpm2-encrypted = {
virtualisation.tpm.enable = true;
custom.image.hasTpm2 = true;
};
Expand Down

0 comments on commit 1118a78

Please sign in to comment.