Tutorial

Arch Linux Installation Guide

A comprehensive guide to installing Arch Linux with full disk encryption, secure boot, and hardened security configuration.

Updated January 19, 2025 5 min read advanced

Prerequisites

  • Basic familiarity with Linux command line
  • A bootable Arch Linux USB drive
  • Backup of any important data on the target drive
Table of Contents

This guide is a hands-on install walkthrough for a UEFI system using GPT, full-disk encryption (LUKS), and Secure Boot. It assumes a single disk and uses /dev/sda throughout. If your system uses NVMe, adjust paths (for example, /dev/nvme0n1).

Warning

These commands will erase data on the target drive. Double-check device names before partitioning or formatting.

Partition Drive

The goal is a small EFI System Partition, an unencrypted /boot for GRUB, and an encrypted root partition for everything else.

Find the drive

dmesg | grep /dev/sd

Identify the target disk name (for example, /dev/sda) before continuing.

cfdisk

cfdisk /dev/sda

Create a GPT label, then carve out the EFI, /boot, and root partitions.

End state

Label: GPT

/dev/sda1 128M EFI System
/dev/sda2 512M Linux Filesystem
/dev/sda3 <Remaining> Linux Filesystem

Partition layout recap: /dev/sda1 becomes /boot/efi, /dev/sda2 becomes /boot, and /dev/sda3 becomes the encrypted root filesystem.

Format Partitions

Use FAT32 for EFI and ext4 for the unencrypted /boot partition.

mkfs.fat -F32 /dev/sda1

mkfs.ext4 /dev/sda2

Encrypted partition

Initialize LUKS on the root partition, open it, then format the mapped device.

modprobe dm-crypt
modprobe dm-mod

cryptsetup luksFormat -v -s 512 -h sha512 /dev/sda3

cryptsetup open /dev/sda3 luks_root

mkfs.ext4 /dev/mapper/luks_root

Use a strong passphrase. This is what unlocks the root filesystem at boot.

Check Encrypted Partition Data

Confirm the mapper is active and the LUKS header looks correct.

Verify /dev/mapper/luks_root:

sudo dmsetup table luks_root

Expected output:

0 975165455 crypt aes-xts-plain64 :64:logon:cryptsetup:87103c1f-c96b-452f-93c7-742797a85926-d0 0 8:3 32768

Verify /dev/sda3:

sudo cryptsetup luksDump /dev/sda3

Mount

Mount the encrypted root first, then mount /boot and /boot/efi.

mount /dev/mapper/luks_root /mnt

mkdir /mnt/boot
mount /dev/sda2 /mnt/boot

mkdir /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi

Swap

Create a swap file inside the encrypted root. Adjust size as needed.

cd /mnt

# 8GB swap
dd if=/dev/zero of=swap bs=1M count=8192

mkswap swap

chmod 0600 swap

swapon swap

Installing Arch Linux

Refresh keys if the ISO is old, then install the base system and boot tooling.

May need to update keys first

pacman -Sy archlinux-keyring

Install main system components

pacstrap -i /mnt base base-devel linux linux-firmware linux-headers efibootmgr mkinitcpio grub vim

Filesystem table

Generate /etc/fstab so mounts persist after reboot.

genfstab -U /mnt > /mnt/etc/fstab

Initial System Config

Enter the new system for configuration.

arch-chroot /mnt

Locale

Uncomment the locale you want, then generate it.

Edit /etc/locale.gen and uncomment:

en_US.UTF-8

Generate locales:

locale-gen

Set environment variables:

echo LANG=en_US.UTF-8 > /etc/locale.conf
export LANG=en_US.UTF-8

Time

Set timezone and sync hardware clock to UTC.

ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime

hwclock --systohc --utc

Hostname

Choose a hostname and define host mappings.

echo mosiah > /etc/hostname

Edit /etc/hosts:

127.0.0.1      localhost mosiah
127.0.1.1      mosiah
::1            localhost

Reflector

Update mirrors to improve package download speed.

pacman -S reflector
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak
reflector -c "US" -f 12 -l 10 -n 12 --save /etc/pacman.d/mirrorlist

Bootloader

Configure GRUB to unlock the encrypted root partition at boot.

GRUB mount encrypted drive

Make sure the device path and mapper name match what you created earlier.

Edit /etc/default/grub:

GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda3:luks_root"

Add encrypt to mkinitcpio HOOKS

This ensures the initramfs can prompt for and unlock LUKS.

Edit /etc/mkinitcpio.conf:

HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)

Create initramfs

mkinitcpio -p linux

Install GRUB

Install the bootloader to the EFI system partition.

Tip

The --removable flag can make the difference on some systems

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch

Sticky Grub option

Useful if you keep multiple kernels and want the last selection to persist.

Edit /etc/default/grub:

GRUB_DEFAULT=saved
...
# at bottom of file uncomment the following
GRUB_SAVEDEFAULT=true

Generate grub.cfg

Regenerate this after kernel installs or bootloader changes.

# run this again after installing linux-hardened and linux-lts
grub-mkconfig -o /boot/grub/grub.cfg

First user

Create a non-root account and grant sudo via the wheel group.

useradd -m user
passwd user

usermod -aG wheel,audio,video,storage user

# check /etc/sudoers to make sure "wheel" group is uncommented
EDITOR=vim visudo

umask

Restrict default file permissions for new files and directories.

Edit /etc/profile and ~/.bashrc:

umask 027

Secure Boot

This section uses sbctl to create and enroll custom keys, then sign boot files. Make sure you are comfortable managing Secure Boot keys before proceeding.

Install sbctl

sudo pacman -S sbctl

Installed to: /usr/share/secureboot/

Check status

Confirm whether the system is in Setup Mode.

sbctl status

Generate Keys

Create Platform Key (PK), Key Exchange Key (KEK), and db keys.

sudo sbctl create-keys

Enroll Keys

Must be in Setup Mode:

sudo systemctl --firmware-setup reboot

Then:

sudo sbctl enroll-keys -m

Check Enrollment

Verify that your keys are active.

sbctl status

Check what files need to be signed

Identify unsigned EFI binaries.

sudo sbctl verify

Sign files

Sign the GRUB EFI binary (and any other reported files).

sudo sbctl sign -s /boot/efi/EFI/GRUB/grubx64.efi

Warning

Immutable file error You may get an error because of an issue with certain files being immutable. To make those files mutable, run the following command for each file then re-sign afterwards:

sudo chattr -i /sys/firmware/efi/efivars/*

Verify files are signed

sudo sbctl verify

Troubleshooting

Fixing grub 2.06 “error: verification requested but nobody cares”

See: https://wejn.org/2021/09/fixing-grub-verification-requested-nobody-cares/

  1. Regenerate .efi file (grub-install command above)
  2. In the .efi file change “SecureBoot” to “SecureB00t”
  3. Sign the .efi file

View certificates

sudo openssl x509 -in /usr/share/secureboot/keys/PK/PK.pem -text -noout

EFI boot manager

Use efibootmgr to inspect or clean up stale boot entries.

# view current bootloaders
efibootmgr

# remove an entry
efibootmgr -Bb <num>

Black Arch bootstrap

Optional: enable the BlackArch repository if you need offensive tooling. Read the official instructions carefully before enabling it.

See: https://www.blackarch.org/downloads.html#install-repo

# Run https://blackarch.org/strap.sh as root and follow the instructions.
curl -O https://blackarch.org/strap.sh

# Verify the SHA1 sum
echo 5ea40d49ecd14c2e024deecf90605426db97ea0c strap.sh | sha1sum -c

# Set execute bit
chmod +x strap.sh

# Run strap.sh
sudo ./strap.sh

# Enable multilib following https://wiki.archlinux.org/index.php/Official_repositories#Enabling_multilib and run:
sudo pacman -Syu

Desktop

This section installs the Cinnamon desktop environment. Skip if you want a minimal headless install or a different DE.

Cinnamon

pacman -S cinnamon gdm gnome-extra gnome-disk-utility baobab

Enable services

Enable display manager and networking on boot.

sudo systemctl enable gdm.service
sudo systemctl enable NetworkManager.service

Firewall

Enable iptables services (adjust if you prefer nftables).

sudo systemctl enable iptables
sudo systemctl enable ip6tables

IPv6

Additional rules are needed for IPv6 if you are using iptables:

-A INPUT -p ipv6-icmp -m limit --limit 10/sec -j ACCEPT
-A INPUT -p udp -d fe80::/64 -m conntrack --ctstate NEW -m udp --dport 546 -j ACCEPT
IPv6 Kernel Module

Load IPv6 if it is not already enabled.

sudo modprobe ipv6
IPv6 Privacy Extensions

Note

Without privacy extensions, your IPv6 address is derived from your MAC address

See: https://wiki.archlinux.org/title/IPv6

Create /etc/sysctl.d/40-ipv6.conf:

# Enable IPv6 Privacy Extensions
net.ipv6.conf.all.use_tempaddr=2
net.ipv6.conf.default.use_tempaddr=2
net.ipv6.conf.wlp2s0.use_tempaddr=2
net.ipv6.conf.eno1.use_tempaddr=2

net.ipv6.conf.wlp2s0.stable_secret = 428d:d7be:d949:8de4:xxxx:xxxx:xxxx:xxxx
net.ipv6.conf.wlp2s0.addr_gen_mode = 2

net.ipv6.conf.eno1.stable_secret = 9c37:3101:5ee7:f27d:xxxx:xxxx:xxxx:xxxx
net.ipv6.conf.eno1.addr_gen_mode = 2
IPv6 Privacy in NetworkManager

If you use NetworkManager, set IPv6 privacy to temporary addresses.

Create /etc/NetworkManager/conf.d/ipv6-privacy.conf:

[connection]
ipv6.ip6-privacy=2
IPv6 Privacy Extensions in systemd-networkd

If you use systemd-networkd instead, set per-interface privacy.

Create /etc/systemd/network/25-wireless.network:

[Match]
Name=wlp2s0

[Network]
DHCP=yes
IPv6PrivacyExtensions=kernel

Create /etc/systemd/network/20-ethernet.network:

[Match]
Name=eno1

[Network]
DHCP=yes
IPv6PrivacyExtensions=kernel

Logrotate

Uses yay (AUR helper). Install it first if you have not already.

yay -S logrotate
systemctl enable logrotate.timer
systemctl start logrotate.timer

View logs

Helpful for troubleshooting service start-up issues.

sudo journalctl -u system.*
sudo journalctl -u user.*

Fonts

Optional Microsoft fonts (requires yay).

# install yay via blackarch repos first
yay -S ttf-ms-win10-auto

Chromium

Install Chromium from AUR and set the password store to avoid startup issues.

yay -S chromium

Tip

If Chromium does not open: password-store Create ~/.config/chromium-flags.conf:

--password-store=basic

Firefox

Install Firefox from AUR.

yay -S firefox

Tip

If Firefox takes a while to load This is likely an xdg-desktop-portal timeout. Remove the GNOME portal:

yay -R xdg-desktop-portal-gnome

Steam

Requires multilib to be enabled.

yay -S steam
yay -S proton

Printers

Install and enable CUPS.

yay -S cups

sudo systemctl enable cups --now

HP

HP printer setup via HPLIP.

yay -S hplip

sudo hp-setup -i

Exit and reboot

Exit the chroot, unmount, and reboot into the new install.

exit
umount -l /mnt
reboot

Cinnamon Tweaks

Optional tweaks for the Cinnamon desktop.

Window List Applet

Align Left

In dconf-editor, navigate to org → cinnamon → enable-applets:

'panel1:left:11:<window-list-applet-id>'

Use the exact window-list applet id shown on your system (it can vary by Cinnamon version).

Drivers

Identify your GPU and install the matching driver.

lspci | grep VGA

Video

Search for Xorg video drivers.

pacman -Ss | grep xf86-video

AMD/Intel/Nvidia

Find vendor-specific packages.

pacman -Ss | grep -i amd
pacman -Ss | grep -i intel
pacman -Ss | grep -i nvidia

Microcode

Install CPU microcode updates for stability and security.

Determine whether CPU is Intel or AMD and install the corresponding microcode:

lscpu
yay -S intel-ucode
# or
yay -S amd-ucode

Grub

This should automatically be called on microcode installation, but here for completeness:

sudo grub-mkconfig -o /boot/grub/grub.cfg