Last active
April 4, 2025 12:44
-
-
Save sveitser/ab427ed89e32e3e99539f832023fdb2b to your computer and use it in GitHub Desktop.
Install nixos on luks, zfs and encrypt passphrase with yubikey
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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="[email protected]" | |
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