Skip to content

Instantly share code, notes, and snippets.

@zenlor
Created August 20, 2016 09:56
Show Gist options
  • Save zenlor/58c60c58fea612507bfd6880a9d17d37 to your computer and use it in GitHub Desktop.
Save zenlor/58c60c58fea612507bfd6880a9d17d37 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Config
EFI_PART=/dev/sda1
LUKS_PART=/dev/sda2
EFI_MNT=/root/boot
# Utils
rbtohex() { ( od -An -vtx1 | tr -d ' \n' ) }
hextorb() { ( tr '[:lower:]' '[:upper:]' | sed -e 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI'| xargs printf ) }
l() { echo -en "$@" }
#
# ---- The real work
#
l "mount boot partition"
mkdir "$EFI_MNT"
mkfs.vfat -F 32 -n uefi "$EFI_PART"
mount "$EFI_PART" "$EFI_MNT"
l "setup crypt-storage"
STORAGE=/crypt-storage/default
mkdir -p "$(dirname $EFI_MNT$STORAGE)"
l "install gcc, ykpers and openssl"
nix-env -i gcc-wrapper
nix-env -i ykpers
nix-env -i openssl
l "compile 'pbkdf2-sha512'"
cc -O3 -I$(find / | grep "openssl/evp\.h" | head -1 | sed -e 's|/openssl/evp\.h$||g' | tr -d '\n') \
-L$(find / | grep "lib/libcrypto" | head -1 | sed -e 's|/libcrypto\..*$||g' | tr -d '\n') \
$(find / | grep "pbkdf2-sha512\.c" | head -1 | tr -d '\n') -o ./pbkdf2-sha512 -lcrypto
l "create salt"
SALT_LENGTH=16
salt="$(dd if=/dev/random bs=1 count=$SALT_LENGTH 2>/dev/null | rbtohex)"
l "create secret key for the yubikey"
k_yubi="$(dd if=/dev/random bs=1 count=20 2>/dev/null | rbtohex)"
l "get the user passphrase (recommended)"
read -s k_user
l "calculate initial yubikey challenge"
challenge="$(echo -n $salt | openssl dgst -binary -sha512 | rbtohex)"
l "calculate the yk response"
response="$(echo -n $challenge | hextorb | openssl dgst -binary -sha1 -mac HMAC -macopt hexkey:$k_yubi | rbtohex)"
l "derive the luks slot key"
KEY_LENGTH=512
ITERATIONS=1000000
if ( "${k_user}" != "" ); then
k_luks="$(echo -n $k_user | ./pbkdf2-sha512 $(($KEY_LENGTH / 8)) $ITERATIONS $response | rbtohex)"
else
k_luks="$(echo | ./pbkdf2-sha512 $(($KEY_LENGTH / 8)) $ITERATIONS $response | rbtohex)"
fi
l "create luks device"
CIPHER=aes-xts-plain64
HASH=sha512
echo -n "$k_luks" |\
hextorb |\
cryptsetup luksFormat --cipher="$CIPHER" \
--key-size="$KEY_LENGTH" --hash="$HASH" --key-file=- "$LUKS_PART"
l "store secret key in then EFI partition"
echo -ne "$salt\n$ITERATIONS" > $EFI_MNT$STORAGE
l "store the secret key on the yk"
SLOT=2
ykpersonalize -"$SLOT" -ochal-resp -ochal-hmac -a"$k_yubi"
l "open luks device"
LUKSROOT=luksroot
echo -n "$k_luks" | hextorb | cryptsetup luksOpen --key-file=- "$LUKS_PART" "$LUKSROOT"
l "umount the EFI partition"
umount "$EFI_MNT"
l "\n\n\n setup LVM \n\n\n"
pvcreate "/dev/mapper/${LUKSROOT}"
l "Setup a volume group (partitions)"
VGNAME=partitions
vgcreate "$VGNAME" "/dev/mapper/$LUKSROOT"
l "set two logical partitions (root + swap)"
lvcreate -L 4G -n swap "$VGNAME"
FSROOT=fsroot
lvcreate -l 100%FREE -n "$FSROOT" "$VGNAME"
vgchange -ay
l "make swap fs"
mkswap -L swap /dev/partitions/swap
l "\n\n\n BTRFS Setup \n\n\n"
l "Step 1: Create the main btrfs volume's filesystem."
mkfs.btrfs -L "$FSROOT" "/dev/partitions/$FSROOT"
l "Should the above fail, you might have encountered a bug that can be solved with doing the following, then attempting the above again:"
mkdir /mnt-root
touch /mnt-root/nix-store.squashfs
l "Step 2: Mount the main btrfs volume."
mount "/dev/partitions/$FSROOT" /mnt
l 'Step 3: Create the subvolumes, for example "root" and "home".'
cd /mnt
btrfs subvolume create root
btrfs subvolume create home
l "Step 4: Create mountpoints on the root subvolume and finalise things for NixOS installation."
umount /mnt
mount -o subvol=root "/dev/partitions/$FSROOT" /mnt
mkdir /mnt/home
mount -o subvol=home "/dev/partitions/$FSROOT" /mnt/home
mkdir /mnt/boot
mount "EFI_PART" /mnt/boot
swapon /dev/partitions/swap
l "generate nix config"
nixos-generate-config --root /mnt
l "READY to install!!!"
l "\n\n edit the file /mnt/etc/nixos/configuration.nix"
echo <<EOF
You must set the option boot.loader.grub.device to specify on which disk the GRUB boot loader is to be installed. Without it, NixOS cannot boot.
Another critical option is fileSystems, specifying the file systems that need to be mounted by NixOS. However, you typically don’t need to set it yourself, because nixos-generate-config sets it automatically in /mnt/etc/nixos/hardware-configuration.nix from your currently mounted file systems. (The configuration file hardware-configuration.nix is included from configuration.nix and will be overwritten by future invocations of nixos-generate-config; thus, you generally should not modify it.)
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment