Skip to content

Commit

Permalink
fix: more secure boot changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Lehmanator committed Jul 24, 2024
1 parent 5ec0a8f commit f4a837b
Show file tree
Hide file tree
Showing 17 changed files with 287 additions and 352 deletions.
9 changes: 1 addition & 8 deletions nixos/hosts/fw/profiles.nix
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
{
config,
lib,
pkgs,
inputs,
...
}: {
{ config, lib, pkgs, inputs, ... }: {
imports = [
../../profiles
../../profiles/boot
# ../../profiles/boot/secureboot.nix
../../profiles/desktop
../../profiles/desktop/de/gnome
../../profiles/hardware/display
Expand Down
1 change: 0 additions & 1 deletion nixos/hosts/wyse/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
../../profiles

../../profiles/boot
#../../profiles/boot/unl0kr.nix
../../profiles/desktop
../../profiles/desktop/de/gnome
../../profiles/hardware/display
Expand Down
60 changes: 43 additions & 17 deletions nixos/profiles/boot/default.nix
Original file line number Diff line number Diff line change
@@ -1,46 +1,64 @@
{ config, lib, pkgs, user, ... }:
#
# https://wiki.archlinux.org/index.php/Disk_encryption
# https://nixos.wiki/wiki/Full_Disk_Encryption
# https://nixos.org/wiki/Encrypted_Root_on_NixOS
# https://nixos.wiki/wiki/Remote_disk_unlocking
#
let
inherit (lib) mkDefault;
inherit (lib) mkDefault mkIf;
opts = {
disk-unlock-password-entry = true;
disk-unlock-usb-key = false;
};
in
{
imports = [
./plymouth.nix
./plymouth.nix # imports ./quiet.nix
./systemd-boot.nix
./systemd-initrd.nix

#./disko.nix
#./extra-bootloader-entries.nix
#./hibernation.nix
#./iscsi-initiator.nix
#./nvme.nix
#./print-config-install.nix
#./secureboot.nix
#./systemd-debug.nix
#./systemd-emergency.nix
#./systemd-repart.nix
#./unl0kr.nix

#./entries # # ./entries/{efi-shell,fwupd,memtest86,netbootxyz,restart-bootloader,usb-boot}.nix
#./filesystem-support # ./filesystem-support/{bcachefs,btrfs,f2fs,lvm2,mdadm,ntfs,xfs,zfs}.nix
#./entries # ./entries/{efi-shell,fwupd,memtest86,netbootxyz,restart-bootloader,usb-boot}.nix
#./fs # ./fs/{bcachefs,btrfs,lvm2,mdadm,ntfs,zfs}.nix
#./fs # ./fs/{f2fs,ntfs,xfs}.nix
#./fs/layouts # ./fs/layouts/xbootldr.nix
#./hw # ./hw/{nvme,tpm2}.nix
#./network # ./network/{iscsi-initiator,netboot,pixieboot}.nix

#./efivars.nix
#./tpm.nix
#./xbootldr.nix
#./hibernation.nix
];

boot = {
bootspec = {
# Write bootspec docs for each build.
enable = mkDefault true;
enable = true; #mkDefault true;

# Validate bootspec documents upon each build.
# - Note: introduces build-time Golang dep Cuelang.
# - Warn: Make certain bootspec docs are correct.
enableValidation = mkDefault true;
enableValidation = true; #mkDefault true;

# extensions = {};
};

initrd = {
# --- Graphical Disk Unlock w/ Touch Keyboard ---
# https://github.com/droidian/unl0kr
# TODO: Enable when:
# - no keyboard OR touchscreen (mobile devices)
# - disk encrypted
# TODO: Write configuration file.
# TODO: Create NixOS module for config options.
# TODO: Move config to profiles/mobile?
unl0kr.enable = opts.disk-unlock-password-entry;
kernelModules = mkIf opts.disk-unlock-usb-key ["usb_storage"];
};

loader = {
# Second until default bootloader entry boots.
# - `null` = wait indefinitely
Expand All @@ -49,11 +67,19 @@ in

efi = {
# Where to mount the EFI system partition
efiSysMountPoint = mkDefault "/boot"; #"/boot/efi";
# TODO: Follow Discoverable Partitions Spec:
# https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
# - TODO: `XBOOTLDR` / `ESP` splitting?
# - TODO: Rewrite to `/efi`, `/boot`, or `/boot/efi`?
# NOTE: Set to "/boot/efi" in `nixos/hosts/fw/configuration.nix`
# Default: "/boot"
efiSysMountPoint = mkDefault "/boot"; #"/boot/efi";

# Whether install process allowed to modify EFI boot variables
canTouchEfiVariables = mkDefault true;
};
};
};

environment.systemPackages = mkIf config.boot.bootspec.enable [pkgs.bootspec];
}
6 changes: 0 additions & 6 deletions nixos/profiles/boot/disko.nix

This file was deleted.

11 changes: 3 additions & 8 deletions nixos/profiles/boot/entries/usb-boot.nix
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
{ config, ... }:
{
imports = [ ];

{ config, ... }: {
# TODO: Enable networking, disks in initrd / UEFI?

# TODO: Add EFI binary paths for all extraEntries.
boot.loader.systemd-boot = {
extraEntries = {
# TODO: Add EFI binary paths for all extraEntries.
"usb-boot" = ''
title Boot from USB drive
efi
'';
};

extraFiles = {
#"efi/<dirName>/<efiBinaryName>.efi" = "${pkgs.<efiBinaryPackage>}/<efiBinaryName>.efi";
#"efi/<dirName>/<efiBinaryName>.efi" = "${pkgs.<efiBinaryPackage>}/<efiBinaryName>.efi";
#"efi/reboot-bootloader/no-plymouth.efi" = "${pkgs.systemd-boot}/systemd-boot.efi"; # TODO: Get real path
};
};
Expand Down
81 changes: 24 additions & 57 deletions nixos/profiles/boot/hibernation.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
{ inputs
, config
, lib
, pkgs
, ...
}:
{ inputs, config, lib, pkgs, ... }:
#
# TODO: Possible to work with machines that are Kubernetes nodes?
# TODO: Setup Full Disk Encryption (FDE) before enabling swap & hibernation.
# TODO: Encrypt keyfiles with agenix or sops-nix, then add to repo.
Expand All @@ -12,16 +8,13 @@
# - [ ] Mount other keyfiles at proper location on disk.
# TODO: Configure hardware-configuration & disk partitions with Disko.
#
#
# See:
#
# - https://nixos.wiki/wiki/Laptop
# - https://sawyershepherd.org/post/hibernating-to-an-encrypted-swapfile-on-btrfs-with-nixos/
#
{
imports = [
#./swap.nix
];
# imports = [ ./swap.nix ];

# Device for manual resume attempt during boot.
# This should be used primarily if you want to resume from file.
Expand Down Expand Up @@ -65,60 +58,34 @@
# - the path of the swap device or file (device) or
# - the label of the swap device (label, see mkswap -L).
# Using a label is recommended.
swapDevices = {

primary-swap = {

# --- Swap device parameters ---
device = "/dev/nvme0n1p2"; # Path of the device or swap file.
discardPolicy = null; # null | once | pages | both
label = "swap"; # Label of the device. Can be used instead of device.
options = [ "defaults" ]; # Options used to mount the swap.
priority = 10; # Priority of the swap device b/w [0, 32767] where higher number => higher priority. null lets kernel choose priority, which will show up as negative value.
size = 2048; # Swap size in Megabytes. # TODO: Set to RAM size * 1.5

# --- Swap Encryption ---
encrypted = {
enable = true; # The block device is backed by an encrypted one, adds this device as a initrd luks entry.
blkDev = "/dev/nvme0n1p2"; # Location of the backing encrypted device.
# Path to a keyfile used to unlock the backing encrypted device.
# At the time this keyfile is accessed,
# the neededForBoot filesystems (see fileSystems.<name?>.neededForBoot) will have been mounted under /mnt-root,
# so the keyfile path should usually start with “/mnt-root/”.
keyFile = "/mnt-root/root/.swapkey";

# Label of the unlocked encrypted device. Set fileSystems.<name?>.device to /dev/mapper/<label> to mount the unlocked device.
label = "swap";
};

# --- Swap Random Encryption ---
# Encrypt swap device with a random key. This way you won’t have a persistent swap device.
# HINT: run `cryptsetup benchmark` to test cipher performance on your machine.
# WARNING: Don’t try to hibernate when you have at least one swap partition with this option enabled!
# We have no way to set the partition into which hibernation image is saved, so if your image ends up on an encrypted one you would lose it!
# WARNING: Do not use /dev/disk/by-uuid/… or /dev/disk/by-label/… as your swap device when using randomEncryption
# ...as the UUIDs & labels will get erased on every boot when the partition is encrypted.
# Best to use /dev/disk/by-partuuid/…
randomEncryption = {
enable = false; # Encrypt swap with random data. Note: cannot be used w/ hibernate!
allowDiscards = false; # Harden: set false.
cipher = "aes-xts-plain64"; #
keySize = "512"; # If null, will be determined by cryptsetup. See: cryptsetup-open(8)
sectorSize = "4096"; # If null, will be determined by cryptsetup. See: cryptsetup-open(8)
source = "/dev/urandom"; # /dev/random
};

swapDevices.primary-swap = {
device = "/dev/nvme0n1p2"; # Path of the device or swap file.
discardPolicy = null; # null | once | pages | both
label = "swap"; # Label of the device. Can be used instead of device.
options = [ "defaults" ]; # Options used to mount the swap.
priority = 10; # Priority of the swap device b/w [0, 32767] where higher number => higher priority. null lets kernel choose priority, which will show up as negative value.
size = 2048; # Swap size in Megabytes. # TODO: Set to RAM size * 1.5

# --- Swap Encryption ---
encrypted = {
enable = true; # The block device is backed by an encrypted one, adds this device as a initrd luks entry.
blkDev = "/dev/nvme0n1p2"; # Location of the backing encrypted device.
# Path to a keyfile used to unlock the backing encrypted device.
# At the time this keyfile is accessed,
# the neededForBoot filesystems (see fileSystems.<name?>.neededForBoot) will have been mounted under /mnt-root,
# so the keyfile path should usually start with “/mnt-root/”.
keyFile = "/mnt-root/root/.swapkey";

# Label of the unlocked encrypted device. Set fileSystems.<name?>.device to /dev/mapper/<label> to mount the unlocked device.
label = "swap";
};

randomEncryption.enable = lib.mkForce false;
};

# If you have issues w/ device not shutting off after hibernating, uncomment these lines:
#systemd.sleep.extraConfig = ''
# [Sleep]
# HibernateMode=shutdown
#'';



}

63 changes: 26 additions & 37 deletions nixos/profiles/boot/plymouth.nix
Original file line number Diff line number Diff line change
@@ -1,51 +1,40 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
#
# Set quiet boot so splash isnt interrupted by scrolling boot logging text.
# TODO: Determine if using disk encryption. If so, display unlock util (requires systemd-based initrd?)
#
{
#imports = [ ./quiet.nix ];
imports = [ ./quiet.nix ];
boot = {
plymouth = {
plymouth = with pkgs; {
enable = lib.mkDefault true;
font = "${pkgs.cantarell-fonts}/share/fonts/cantarell/Cantarell-VF.otf"; # # Console font.
#font = "${pkgs.dejavu_fonts.minimal}/share/fonts/truetype/DejaVuSans.ttf"; # TODO: Font work w/ boot-console/Plymouth?
#logo="${pkgs.nixos-icons}/share/icons/hicolor/48x48/apps/nix-snowflake-white.png"; # OS logo img (can use files in Nix store)
#logo=pkgs.fetchurl {url="https://nixos.org/logo/nixos-hires.png"; sha256="1ivzgd7iz0i06y36p8m5w48fd8pjqwxhdaavc0pxs7w1g7mcy5si";};

# Tutorial to create Plymouth theme: https://brej.org/blog/?p=197
# https://brej.org/blog/?p=238
theme = "spinner"; # bgrt|spinner-monochrome|details|fade-in|glow|script|solar|spinfinity|spinner|text|tribar|breeze
themePackages = [
# Packages providing Plymouth themes
pkgs.adi1090x-plymouth-themes
pkgs.catppuccin-plymouth
pkgs.libsForQt5.breeze-plymouth
pkgs.nixos-bgrt-plymouth
#(pkgs.plymouth-spinner-monochrome.override { inherit (config.boot.plymouth) logo; })
];
# Console font.
# TODO: Font work w/ boot-console/Plymouth?
# TODO: Share font with desktop?
#font = "${dejavu_fonts.minimal}/share/fonts/truetype/DejaVuSans.ttf";
font = "${cantarell-fonts}/share/fonts/cantarell/Cantarell-VF.otf";

# OS logo img (can use files in Nix store)
#logo="${nixos-icons}/share/icons/hicolor/48x48/apps/nix-snowflake-white.png";
#logo = fetchurl {url="https://nixos.org/logo/nixos-hires.png"; sha256="1ivzgd7iz0i06y36p8m5w48fd8pjqwxhdaavc0pxs7w1g7mcy5si";};

# Tutorials to create Plymouth themes:
# - https://brej.org/blog/?p=197
# - https://brej.org/blog/?p=238
# Options: bgrt | spinner-monochrome | details | fade-in | glow |
# script | solar | spinfinity | spinner | breeze | text | tribar
theme = "spinner";

# Packages providing Plymouth themes
# (plymouth-spinner-monochrome.override { inherit (config.boot.plymouth) logo; })
themePackages = with pkgs; [adi1090x-plymouth-themes catppuccin-plymouth libsForQt5.breeze-plymouth nixos-bgrt-plymouth];

# Extra lines to append to Plymouth config.
extraConfig = ''
DeviceScale=2
'';
};

# --- quiet / silent boot ---
consoleLogLevel =
lib.mkIf config.boot.plymouth.enable 0; # Lowest boot console log level
initrd.verbose =
!config.boot.plymouth.enable; # # Minimal info to console in initrd.
kernelParams = lib.mkIf config.boot.plymouth.enable [
"quiet"
"loglevel=3"
"systemd.show_status=auto"
"udev.log_level=3"
"rd.udev.log_level=3"
"vt.global_cursor_default=0"
]; # "splash"
};

console = {
Expand Down
9 changes: 0 additions & 9 deletions nixos/profiles/boot/print-config-install.nix

This file was deleted.

35 changes: 35 additions & 0 deletions nixos/profiles/boot/quiet.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
{
# Enable "Silent Boot"
# - Note: Required for Plymouth bootsplash?
boot = {
# Hide the OS choice for bootloaders.
# It's still possible to open the bootloader list by pressing any key
# It will just not appear on screen unless a key is pressed
loader.timeout = 0;

# Lowest boot console log level
consoleLogLevel = 0;

# Minimal info to console in initrd
initrd.verbose = false;

kernelParams = [
"quiet"
"splash"
"boot.shell_on_fail"
"loglevel=3"
"rd.systemd.show_status=false"
"rd.udev.log_level=3"
"udev.log_priority=3"

# -- plymouth.nix ---
# These params were previously enabled in ./plymouth.nix,
# but weren't in wiki page on quiet boot / Plymouth, so we removed them.
#
#"systemd.show_status=auto"
#"udev.log_level=3"
#"vt.global_cursor_default=0"
];
};
}
Loading

0 comments on commit f4a837b

Please sign in to comment.