Skip to content

Instantly share code, notes, and snippets.

@sveitser
Last active January 1, 2024 21:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sveitser/ab427ed89e32e3e99539f832023fdb2b to your computer and use it in GitHub Desktop.
Save sveitser/ab427ed89e32e3e99539f832023fdb2b to your computer and use it in GitHub Desktop.
Install nixos on luks, zfs and encrypt passphrase with yubikey
#!/usr/bin/env bash
#
# 1. boot from live cd, with programs.gpg enabled
# 2. gpg --import /your/public/key
# 3. edit GPG_ID, DISK below
# 4. run script
#
set -euo pipefail
GPG_ID="foo@bar.com"
DISK="/dev/disk/by-id/..."
PUB_KEY="./yubikey-public.asc"
PASSPHRASE="./luks-passphrase.asc"
ENCRYPTED_PASSPHRASE="$PASSPHRASE".gpg
openssl genrsa -out $PASSPHRASE 4096
rm -f $ENCRYPTED_PASSPHRASE
gpg --trust-model always --encrypt --recipient $GPG_ID $PASSPHRASE
gpg --export --armor $GPG_ID > $PUB_KEY
BOOT="$DISK-part1"
LINUX="$DISK-part2"
LUKS_DEVICE_NAME=cryptroot
LUKS_DISK="/dev/mapper/$LUKS_DEVICE_NAME"
ZFS="$LUKS_DISK"
# clean up from last run
zpool destroy tank || true
cryptsetup luksClose "$LUKS_DEVICE_NAME" || true
umount -A --recursive /mnt || true
wipefs -af "$DISK"
sgdisk -Zo "$DISK"
echo "Creating boot (EFI) partition"
sgdisk -n 0:1M:+512M -t 0:EF00 "$DISK"
echo "Creating Linux partition"
# calculated end sector to align with 4096 on Samsung 980Pro, required by luks --sector-size 409e
# sgdisk -a 4096 -n 0:0:+3905974272 -t 0:BF01 "$DISK"
sgdisk -n 0:0:0 -t 0:BF01 "$DISK"
partprobe "$DISK"
sleep 1
echo "Format BOOT partition $BOOT"
mkfs.vfat "$BOOT"
echo "Creating LUKS container on $LINUX"
# cryptsetup luksFormat --sector-size 4096 --batch-mode --key-file "$PASSPHRASE" "$LINUX"
cryptsetup luksFormat --batch-mode --key-file "$PASSPHRASE" "$LINUX"
cryptsetup luksOpen --key-file "$PASSPHRASE" "$LINUX" "$LUKS_DEVICE_NAME"
echo "Create ZFS pool on $ZFS"
zpool create -O atime=off -O xattr=sa -O acltype=posixacl -o ashift=13 -f -m none -R /mnt tank "$ZFS"
# zpool create -f -m none -R /mnt tank "$ZFS"
echo "Create ZFS datasets"
zfs create -o mountpoint=legacy tank/root
zfs create -o mountpoint=legacy tank/root/nix
zfs create -o mountpoint=legacy tank/home
zfs snapshot tank/root@blank
echo "Mount ZFS datasets"
mount -t zfs tank/root /mnt
mkdir /mnt/nix
mount -t zfs tank/root/nix /mnt/nix
mkdir /mnt/home
mount -t zfs tank/home /mnt/home
mkdir /mnt/boot
mount "$BOOT" /mnt/boot
echo "Generate NixOS configuration"
nixos-generate-config --root /mnt
# Add LUKS and ZFS configuration
HOSTID=$(head -c8 /etc/machine-id)
LINUX_DISK_UUID=$(blkid --match-tag UUID --output value "$LINUX")
HARDWARE_CONFIG=$(mktemp)
cat <<CONFIG > "$HARDWARE_CONFIG"
networking.hostId = "$HOSTID";
boot.supportedFilesystems = [ "zfs" ];
boot.initrd.luks.gpgSupport = true;
boot.initrd.luks.devices."$LUKS_DEVICE_NAME".device = "/dev/disk/by-uuid/$LINUX_DISK_UUID";
boot.initrd.luks.devices."$LUKS_DEVICE_NAME".gpgCard.publicKey = ./yubikey-public.asc;
boot.initrd.luks.devices."$LUKS_DEVICE_NAME".gpgCard.encryptedPass = ./luks-passphrase.asc.gpg;
boot.zfs.devNodes = "$ZFS";
CONFIG
echo "Append configuration to hardware-configuration.nix"
sed -i "\$e cat $HARDWARE_CONFIG" /mnt/etc/nixos/hardware-configuration.nix
cp -v $ENCRYPTED_PASSPHRASE $PUB_KEY /mnt/etc/nixos/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment