Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disko: Enable Luks disk encryption #517

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/common/hardware/definition.nix
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,18 @@
Path to the disk
'';
};
options.imageSize = mkOption {
type = types.str;
description = ''
Size of the image
'';
};
});
default = {};
example = literalExpression ''
{
disk1.device = "/dev/nvme0n1";
disk1.imageSize = "100G"
}
'';
};
Expand Down
9 changes: 8 additions & 1 deletion modules/common/hardware/lenovo-x1/definitions/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@
in {
inherit (hwDefinition) mouse;
inherit (hwDefinition) touchpad;
inherit (hwDefinition) disks;
inherit (hwDefinition) network;
inherit (hwDefinition) gpu;

disks = {
disk1.device = "/dev/nvme0n1";
# 250G is the size of the 1st LVM pool, 10G is reserved for the second LVM pool
# Second LVM pool can be extended safely to the end of the disk, and its restricted size
# makes flashing quicker.
disk1.imageSize = "260G";
};

# Notes:
# 1. This assembles udev rules for different hw configurations (i.e., different mice/touchpads) by adding
# all of them to the configuration. This was chosen for simplicity to not have to provide hw identifier at build,
Expand Down
4 changes: 0 additions & 4 deletions modules/common/hardware/lenovo-x1/definitions/x1-gen10.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
mouse = ["ELAN067B:00 04F3:31F8 Mouse" "SYNA8016:00 06CB:CEB3 Mouse"];
touchpad = ["ELAN067B:00 04F3:31F8 Touchpad" "SYNA8016:00 06CB:CEB3 Touchpad"];

disks = {
disk1.device = "/dev/nvme0n1";
};

network.pciDevices = [
{
# Passthrough Intel WiFi card
Expand Down
4 changes: 0 additions & 4 deletions modules/common/hardware/lenovo-x1/definitions/x1-gen11.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
"ELAN067B:00 04F3:31F8 Touchpad"
];

disks = {
disk1.device = "/dev/nvme0n1";
};

network.pciDevices = [
{
# Passthrough Intel WiFi card
Expand Down
181 changes: 181 additions & 0 deletions modules/disko/disko-ab-partitions.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
#
# !!! To utilize this partition scheme, the disk size must be >252G !!!
#
# This partition scheme contains three common partitions and two LVM pools.
# First LVM pool occupies 250G and second one occupies the rest of the disk space.
# Some paritions are duplicated for the future AB SWupdate implementation.
#
# First three partitions are related to the boot process:
# - boot : Bootloader partition
# - ESP-A : (500M) Kernel and initrd
# - ESP-B : (500M)
#
# First LVM pool contains next partitions:
# - root-A : (50G) Root FS
# - root-B : (50G)
# - vm-storage-A : (30G) Possible standalone pre-built VM images are stored here
# - vm-storage-B : (30G)
# - reserved-A : (10G) Reserved partition, no use
# - reserved-B : (10G)
# - gp-storage : (50G) General purpose storage for some common insecure cases
# - recovery : (rest of the LVM pool) Recovery factory image is stored here
#
# Second LVM pool is dedicated for Storage VM completely.
_: {
disko.memSize = 2048;
disko.devices = {
disk.disk1 = {
type = "disk";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "EF02";
};
esp_a = {
name = "ESP_A";
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"umask=0077"
"nofail"
];
};
};
esp_b = {
name = "ESP_B";
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountOptions = [
"umask=0077"
"nofail"
];
};
};
other_1 = {
name = "lvm_pv_1";
size = "250G";
content = {
type = "lvm_pv";
vg = "pool";
};
};
# LVM pool that is going to be passed to the Storage VM
other_2 = {
name = "lvm_pv_2";
size = "100%";
content = {
type = "lvm_pv";
vg = "vmstore";
};
};
};
};
};
lvm_vg = {
pool = {
type = "lvm_vg";
lvs = {
root_a = {
size = "50G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
"noatime"
];
};
};
vm_storage_a = {
size = "30G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/vmstore";
mountOptions = [
"defaults"
"nofail"
"noatime"
];
};
};
reserved_a = {
size = "10G";
};
root_b = {
size = "50G";
content = {
type = "filesystem";
format = "ext4";
mountOptions = [
"defaults"
"noatime"
];
};
};
vm_storage_b = {
size = "30G";
content = {
type = "filesystem";
format = "ext4";
mountOptions = [
"defaults"
"nofail"
"noatime"
];
};
};
reserved_b = {
size = "10G";
};
gp_storage = {
size = "50G";
content = {
type = "filesystem";
format = "ext4";
mountOptions = [
"defaults"
"nofail"
"noatime"
];
};
};
recovery = {
size = "100%FREE";
};
};
};
vmstore = {
# Dedicated partition for StorageVM
type = "lvm_vg";
lvs = {
storagevm = {
size = "100%FREE";
content = {
type = "filesystem";
format = "ext4";
mountOptions = [
"defaults"
"nofail"
"noatime"
];
};
};
};
};
};
};
}
42 changes: 41 additions & 1 deletion modules/disko/disko-basic-postboot.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{pkgs, ...}: let
{
pkgs,
config,
lib,
...
}: let
cfg = config.ghaf.disk.encryption;
encryptionCmds =
if cfg.enable
then ''
partitions_to_encrypt=("/dev/mapper/pool-vm_storage_a" "/dev/mapper/pool-vm_storage_b")
readarray -t pd_partitions <<<"$(${pkgs.util-linux}/bin/lsblk -no PATH,FSTYPE,UUID $PARENT_DISK)"

# Find out the partition which needs to be encrypted in a loop
for pp in "''${pd_partitions[@]}"
do
P_DEVPATH=$(echo "$pp" | ${pkgs.gawk}/bin/awk '{print $1}')
P_FSTYPE=$(echo "$pp" | ${pkgs.gawk}/bin/awk '{print $2}')
P_DEVUUID=$(echo "$pp" | ${pkgs.gawk}/bin/awk '{print $3}')
if (${pkgs.coreutils}/bin/printf '%s\n' "''${partitions_to_encrypt[@]}" | ${pkgs.gnugrep}/bin/grep -q -x "$P_DEVPATH"); then
FOUND=1
else
FOUND=0
fi
[[ "$FOUND" != 0 && "$P_FSTYPE" == "ext4" ]] && {
echo -n "ghaf" | ${pkgs.cryptsetup}/bin/cryptsetup luksFormat -q $P_DEVPATH
echo -n "ghaf" | ${pkgs.cryptsetup}/bin/cryptsetup open $P_DEVPATH crypt-$P_DEVUUID
${pkgs.e2fsprogs}/bin/mkfs.ext4 /dev/mapper/crypt-$P_DEVUUID
PASSWORD=ghaf ${pkgs.systemd}/bin/systemd-cryptenroll --fido2-device=auto --fido2-with-client-pin=yes $P_DEVPATH
}
done
''
else "";

postBootCmds = ''
set -xeuo pipefail

Expand Down Expand Up @@ -38,6 +71,9 @@
}
done

# Currently with new disk partitioning scheme resizing won't have impact, so encrypting here
${encryptionCmds}

# If boot device was not found, exit at this point, but still return 0, so it
# won't stop device from booting.
[[ "$FOUND_PARENT" != 1 ]] && echo "Did not find boot device" && exit 0
Expand All @@ -59,4 +95,8 @@
'';
in {
boot.postBootCommands = postBootCmds;
boot.initrd.luks.devices = lib.mkIf cfg.enable {
"crypt-pool-vm_storage_b".device = "/dev/mapper/pool-vm_storage_b";
"crypt-pool-vm_storage_a".device = "/dev/mapper/pool-vm_storage_a";
};
}
7 changes: 7 additions & 0 deletions modules/disko/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,12 @@
./lenovo-x1-disko-basic.nix
./disko-basic-postboot.nix
];

disko-ab-partitions-v1.imports = [
inputs.disko.nixosModules.disko
./disko-ab-partitions.nix
./lenovo-x1-disk-encryption.nix
./disko-basic-postboot.nix
];
};
}
10 changes: 10 additions & 0 deletions modules/disko/lenovo-x1-disk-encryption.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright 2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{lib, ...}:
with lib; {
options.ghaf.disk.encryption.enable = mkOption {
description = "Enable Ghaf disk encryption";
type = types.bool;
default = false;
};
}
2 changes: 1 addition & 1 deletion targets/lenovo-x1/everything.nix
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
self.nixosModules.lanzaboote
self.nixosModules.microvm

self.nixosModules.disko-lenovo-x1-basic-v1
self.nixosModules.disko-ab-partitions-v1

./sshkeys.nix
({
Expand Down