Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save skorotkiewicz/6a18ae409651ebcbdf0c4a1352137602 to your computer and use it in GitHub Desktop.
Save skorotkiewicz/6a18ae409651ebcbdf0c4a1352137602 to your computer and use it in GitHub Desktop.
Arch install with ZFS root on LUKS and EFISTUB
# Create your partition layout (using GPT)
# 1 - ESP (FAT32, 128M)
# 2 - Linux (luks, any size)
# Format your partitions
mkfs.fat -F32 /dev/sdx1
cryptsetup luksFormat --key-size 512 --cipher aes-xts-plain64 /dev/sdx2
# Open your luks partition
cryptsetup open /dev/sdx2 luks_root
# Make sure ZFS is loaded before continuing
modprobe zfs
# Create your ZFS pool
# Note:
# - For drives with a block size of 512b, use ashift=9
# - For drives with a blocks size of 4KiB, use ahift=12
zpool create \
-o ashift=12\
-O xattr=sa\
-O redundant_metadata=most\
-O normalization=formD\
-O acltype=posixacl\
-O compression=lz4\
-O dedup=on\
-O dnodesize=legacy\
-O relatime=on\
-O mountpoint=none\
-O canmount=off\
-O devices=off\
-m none\
zroot\
/dev/mapper/luks_root
# Export your new zpool and reimport it with an alternate root to avoid mounting conflicts
zpool export zroot
zpool import -R /mnt zroot
# Create all of your datasets
# 1 - zroot/root (/)
# 2 - zroot/home (/home)
# 3 - zroot/home/root (/root)
# 4 - zroot/home/your_user_here (/home/your_user_here)
# 5 - zroot/var (/var)
zfs create -o mountpoint=/ zroot/root
zfs create -o mountpoint=/home zroot/home
zfs create -o mountpoint=/home/your_user_here zroot/home/your_user_here
zfs create -o mountpoint=/root zroot/home/root
zfs create -o mountpoint=/var zroot/var
# Configure the root filesystem
zpool set bootfs=zroot/root zroot
# Exit the chroot and copy over hte current ZFS cache
# Note: This step is required for the ZFS daemon to start
cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache
# Re-enter the chroot and set the cache for the root pool
arch-chroot /mnt
zpool set cachefile=/etc/zfs/zpool.cache zroot
# Enable the the following systemd services in order to import the zroot pool at boot
systemctl enable zfs.target zfs-import-cache.service zfs-import.target
# Set up zfs-mount-generator to generate systemd mount units for all of your datasets that need to be mounted at boot
mkdir /etc/zfs/zfs-list.cache
ln -s /usr/lib/zfs/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d
systemctl enable zfs-zed.service
systemctl start zfs-zed.service
touch /etc/zfs/zfs-list.cache/zroot
# Update a property of your root dataset in order to generate a ZED event and update the list cache for the pool
zfs set canmount=on zroot
# Restore the previous value for that dataset
zfs set canmount=off zroot
# Mount your ESP
mkdir -p /mnt/boot
mount /dev/sdx1 /mnt/boot
# Export your mount configuration to /mnt/etc/fstab
# Note: You must comment out all of the exported ZFS dataset mounts, otheriwse you will experience issues booting
genfstab -pU /mnt > /mnt/etc/fstab
# Add a tmpfs for /tmp to /mnt/etc/fstab
# tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
# Install Arch Linux
pacstrap /mnt \
base\
base-devel\
zsh\
vim\
git\
efibootmgr\
dialog\
openssh\
dhcpcd\
dosfstools\
linux\
linux-headers\
linux-firmware\
mkinitcpio\
intel-ucode\
reflector\
wpa_supplicant
# Chroot into your new installation
arch-chroot /mnt
# Set your locales
echo "LANG=en_US.UTF-8\nLC_ALL=C\nLANGUAGE=en_US" > /etc/locale.conf
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
# Set your hostname
echo "your_hostname" > /etc/hostname
# Enable NTP and set your timezone
timedatectl set-ntp true
timedatectl set-timezone your_timezone
# Enable DHCPCD on boot
systemctl enable dhcpcd
# Set your default nameserver (Cloudflare in this case)
# Add the following lines to /etc/resolv.conf:
# nameserver 1.1.1.1
# nameserver 2606:4700:4700::1001
# options single-request
# Enable the wheel sudo group
# Uncomment the following line in /etc/sudoers with visudo
# %wheel ALL=(ALL) ALL
# Create your user and set the correct permissions for your home directory
useradd your_user_here
usermod -aG wheel your_user_here
chown your_user_here:your_user_here /home/your_user_here
# Set a root password
passwd
# Set your user's password
passwd your_user_here
# Enable the multiarch repo in /etc/pacman.conf by uncommenting the following lines:
# [multilib]
# Include = /etc/pacman.d/mirrorlist
# Use reflector to order your mirrorlist for speed and update your repos
reflector -c Country -f 150 --threads `nproc` > /mnt/etc/pacman.d/mirrorlist
pacman -Sy
# Configure makepkg for faster AUR package builds
# - Uncomment and change #MAKEFLAGS="-j2" to MAKEFLAGS="-j`nproc`"
# - Change PKGEXT='.pkg.tar.xz' to PKGEXT='.pkg.tar' to disable package compression
# Give your user relevant access to their dataser
zfs allow your_user_here create,mount,mountpoint,snapshot zroot/home/your_user_here
# Su into your user and cd to your home directory
su your_user_here
cd ~
# Install Yay (or your AUR helper of of choice)
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
# Use Yay (or your AUR helper of choice) to install the following packages
yay -Sy --noconfirm --sudoloop arch-efiboot zfs-utils zfs-dkms
# Configure your initrd (udev or systemd)
# - For udev-based systems, set the following lines in /etc/mkinitcpio.conf
# MODULES=(zfs)
# HOOKS=(base udev autodetect modconf block encrypt zfs filesystems keyboard)
# - For systemd-based systems, install the follwing AUR packages
yay -Sy --noconfirm --sudoloop mkinitcpio-sd-zfs
# and set the following lines in /etc/mkinitcpio.conf
# MODULES=(zfs)
# HOOKS=(base systemd keyboard autodetect modconf block sd-encrypt sd-zfs filesystems)
# Exit your user's shell and get the UUID of your LUKS partition
lsblk -o +UUID
# Configure your kernel cmdline
# - For udev-based systems, edit /boot/cmdline.txt and add the following:
# cryptdevice=UUID=UUID_OF_YOUR_LUKS_PARTITION:luks:allow-discards zfs=zroot/root root=ZFS=zroot/root rw quiet
#
# - For systemd-based systems the configuration is a little different
# Note: There seems to be an issue with the sd-zfs systemd generator that causes importing pools by cache file to break.
# The current workaround is to just disable it by setting zfs_force=1 and zfs_ignorecache=1
#
# Edit /boot/cmdline.txt and add the following:
# rd.luks.name=UUID_OF_YOUR_LUKS_PARTITION=root zfs=zroot/root zfs_force=1 zfs_ignorecache=1 root=zfs:zroot/root rw quiet
# Rebuild your initrd as root
mkinitcpio -p linux
# Build your EFISTUB loader
# Note: If you make changes to your initrd, or files included in your initrd, you will need to re-run this command
# in order to update your EFISTUB. This includes /boot/cmdline.txt
build_efi_kernels
# Register your EFISTUB loader with efibootmgr or place it in the default x86_64 EFI location
# - Register with efibootmgr
efibootmgr -c -d /dev/sdx -p 1 -L "EFISTUB" -l "\linux.efi"
# - Move it into the default x86_64 EFI location
mkdir -p /boot/EFI/BOOT
mv /boot/linux.efi /boot/EFI/BOOT/bootx64.efi
# That's it, enjoy your new system!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment