Skip to content

Instantly share code, notes, and snippets.

@rra3b
Last active May 20, 2024 07:37
Show Gist options
  • Save rra3b/e3e5f5aa6f8a569a44ca4f674849ce7d to your computer and use it in GitHub Desktop.
Save rra3b/e3e5f5aa6f8a569a44ca4f674849ce7d to your computer and use it in GitHub Desktop.
Arch full disk encryption with BTRFS, FIDO2, Secure Boot, rEFInd boot manager

Arch Linux Installation Guide

Tested with Yubikey 5 NFC and Yubikey 5c NFC, but any security key with FIDO2 should work too.

Prepare

  1. Boot into the Arch Linux live ISO.
  2. Change the root password:
passwd
  1. Now you can SSH into your live system:
ip addr

Partition and Install Base System

  1. Click the Raw button on the 01-partition_and_install.sh file in this repository to get the raw URL.

  2. Download and run the script:

curl -O <raw-url-of-01-partition_and_install.sh>
  1. Change disk and maybe kernel variant at the top to match your setup.

  2. Run the script, which will prompt you for the disk encryption password:

sh 01-partition_and_install.sh

Post Install (Setup Secure Boot and rEFInd Boot Manager)

  1. Click the Raw button on the 02-post_install.sh file in this repository to get the raw URL.

  2. Download and run the script:

curl -O <raw-url-of-02-post_install.sh>
  1. Change username and name in script.

  2. Run the script to complete the post-installation setup:

sh 02-post_install.sh
  1. Don't forget to delete the downloaded script
rm 02-post_install.sh

WIP

  • Snapper
  • rEFInd Btrfs
disk="nvme0n1"
kernel="linux-zen"
sgdisk -Z "/dev/$disk"
sgdisk -o "/dev/$disk"
sgdisk -n 1::+600M -t 1:ef00 -p "/dev/$disk"
sgdisk -n 2:: -t 2:8309 -p "/dev/$disk"
cryptsetup luksFormat --perf-no_read_workqueue --perf-no_write_workqueue --type luks2 --cipher aes-xts-plain64 --key-size 512 --iter-time 2000 --pbkdf argon2id --hash sha3-512 "/dev/${disk}p2"
systemd-cryptenroll --fido2-device=auto "/dev/${disk}p2"
cryptsetup --allow-discards --perf-no_read_workqueue --perf-no_write_workqueue --persistent open "/dev/${disk}p2" arch
mkfs.vfat -F32 -n "EFI" "/dev/${disk}p1"
mkfs.btrfs -L ARCH -n 32k /dev/mapper/arch
mount /dev/mapper/arch /mnt
btrfs sub c /mnt/@
mkdir -p /mnt/@/{usr,var/lib}
btrfs sub c /mnt/@/home
btrfs sub c /mnt/@/opt
btrfs sub c /mnt/@/root
btrfs sub c /mnt/@/usr/local
btrfs sub c /mnt/@/var/abs
btrfs sub c /mnt/@/var/cache
btrfs sub c /mnt/@/var/log
btrfs sub c /mnt/@/var/lib/flatpak
btrfs sub c /mnt/@/var/tmp
btrfs sub c /mnt/@/.snapshots
umount /mnt
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@ /dev/mapper/arch /mnt
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/home /dev/mapper/arch /mnt/home
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/opt /dev/mapper/arch /mnt/opt
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/root /dev/mapper/arch /mnt/root
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/usr/local /dev/mapper/arch /mnt/usr/local
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/var/abs /dev/mapper/arch /mnt/var/abs
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/var/cache /dev/mapper/arch /mnt/var/cache
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/var/log /dev/mapper/arch /mnt/var/log
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/var/lib/flatpak /dev/mapper/arch /mnt/var/lib/flatpak
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/var/tmp /dev/mapper/arch /mnt/var/tmp
mount -o noatime,nodiratime,compress=zstd:1,commit=120,space_cache=v2,ssd,discard=async,subvol=@/.snapshots /dev/mapper/arch /mnt/.snapshots
mount -m -o fmask=0077,umask=0077 "/dev/${disk}p1" /mnt/efi
# change mirror accept only edu or org mirror
reflector -c 'Taiwan' -p https --verbose --latest 5 --sort rate --threads $(nproc) | grep -E 'edu|org|^#|^$' | tee /etc/pacman.d/mirrorlist
sed -i 's/^#ParallelDownloads/ParallelDownloads/' /etc/pacman.conf
pacstrap /mnt \
base "${kernel}" "${kernel}-headers" linux-firmware amd-ucode \
sbctl sbsigntools efibootmgr btrfs-progs libfido2 refind terminus-font \
mesa vulkan-radeon libva-mesa-driver mesa-vdpau xf86-video-amdgpu networkmanager \
man-db man-pages texinfo reflector zsh git base-devel rustup neovim fzf pigz pbzip2
arch-chroot /mnt
kernel="linux-zen"
create_user="bear"
host="bear-ws"
TZ="Asis/Taipei"
reflector -c 'Taiwan' -p https --verbose --latest 5 --sort rate --threads $(nproc) | grep -E 'edu|org|^#|^$' | tee /etc/pacman.d/mirrorlist
sed -i 's/^#ParallelDownloads/ParallelDownloads/' /etc/pacman.conf
ln -sf /usr/share/zoneinfo/$TZ /etc/localtime
hwclock -uw
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/#en_US ISO-8859-1/en_US ISO-8859-1/g' /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
echo "FONT=ter-v24n" > /etc/vconsole.conf
echo "$host" > /etc/hostname
cat << EOF >> /etc/hosts
127.0.0.1 localhost
::1 localhost
127.0.1.1 $host.localdomain $host
127.0.0.1 $host
EOF
### setup user
useradd -mG wheel,audio,video,input,kvm -s /usr/bin/zsh "$create_user"
echo "Set password for user: $create_user"
passwd "$create_user"
# temproary disable sudo password
echo '%wheel ALL=(ALL:ALL) NOPASSWD: /usr/bin/pacman' > /etc/sudoers.d/wheel
sudo -u "$create_user" rustup default stable
sudo -u "$create_user" git clone --depth=1 --single-branch https://aur.archlinux.org/paru.git "/home/$create_user/src/oss/paru"
# subshell to avoid cd back
(cd "/home/$create_user/src/oss/paru" && sudo -u "$create_user" makepkg -si --noconfirm)
sudo -u "$create_user" paru -S shim-signed --noconfirm
# add sudo password back
echo '%wheel ALL=(ALL:ALL) ALL' > /etc/sudoers.d/wheel
# shim for secure boot
refind-install --shim /usr/share/shim-signed/shimx64.efi --localkeys
# install refind theme
git clone --single-branch --depth=1 https://github.com/dheishman/refind-dreary.git /efi/EFI/refind/themes/refind-dreary-tmp
mv /efi/EFI/refind/themes/refind-dreary-tmp/highres /efi/EFI/refind/themes/refind-dreary
rm -rf /efi/EFI/refind/themes/refind-dreary-tmp
sed -i 's/#use_graphics_for osx,linux/use_graphics_for linux/' /efi/EFI/refind/refind.conf
sed -i 's/#scanfor internal,external,optical,manual/scanfor manual,external/' /efi/EFI/refind/refind.conf
printf "\ninclude themes/refind-dreary/theme.conf" >> /efi/EFI/refind/refind.conf
### mkinitcpio
sed -i 's/MODULES=()/MODULES=(btrfs)/' /etc/mkinitcpio.conf
sed -i 's/BINARIES=()/BINARIES=("\/usr\/lib\/libfido2.so")/' /etc/mkinitcpio.conf
sed -i 's/^HOOKS=.*/HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)/' /etc/mkinitcpio.conf
echo "rd.luks.name=$(blkid -s UUID -o value /dev/nvme0n1p2)=arch rd.luks.options=fido2-device=auto root=/dev/mapper/arch rootflags=subvol=@ rw quiet nmi_watchdog=0 add_efi_memmap initrd=/amd-ucode.img" > /etc/kernel/cmdline
# rd.luks.name=19891d4d-f8a9-48ee-8a11-e02d4d161e2b=arch rd.luks.options=fido2-device=auto root=/dev/mapper/arch rootflags=subvol=@ rw quiet nmi_watchdog=0 add_efi_memmap initrd=/amd-ucode.img
preset="/etc/mkinitcpio.d/${kernel}.preset"
sed -i 's/^PRESETS=.*/PRESETS=("default")/' "$preset"
sed -i 's/^#default_uki=.*/default_uki="\/efi\/EFI\/Linux\/arch-linux.efi"/' "$preset"
sed -i 's/^#default_options=.*/default_options="--splash \/usr\/share\/systemd\/bootctl\/splash-arch.bmp"/' "$preset"
sed -i '/^fallback_*/ s/^/#/' "$preset"
# post hook sign for secure boot
cat << 'EOF' > /etc/initcpio/post/uki-sbsign
#!/usr/bin/env bash
uki="$3"
[[ -n "$uki" ]] || exit 0
keypairs=(/etc/refind.d/keys/refind_local.key /etc/refind.d/keys/refind_local.crt)
for (( i=0; i<${#keypairs[@]}; i+=2 )); do
key="${keypairs[$i]}" cert="${keypairs[(( i + 1 ))]}"
if ! sbverify --cert "$cert" "$uki" &>/dev/null; then
sbsign --key "$key" --cert "$cert" --output "$uki" "$uki"
fi
done
EOF
chmod u+x /etc/initcpio/post/uki-sbsign
sbctl create-keys
mkdir -p /efi/EFI/Linux
mkinitcpio -P
# setup network
systemctl enable NetworkManager
echo "Post install finshed, now you may reboot to your new system."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment