Skip to content

Commit

Permalink
secure-boot: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
linyinfeng committed Dec 8, 2023
1 parent 7c8cdc9 commit ca09970
Show file tree
Hide file tree
Showing 24 changed files with 530 additions and 122 deletions.
1 change: 1 addition & 0 deletions devshell/terraform.nix
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
openssl
ruby
yq-go
efitools
encryptTo
];
text = ''
Expand Down
20 changes: 19 additions & 1 deletion lib/data/data.json

Large diffs are not rendered by default.

22 changes: 20 additions & 2 deletions lib/data/template.yq
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"as198764_v6_cidr": .as198764_v6_cidr.value,
"as198764_anycast_address": .as198764_anycast_address.value,

"ca_cert_pem": .ca_cert_pem.value,

"cache_s3_url": .b2_s3_api_url.value,
"cache_s3_host": .b2_s3_api_host.value,
"mastodon_media_region": .b2_s3_region.value,
Expand Down Expand Up @@ -37,6 +35,26 @@
}
},

"ca_cert_pem": .ca_cert_pem.value,
"secure_boot": {
"signature_owner_guid": .secure_boot_signature_owner_guid.value,
"platform_key": {
"certificate_pem": .secure_boot_pk_cert_pem.value,
"efi_signature_list_base64": .secure_boot_pk_esl_base64.value,
"signed_efi_signature_list_base64": .secure_boot_pk_signed_esl_base64.value
},
"key_exchange_key": {
"certificate_pem": .secure_boot_kek_cert_pem.value,
"efi_signature_list_base64": .secure_boot_kek_esl_base64.value,
"signed_efi_signature_list_base64": .secure_boot_kek_signed_esl_base64.value
},
"database": {
"certificate_pem": .secure_boot_db_cert_pem.value,
"efi_signature_list_base64": .secure_boot_db_esl_base64.value,
"signed_efi_signature_list_base64": .secure_boot_db_signed_esl_base64.value
}
},

"hosts": .hosts.value | map_values(
with_entries(
select(
Expand Down
4 changes: 2 additions & 2 deletions nixos/hosts/framework/_hardware.nix
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@
# currently nothing
];
};
# out-of-tree module "kvmfr" required
# because kernel needs to be recompiled
# enable lockdown by the way
# enable module signing and lockdown by the way
boot.kernelModuleSigning.enable = true;
boot.kernelLockdown = true;
}
62 changes: 2 additions & 60 deletions nixos/hosts/framework/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ in {
nix.access-tokens
nix.nixbuild
nix.hydra-builder-client
nix.hydra-builder-server
security.tpm
networking.wireguard-home
networking.behind-fw
Expand All @@ -43,6 +44,7 @@ in {
programs.service-mail
programs.tg-send
hardware.backlight
hardware.sr-iov
users.yinfeng
])
++ [
Expand Down Expand Up @@ -145,7 +147,6 @@ in {
fileSystems."/persist" = btrfsSubvolMain "@persist" {neededForBoot = true;};
fileSystems."/var/log" = btrfsSubvolMain "@var-log" {neededForBoot = true;};
fileSystems."/nix" = btrfsSubvolMain "@nix" {neededForBoot = true;};
fileSystems."/sbkeys" = btrfsSubvolMain "@sbkeys" {};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/5C56-7693";
fsType = "vfat";
Expand All @@ -160,65 +161,6 @@ in {
];
}

# sr-iov of intel gpu
{
boot.kernelParams = ["intel_iommu=on" "i915.enable_guc=3" "i915.max_vfs=7"];
systemd.services.setup-sriov = let
num = 1;
in {
script = ''
set -e
echo ${toString num} | tee /sys/devices/pci0000:00/0000:00:02.0/sriov_numvfs
'';
serviceConfig = {
Type = "oneshot";
};
requiredBy = ["libvirtd.service"];
before = ["libvirtd.service"];
};
systemd.services.detach-sriov-devices = {
script = ''
set -e
virsh nodedev-detach pci_0000_00_02_1
'';
path = with pkgs; [
libvirt
];
serviceConfig = {
Type = "oneshot";
};
requiredBy = ["libvirtd.service"];
after = ["libvirtd.service"];
before = ["libvirt-guests.service"];
};
environment.systemPackages = with pkgs; [
looking-glass-client
];
# https://looking-glass.io/docs/B6/module/#vm-host
boot = {
extraModulePackages = with config.boot.kernelPackages; [
kvmfr
];
kernelModules = [
"kvmfr"
];
extraModprobeConfig = ''
options kvmfr static_size_mb=64
'';
};
services.udev.extraRules = ''
ACTION=="add", SUBSYSTEM=="kvmfr", GROUP="libvirtd", MODE="0660"
'';
virtualisation.libvirtd.qemu.verbatimConfig = ''
cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm",
"/dev/kvmfr0"
]
'';
}

# windows fonts
(
let
Expand Down
85 changes: 74 additions & 11 deletions nixos/profiles/boot/secure-boot/default.nix
Original file line number Diff line number Diff line change
@@ -1,22 +1,78 @@
{
config,
lib,
pkgs,
...
}: {
options = {
boot.secureBoot = {
publicKeyFile = lib.mkOption {
type = lib.types.path;
default = pkgs.writeText "module-signing.crt" config.lib.self.data.secure_boot.database.certificate_pem;
};
privateKeyFile = lib.mkOption {
type = lib.types.path;
default = config.sops.secrets."secure_boot_db_private_key".path;
};
};
boot.kernelModuleSigning = {
enable = lib.mkEnableOption "kernel module signing";
hash = lib.mkOption {
type = lib.types.enum ["SHA1" "SHA224" "SHA256" "SHA384" "SHA512"];
default = "SHA512";
};
certificate = lib.mkOption {
type = lib.types.path;
# just the same as the database key
default = config.boot.secureBoot.publicKeyFile;
};
key = lib.mkOption {
type = lib.types.path;
default = config.boot.secureBoot.privateKeyFile;
};
# defined in profiles/nix/hydra-builder-server
# kernel and modules must be built on thess servers
combined = lib.mkOption {
type = lib.types.path;
default = config.sops.templates."linux-module-signing-key.pem".path;
};
signModule = lib.mkOption {
type = lib.types.path;
default = pkgs.writeShellApplication {
name = "signModule";
text = let
inherit (config.boot.kernelPackages) kernel;
in ''
echo "Signing kernel module '$1'..."
"${kernel.dev}/lib/modules/${kernel.modDirVersion}/build/scripts/sign-file" \
"${config.boot.kernelModuleSigning.hash}" \
"${config.boot.kernelModuleSigning.key}" \
"${config.boot.kernelModuleSigning.certificate}" \
"$@"
'';
};
};
};
boot.kernelLockdown = lib.mkEnableOption "kernel lockdown";
};

config = lib.mkMerge [
{
assertions = [
{
assertion = config.boot.kernelLockdown -> config.boot.kernelModuleSigning.enable;
message = "boot.kernelLockdown requires boot.kernelModuleSigning.enable";
}
];
}
{
boot.lanzaboote = {
enable = true;
publicKeyFile = "/sbkeys/generated/db.crt";
privateKeyFile = "/sbkeys/generated/db.key";
inherit (config.boot.secureBoot) publicKeyFile privateKeyFile;
};
boot.kernelPatches = [
{
name = "keyring";
name = "uefi-keyring";
patch = null;
extraConfig = ''
INTEGRITY_MACHINE_KEYRING y
Expand All @@ -30,27 +86,34 @@
}
];
}
(lib.mkIf config.boot.kernelModuleSigning.enable {
boot.kernelPatches = [
# this patch makes the linux kernel unreproducible
{
name = "moduel-signing";
patch = null;
extraConfig = ''
MODULE_SIG y
MODULE_SIG_SHA512 y
MODULE_SIG_HASH sha512
MODULE_SIG_KEY ${config.boot.kernelModuleSigning.combined}
'';
}
];
})
(lib.mkIf config.boot.kernelLockdown {
boot.kernelParams = [
"lockdown=integrity"
];
boot.kernelPatches = [
# this patch makes the linux kernel unreproducible
{
name = "lockdown";
patch = null;
extraConfig = ''
MODULE_SIG y
SECURITY_LOCKDOWN_LSM y
'';
}
];
# assertions = [
# {
# assertion = lib.length config.boot.extraModulePackages == 0;
# message = "out-of-tree and unsigned kernel module not supported";
# }
# ];
})
];
}
79 changes: 79 additions & 0 deletions nixos/profiles/hardware/sr-iov/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
config,
pkgs,
...
}: {
boot.kernelParams = ["intel_iommu=on" "i915.enable_guc=3" "i915.max_vfs=7"];
systemd.services.setup-sriov = let
num = 1;
in {
script = ''
set -e
echo ${toString num} | tee /sys/devices/pci0000:00/0000:00:02.0/sriov_numvfs
'';
serviceConfig = {
Type = "oneshot";
};
requiredBy = ["libvirtd.service"];
before = ["libvirtd.service"];
};
systemd.services.detach-sriov-devices = {
script = ''
set -e
virsh nodedev-detach pci_0000_00_02_1
'';
path = with pkgs; [
libvirt
];
serviceConfig = {
Type = "oneshot";
};
requiredBy = ["libvirtd.service"];
after = ["libvirtd.service"];
before = ["libvirt-guests.service"];
};
environment.systemPackages = with pkgs; [
looking-glass-client
];
# https://looking-glass.io/docs/B6/module/#vm-host
boot = {
extraModulePackages = with config.boot.kernelPackages; [
(
if (config.boot ? kernelModuleSigning && config.boot.kernelModuleSigning.enable)
then
(kvmfr.overrideAttrs (old: {
nativeBuildInputs =
(old.nativeBuildInputs or [])
++ [
config.boot.kernelModuleSigning.signModule
];
# signature will be stripped
dontStrip = true;
postBuild =
(old.postBuild or "")
+ ''
signModule kvmfr.ko
'';
}))
else kvmfr
)
];
kernelModules = [
"kvmfr"
];
extraModprobeConfig = ''
options kvmfr static_size_mb=64
'';
};
services.udev.extraRules = ''
ACTION=="add", SUBSYSTEM=="kvmfr", GROUP="libvirtd", MODE="0660"
'';
virtualisation.libvirtd.qemu.verbatimConfig = ''
cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm",
"/dev/kvmfr0"
]
'';
}
19 changes: 19 additions & 0 deletions nixos/profiles/nix/hydra-builder-server/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,23 @@
gid = config.ids.gids.hydra-builder;
};
nix.settings.trusted-users = ["@hydra-builder"];

nix.settings.extra-sandbox-paths = [
config.sops.templates."linux-module-signing-key.pem".path
config.sops.secrets."secure_boot_db_private_key".path
];
sops.templates."linux-module-signing-key.pem" = {
content = ''
${config.lib.self.data.secure_boot.database.certificate_pem}
${config.sops.placeholder."secure_boot_db_private_key"}
'';
group = "nixbld";
mode = "440";
};
sops.secrets."secure_boot_db_private_key" = {
sopsFile = config.sops-file.terraform;
group = "nixbld";
mode = "440";
restartUnits = []; # no need to restart any unit
};
}
2 changes: 2 additions & 0 deletions nixos/profiles/programs/tools/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ in {
gptfdisk
htop
jq
keyutils
lm_sensors
moreutils
ncdu
openssl
parted
pciutils
procs
Expand Down
2 changes: 1 addition & 1 deletion nixos/profiles/services/matrix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ in
};

systemd.services.matrix-synapse = {
# copy singing key to signing key path
# copy signing key to signing key path
serviceConfig.ExecStartPre = lib.mkBefore [
("+"
+ (pkgs.writeShellScript "matrix-synapse-fix-permissions" ''
Expand Down
Loading

0 comments on commit ca09970

Please sign in to comment.