Logo

Arch Linux Secure Setup: BTRFS, LUKS Encryption, Secure Boot

February 18, 2020
5 min read

Your laptop gets stolen and your files are now readable by everyone. Standard Arch installations often skip physical access protections — the standard guide gives you a working system but no protection from the real world.

This guide adds encryption, secure boot, and snapshots without making the system painful to use. We’ll implement LUKS2 encryption so your files stay locked even if someone has physical access to your disk, BTRFS snapshots to roll back broken updates, and secure boot so only trusted code can boot your system.

Time to stop accepting compromised security as the default.

System Preparation and Boot Setup

Before starting any installation, you need to verify your system supports modern security features and prepare the firmware for custom secure boot keys. Your system must be UEFI-based (not legacy BIOS) and support clearing/managing secure boot keys - most laptops from 2012 onwards meet these requirements, but older systems may not be compatible.

Enter your UEFI settings and put secure boot into “setup mode” - this clears existing manufacturer keys and allows you to install your own custom keys later. The exact steps vary by manufacturer, so check your computer’s documentation for the specific key combination and menu navigation.

Boot from the Arch ISO and run these verification commands:

Terminal window
# Confirm UEFI mode (directory should exist and contain files)
ls /sys/firmware/efi/efivars
# Check secure boot status (should return 1 for setup mode)
efivar -d --name 8be4df61-93ca-11d2-aa0d-00e098032b8c-SetupMode
# Connect to internet and verify connectivity
iwctl station wlan0 connect "Network_Name"
ping -c 3 archlinux.org
# Optional: Set up remote SSH access for easier installation
# Set temporary root password and get IP address
passwd
ip addr show

Disk Setup and Partitioning

Before touching any disks, identify your target drive carefully - choosing wrong will permanently erase that device’s data. This setup creates two partitions: a small 512MB EFI boot partition (which stays unencrypted so your computer can start) and a large encrypted partition containing your entire operating system and files.

Terminal window
# List all storage devices to identify your target disk
lsblk
# Set the disk variable (e.g. /dev/nvme0n1, /dev/sda, /dev/vda)
export DISK="/dev/nvme0n1"
# Wipe existing partition table and create new GPT layout
sgdisk -Z $DISK
sgdisk -n1:0:+512M -t1:ef00 -c1:EFISYSTEM $DISK
sgdisk -n2:0:0 -t2:8304 -c2:LINUXROOT $DISK
# Verify the partition layout
lsblk $DISK

Encryption and Filesystem Configuration

The storage layers keep your data safe and recoverable. The filesystem layer (BTRFS) handles snapshots for quick recovery and compression to fit more data in less space. The encryption layer (LUKS2) ensures your data stays private even if someone removes your drive and connects it to another computer.

Choose a strong encryption passphrase that you can type during daily boots - it’s required every time the system starts. The setup process will format your drive and create the encrypted container, so double-check you’re working with the correct device.

Terminal window
# Create and open encrypted container (you'll be prompted for passphrase)
cryptsetup luksFormat --type luks2 /dev/disk/by-partlabel/LINUXROOT
cryptsetup luksOpen /dev/disk/by-partlabel/LINUXROOT root
# Format EFI system partition and encrypted BTRFS partition
mkfs.vfat -F32 -n EFISYSTEM /dev/disk/by-partlabel/EFISYSTEM
mkfs.btrfs -L linuxroot /dev/mapper/root

BTRFS Subvolume Structure and Mounting

BTRFS subvolumes split the drive into separate areas that can be snapshotted independently. When an update breaks something, the system files can be restored without losing home folder or requiring a full reinstall.

The @ subvolume holds the operating system - kernel, packages, and configs. @home contains personal files and settings. @snapshots stores recovery points created before updates. @var_log keeps system logs separate so they don’t fill up snapshots with data that changes constantly.

Terminal window
# Set up BTRFS subvolume structure for system snapshots
mount /dev/mapper/root /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@var_log
umount /mnt
# Mount all partitions and subvolumes with compression enabled
mount -o subvol=@,compress=zstd,noatime /dev/mapper/root /mnt
mkdir -p /mnt/{efi,home,.snapshots,var/log}
mount /dev/disk/by-partlabel/EFISYSTEM /mnt/efi
mount -o subvol=@home,compress=zstd,noatime /dev/mapper/root /mnt/home
mount -o subvol=@snapshots,compress=zstd,noatime /dev/mapper/root /mnt/.snapshots
mount -o subvol=@var_log,compress=zstd,noatime /dev/mapper/root /mnt/var/log
# Verify all mounts are correct
findmnt /mnt

Package Installation and System Configuration

Fast package mirrors reduce installation time and keep updates reliable. This minimal selection includes only what’s needed for an encrypted, secure system.

The essential packages: base provides the core system foundation, linux and linux-firmware for the kernel and drivers, CPU microcode for security updates, btrfs-progs for filesystem tools, cryptsetup for disk encryption, sbctl for secure boot management, snapper for system snapshots, sudo for privilege escalation, networkmanager for network connectivity, reflector for mirror management, and nano for text editing during configuration.

Terminal window
# Configure package mirrors for faster downloads and updates
# Replace IT with your country code (e.g., IT, US, GB, DE)
reflector --country IT --age 24 --protocol https --sort rate --save /etc/pacman.d/mirrorlist
# Install base system with encryption and security packages
# Choose intel-ucode for Intel CPUs, amd-ucode for AMD CPUs
pacstrap -K /mnt base linux linux-firmware intel-ucode btrfs-progs \
sudo networkmanager cryptsetup sbctl snapper reflector nano
# Generate filesystem configuration and verify it's correct
genfstab -U /mnt >> /mnt/etc/fstab
# Verify the generated fstab contains entries for all your subvolumes
cat /mnt/etc/fstab
# Should show entries for /, /home, /.snapshots, /var/log, and /efi
# Enter the installed system for configuration
arch-chroot /mnt

System Localization and User Setup

Configure timezone, language settings, and user accounts to complete the base system setup. The timezone ensures accurate timestamps for logs and scheduled tasks. Locale settings control how the system displays dates, numbers, and text encoding. A dedicated user account with sudo privileges provides administrative access while avoiding the security risks of running daily tasks as root.

Terminal window
# Set timezone for your location (e.g., Europe/Rome, America/New_York)
ln -sf /usr/share/zoneinfo/Europe/Rome /etc/localtime
hwclock --systohc
# Configure system locale
# Edit the file and uncomment your preferred locale (e.g., en_US.UTF-8)
nano /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
# Set system hostname (replace 'username' with your preferred name)
echo "username" > /etc/hostname
# Configure hostname resolution
nano /etc/hosts
# Add these lines (replace 'username' with your hostname):
127.0.0.1 localhost
::1 localhost
127.0.1.1 username.localdomain username
# Set root password first, then create user account
passwd
# Create user account with sudo privileges (replace 'username' with your choice)
useradd -m -G wheel username
passwd username
echo "%wheel ALL=(ALL:ALL) ALL" > /etc/sudoers.d/wheel
# Disable root password login for security (only after creating user!)
passwd -l root

Boot Configuration and Encryption Setup

Configure the bootloader to automatically unlock your encrypted drive and load the correct system partition. The kernel needs specific parameters to find and decrypt your root filesystem during startup, and the initramfs must include the right modules to handle BTRFS and LUKS encryption before the main system loads.

Terminal window
# Get UUIDs and create kernel command line configuration
LUKS_UUID=$(blkid -s UUID -o value /dev/disk/by-partlabel/LINUXROOT)
BTRFS_UUID=$(blkid -s UUID -o value /dev/mapper/root)
# Create kernel command line directory and file
mkdir -p /etc/kernel
echo "quiet rd.luks.name=$LUKS_UUID=root root=UUID=$BTRFS_UUID rootflags=subvol=@ rw" > /etc/kernel/cmdline
# Verify the command line was created correctly
cat /etc/kernel/cmdline
echo "LUKS UUID: $LUKS_UUID"
echo "BTRFS UUID: $BTRFS_UUID"
# Configure systemd-based initramfs with encryption support
sed -i 's/^HOOKS=.*/HOOKS=(systemd autodetect modconf kms keyboard sd-vconsole sd-encrypt block btrfs filesystems fsck)/' /etc/mkinitcpio.conf
# Verify the configuration
grep HOOKS /etc/mkinitcpio.conf
# Rebuild initramfs with new configuration
mkinitcpio -P

Unified Kernel Images and Secure Boot

Create signed kernel images that your system trusts and can boot securely. Unified Kernel Images combine the kernel, initramfs, and boot parameters into one file that gets cryptographically signed with your custom keys. This prevents malicious code from running during boot and ensures only your authorized system components can start - if someone tries to modify the kernel or inject malware, the signature verification will fail and the system won’t boot.

The custom secure boot keys replace the manufacturer’s default keys, giving you complete control over what code your system will execute. Once configured, kernel updates automatically rebuild and re-sign the unified image, maintaining security without manual intervention.

Terminal window
# Configure unified kernel image generation
nano /etc/mkinitcpio.d/linux.preset
# Replace the entire file content with:
PRESETS=('default')
ALL_config="/etc/mkinitcpio.conf"
default_uki="/efi/EFI/Linux/arch-linux.efi"
# Create the EFI directory structure
mkdir -p /efi/EFI/Linux
# Generate custom secure boot keys and enroll them
sbctl create-keys
sbctl enroll-keys -m
sbctl status
# Generate and sign the unified kernel image
mkinitcpio -P
sbctl sign -s /efi/EFI/Linux/arch-linux.efi
sbctl verify
# Install systemd-boot as backup bootloader
bootctl install
# Create automatic signing hook for kernel updates
mkdir -p /etc/pacman.d/hooks
nano /etc/pacman.d/hooks/90-uki.hook
# Add these lines:
[Trigger]
Operation = Upgrade
Type = Package
Target = linux
[Action]
Description = Rebuild and sign UKI after kernel upgrade
When = PostTransaction
Exec = /usr/bin/mkinitcpio -P && /usr/bin/sbctl sign -s /efi/EFI/Linux/arch-linux.efi
# Verify the hook was created
cat /etc/pacman.d/hooks/90-uki.hook

System Services and Installation Completion

Enable essential system services and finalize the secure installation. Configure Snapper for automatic filesystem snapshots before package updates, allowing instant rollback from broken changes. The timeline timer creates regular snapshots (hourly snapshots kept for a day, daily for a week, weekly for a month, monthly for a year). The cleanup timer prevents disk overflow by removing old snapshots according to configured policies. NetworkManager provides network connectivity management.

Terminal window
# Create snapper configuration for root filesystem
snapper -c root create-config /
# Configure snapper cleanup policies
snapper -c root set-config TIMELINE_LIMIT_HOURLY=6 TIMELINE_LIMIT_DAILY=3 TIMELINE_LIMIT_WEEKLY=2 TIMELINE_LIMIT_MONTHLY=6
# Enable automatic snapshots, cleanup, and network management
systemctl enable snapper-timeline.timer snapper-cleanup.timer
systemctl enable NetworkManager
# Verify all services are configured to start at boot
systemctl is-enabled NetworkManager snapper-timeline.timer snapper-cleanup.timer
snapper -c root list-configs
# Check that snapper created its initial snapshot
snapper -c root list
# Exit chroot environment and clean shutdown
exit
umount -R /mnt
cryptsetup luksClose root
reboot

Post-Installation Verification

After booting into your new system, verify all security features are working correctly:

Terminal window
# Check secure boot status (should show "enabled")
sbctl status
# Verify encryption is active (should show /dev/mapper/root)
lsblk
# Check BTRFS subvolumes are mounted correctly
findmnt -t btrfs
# Verify snapper is working (should show initial snapshots)
snapper -c root list
# Check that services are running (should show "active")
systemctl status NetworkManager snapper-timeline.timer snapper-cleanup.timer
# Test network connectivity
ping -c 3 archlinux.org

Maintenance and Troubleshooting

Most maintenance runs automatically - systemd services handle snapshots and pacman hooks rebuild kernel images after updates. When things break, it’s usually kernel signing failures or full disks.

Monitor snapshot storage regularly since they accumulate quickly and can fill your drive. Back up your LUKS headers and secure boot keys immediately - lose these and your encrypted data becomes permanently inaccessible, even with the correct passphrase.

Terminal window
# Manual kernel image rebuild and signing (if automatic hook fails)
sudo mkinitcpio -P
sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi
# Verify kernel signature and secure boot status
sudo sbctl verify
sudo sbctl status
# Check available disk space (snapshots can consume significant space)
df -h /
btrfs filesystem usage /
# Manage snapshots (delete old ones if needed)
snapper -c root list
snapper -c root delete <SNAPSHOT_NUMBER>
# Configure automatic cleanup policies if needed
snapper -c root set-config TIMELINE_LIMIT_DAILY=7
# Backup LUKS headers (critical for recovery - store offline!)
sudo cryptsetup luksHeaderBackup /dev/disk/by-partlabel/LINUXROOT --header-backup-file luks-header-backup.img
# Backup secure boot keys (store safely with LUKS backup)
sudo cp -r /usr/share/secureboot/keys/ ~/secureboot-keys-backup/
# Test rollback capability (creates test snapshot)
sudo snapper -c root create --description "Pre-test snapshot"
# Make some changes, then test rollback:
sudo snapper -c root list
sudo snapper -c root undochange <SNAPSHOT_NUMBER>..<NEXT_SNAPSHOT_NUMBER>

Security Considerations

Your system now resists theft, tampering, and boot-time attacks, but installation security is just the foundation. Real-world protection requires ongoing maintenance - firewalls block network intrusions, timely updates patch vulnerabilities, strong passwords prevent credential attacks, and offline backups ensure recovery from hardware failure.

The encryption and signing keys you created during installation are single points of failure. Store LUKS headers and secure boot keys separately from your encrypted system - if you lose them, your data becomes permanently inaccessible even with the correct passphrase. No amount of encryption strength can recover from lost keys.

Consider additional hardening measures for comprehensive security. Configure a firewall to block unwanted network traffic, enable automatic security updates for timely vulnerability patches, and use strong unique passwords for all accounts. Regular offline backups protect against hardware failures and system corruption, while monitoring system logs helps detect suspicious activity and potential intrusions.

Security is an ongoing process, not a one-time setup. The encrypted, signed system you’ve built provides strong protection against physical and boot-time attacks, but maintaining that security requires regular attention to updates, backups, and monitoring. A secure foundation is worthless without secure practices built on top of it.