Last active
May 27, 2024 23:52
-
-
Save Matthewacon/82c2c9cf797ff49528576bef36e0ae28 to your computer and use it in GitHub Desktop.
Arch install with ZFS root on LUKS and EFISTUB
This file contains 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
# 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
oh ok