0) Prep & Clock
Boot the Arch ISO, get a shell, and connect to the network (iwctl for wifi; wired connections should be automatically handled).
Check and sync time:
timedatectl status
timedatectl set-ntp true
1) Partition your disk
This is what I used for a system with 16 GiB RAM and 512 GiB
- EFI System Partition (ESP): 1 GiB, FAT32 →
/dev/sda1 - Swap: 16 GiB →
/dev/sda2 - Root: rest of disk (Btrfs, inside LUKS) →
/dev/sda3
Create them with fdisk/cgdisk and set the ESP type to EFI System.
2) Encrypt & Format
Data-at-rest encryption keeps your information safe only when the computer is not on.
# LUKS on root
cryptsetup luksFormat /dev/sda3
cryptsetup open /dev/sda3 cryptroot
# Filesystems
mkfs.btrfs -L rootfs /dev/mapper/cryptroot
mkfs.fat -F 32 /dev/sda1
mkswap /dev/sda2
3) Mount
mount /dev/mapper/cryptroot /mnt
mount --mkdir /dev/sda1 /mnt/boot
swapon /dev/sda2
(Optional) Create Btrfs subvolumes before mounting if you want them; I used a single root for simplicity.
4) Base Install
pacstrap -K /mnt base linux linux-firmware intel-ucode vim btrfs-progs networkmanager
Generate fstab and harden ESP mount with umask=0077:
genfstab -U /mnt >> /mnt/etc/fstab
# Edit the ESP line in /mnt/etc/fstab and add: umask=0077
5) Chroot & Basic System Config Speedrun
arch-chroot /mnt
Timezone & clock
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
# Or your timezone
hwclock --systohc
Locale
locale-gen
echo 'LANG=en_US.UTF-8' > /etc/locale.conf
Hostname & hosts
echo '<hostname>' > /etc/hostname
cat >> /etc/hosts <<EOF
127.0.0.1 localhost
::1 localhost
127.0.1.1 <hostname>.localdomain <hostname>
EOF
6) Enable initramfs to unlock LUKS
Edit hooks in /etc/mkinitcpio.conf to include encrypt before filesystems. Example:
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)
Build:
mkinitcpio -P
7) systemd-boot
bootctl install
/boot/loader/loader.conf
default arch.conf
timeout 0
console-mode keep
editor no
Find the UUID of the LUKS container:
blkid -s UUID -o value /dev/sda3
/boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=UUID=<UUID>:cryptroot root=/dev/mapper/cryptroot rw quiet
/boot/loader/entries/arch-fallback.conf
title Arch Linux (fallback initramfs)
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux-fallback.img
options cryptdevice=UUID=<UUID>:cryptroot root=/dev/mapper/cryptroot rw quiet
Exit and reboot:
exit
reboot
8) Making a User
Log in as root.
systemctl enable --now NetworkManager
pacman -S sudo pam-u2f exfatprogs
Create your user and a temporary password:
useradd -m -G wheel magmawolf8
passwd magmawolf8
Enable sudo for the wheel group:
export EDITOR=vim
visudo
# Uncomment: %wheel ALL=(ALL:ALL) ALL
9) Configure FIDO2
Create key file:
su - magmawolf8
mkdir -p ~/.config/Yubico
Enroll two YubiKeys (replace <hostname>):
# First key
pamu2fcfg -o pam://<hostname> -i pam://<hostname> > ~/.config/Yubico/u2f_keys
# Second key (append with -n)
pamu2fcfg -o pam://<hostname> -i pam://<hostname> -n >> ~/.config/Yubico/u2f_keys
Edit /etc/pam.d/system-auth.
Add above the pam_unix.so line:
auth [success=2 default=ignore] pam_u2f.so cue origin=pam://<hostname> appid=pam://<hostname>
Then reboot and test you can log in as magmawolf8 using the keys.
If successful and you want key-only auth:
passwd -l magmawolf8 # lock user password
passwd -l root # lock root for extra safety
10) Networking (systemd-resolved + DoT)
sudo systemctl enable --now systemd-resolved
Create a drop-in config file: /etc/systemd/resolved.conf.d/dnssec-tls.conf
[Resolve]
DNSOverTLS=opportunistic
DNSSEC=allow-downgrade
DNS=<your.dns.server,another.dns.server>
Tell NetworkManager to use resolved: /etc/NetworkManager/conf.d/dns.conf
[main]
dns=systemd-resolved
Point things to the stub:
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Disable autoconfigured DNS on your connection (adjust name as needed):
nmcli connection modify "Wired connection 1" ipv4.ignore-auto-dns yes
nmcli connection modify "Wired connection 1" ipv6.ignore-auto-dns yes
Reboot and verify:
resolvectl status # ISP-provided DNS should be inactive on eno1 or wherever you get internet from
11) GUI Stack with Hyprland
Update, then install some core packages:
sudo pacman -Syu
sudo pacman -S wayland xorg-xwayland hyprland alacritty \
noto-fonts noto-fonts-cjk noto-fonts-emoji noto-fonts-extra \
xdg-desktop-portal-hyprland xdg-user-dirs
xdg-user-dirs-update
QT (for hyprpolkitagent):
sudo pacman -S qt5-wayland qt5-svg # (qt6-wayland should already be present)
sudo pacman -S hyprpolkitagent
# Put in Hyprland config: exec-once = systemctl --user start hyprpolkitagent
Thermal stuff, only for Intel CPUs:
sudo pacman -S cpupower thermald
sudo systemctl enable --now thermald
sudo systemctl enable cpupower
12) Ly Login Manager with FIDO2
Install dev tools and build ly:
sudo pacman -S base-devel python git less zig
git clone -b fido2-integration https://github.com/magmawolf8/ly
cd ly
zig build
sudo zig build installexe # systemd is default init
Tweak services:
sudo systemctl disable [email protected]
sudo systemctl enable ly
Edit ly’s config.ini and set:
require_fido2=true
Reboot your system and confirm that the YubiKey login works for ly.
sudo pacman -S openssh
# OpenSSH supports FIDO2 keys (types: ecdsa-sk, ed25519-sk).
# Follow: https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html
Set your identity for Git purposes (if you need to):
git config --global user.name "<Your Name>"
git config --global user.email "<[email protected]>"
14) Configuring Hyprland
Place config in ~/.config/hypr/hyprland.conf (and tweak as desired).
Idle/lock & notification functionality:
sudo pacman -S hypridle hyprlock mako
15) Audio (PipeWire)
sudo pacman -S pipewire wireplumber pipewire-audio pipewire-alsa pipewire-pulse pipewire-jack
systemctl --user enable --now pipewire pipewire-pulse
wpctl set-profile "<card name>" "output:hdmi-stereo+input:analog-stereo"
16) Printer Discovery (CUPS + Avahi mDNS)
sudo pacman -S cups cups-pdf nss-mdns avahi
sudo systemctl enable cups.socket
sudo systemctl enable avahi-daemon
/etc/systemd/resolved.conf.d/mdns-disable.conf
[Resolve]
MulticastDNS=no
/etc/nsswitch.conf:
hosts: mymachines mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns
17) Hypr Ecosystem & Apps
sudo pacman -S wofi hyprpaper hyprcursor
# Set wallpaper per https://wiki.hypr.land/Hypr-Ecosystem/hyprpaper/
# Set cursor per hyprcursor instructions
sudo pacman -S firefox discord
19) Wrap it up
Reboot one more time to make sure that everything works:
- Unlock the disk -> FIDO2 login (ly) -> Hyprland -> network/DNSSEC -> audio -> printing
Have fun with your Arch installation!