This page explains the basic setup of Arch Linux. It was last updated at 2024-06-30.
Info
Always cross check all commands with the current version of the Arch Installation Guide, as the instructions on this page might be outdated.
Caution
Commands in this guide will modify your hard disk, including partitions, encryption and more. Make sure to understand all commands before you execute them. You will lose data! Consult the Arch Wiki or the man pages of all commands and options you are unfamiliar with.
Tip
Create a backup of all important data that you do not want to lose prior to the installation of Arch Linux.
To install Arch Linux, boot from the installation medium. It might be necessary to change UEFI settings to do so. For example:
DELL XPS 13 9370
System Configuration -> USB Configuration -> Enable USB Boot SupportPOST Behaviour -> Fastboot to any value other than MinimalSecure Boot can also already be enabled and set to audit mode. This allows the machine to boot without any valid secure boot keys with a warning message. As soon as we have set up valid secure boot keys and signed our boot image, secure boot can then be enabled to fail on unsigned boot images.
Secure Boot -> Secure Boot Enable -> Secure Boot EnableSecure Boot -> Secure Boot Mode to Audit ModeSecure Boot -> Expert Key Management -> Enable Custom ModeTo access the boot menu:
F2 to access UEFI settingsF12 to access one-time boot menuList available console key maps with localectl list-keymaps. Set the desired key map with loadkeys <key map>.
Console fonts are located in /usr/share/kbd/consolefonts and can be set with setfont <font>.
Info
These changes are temporary and will be lost during reboot. They will be persisted later. Should you need to reboot your machine before these settings are persisted, repeat these steps after a reboot.
Example
loadkeys de-latin1
setfont eurlatgr
Tip
On HiDPi screens, a larger font might be desirable. E.g. ter-132b (the largest font), or ter-118n. If you need
region-specific special characters, set the key map, e.g. setfont ter-118n -m 88591.
Verify that the system is booted in UEFI mode.
cat /sys/firmware/efi/fw_platform_size
This command should return 64. If the command returns 32, the system is booted in UEFI mode and has a 32-bit IA32
UEFI. While this is supported by Arch Linux, it is not supported by this guide.
If the file does not exist, the system may be booted in BIOS or CSM mode. In this case, disable CSM Mode and restart the computer.
Warning
This guide does not work on systems in BIOS mode, or with IA32 UEFI!
Make sure that the computer is connected to the internet with ip link and ip a.
A quick test for a working internet connection can be done with ping -c3 archlinux.org.
If you are not connected, follow one of these steps, depending on the connection you want to set up:
rfkill list.Verify the connection again with ping -c3 archlinux.org.
Once a network connection is established, the system clock should be updated automatically. Check the correct date and
time has been acquired with timedatectl.
Get an overview of available disks with lsblk and/or fdisk -l. Make sure to identify the drives you want to install
Arch Linux to.
This guide sets up two partitions. The first partition is the EFI system partition. It will be used to boot from a unified kernel image. The second partition will be a LUKS encrypted partition, inside of which will be a LVM2 container with SWAP, system, and data partitions. Feel free to modify the setup of the file systems inside the LUKS encrypted partition as you see fit. The unencrypted EFI partition is required though.
Info
Even though we use LVM2 inside of the LUKS encrypted partition, this setup does not allow for the LVM2 volume group to span multiple disks. This is a limitation of this setup. If this limitation is unacceptable for you, check LVM on LUKS in the Arch Wiki for workarounds, or different partition layouts.
Caution
The following steps will repartition and format the disks you specify in the commands. Double-check all drive paths in the upcoming commands. Specifying the wrong drive paths will erase data from drives you did not intend to erase!
Repartitioning the drives and switching to a new encrypted disk will not mask any of your previously unencrypted data. The unencrypted data might still be recoverable by data recovery or data forensic tools. If you want to make sure that data previously stored on the disk is un-recoverable, you need to overwrite all of the disk with random data.
Depending on your disk size and write speed, this can take hours.
If your disk was already encrypted previously, or you do not consider this an option, skip to the next section.
Overwriting your disk with data can be achieved by the following commands
cryptsetup open -q --type pain -d /dev/urandom <drive path> to_be_wiped
dd bs=4M if=/dev/zero of=/dev/mapper/to_be_wiped conv=fsync oflag=direct status=progress
cryptsetup close to_be_wiped
Create a 1GB EFI partition, and use the rest of the disk for the encrypted LUKS partition. To format the disk, use
fdisk <drive path>; here are some helpful commands:
m to show helpg to create a new GPT partition tablen to create a new partitiont to change the type of a partition1: EFI System43: Linux Raidw to write changes and quitCreate the LUKS encrypted system partition and open it.
cryptestup luksFormat <luks partition>
cryptestup open <luks partition> cryptlvm
You can skip this section if you are not using a SSD (Solid State Drive).
You might want to configure TRIM support and disable workqueues to improve performance of SSD Drives.
Warning
Enabling TRIM support on an encrypted drive has potential security implications. See TRIM support for solid state drives. If this is an issue, you might want to skip this step.
Verify your SSD supports TRIM:
lsblk --discard
Enable TRIM support:
cryptsetup --allow-discards --persistent refresh cryptlvm
Drive operation workqueues make sense for slow spinning disks. For SSDs, they usually introduce unnecessary delays. Disabling workqueues can double the speed of file operations on SSDs. Disable the workqueues with the following command
cryptsetup --perf-no_read_workqueue --perf-no_write_workqueue --persistent refresh cryptlvm
Inside the encrypted system partition, create the logical volumes.
pvcreate /dev/mapper/cryptlvm
vgcreate vgsys /dev/mapper/cryptlvm
lvcreate -L <swap size> vgsys -n lvswap
lvcreate -L 32G vgsys -n lvroot
lvcreate -L 32G vgsys -n lvhome
lvcreate -L 32G vgsys -n lvopt
lvcreate -L 32G vgsys -n lvvar
Tip
The SWAP partition can be of any size. The Arch Wiki recommends at least 4GB. If you want to be able to use hibernation, I would recommend two times your physical RAM size.
The (estimated) minimum SWAP space (in bytes) for successful hibernation can be found by looking at
cat /sys/power/image_size. It is usually around 2/5 of the available physical RAM.
Create the file system on the EFI partition, logical volumes and swap.
mkfs.fat -F 32 -n EFI <efi partition>
mkfs.ext4 -L root /dev/vgsys/lvroot
mkfs.ext4 -L home /dev/vgsys/lvhome
mkfs.ext4 -L opt /dev/vgsys/lvopt
mkfs.ext4 -L var /dev/vgsys/lvvar
mkswap /dev/vgsys/lvswap
Mount the create file systems.
swapon /dev/vgsys/lvswap
mount /dev/vgsys/lvroot /mnt
mount --mkdir /dev/vgsys/lvhome /mnt/home
mount --mkdir /dev/vgsys/lvopt /mnt/opt
mount --mkdir /dev/vgsys/lvvar /mnt/var
mount --mkdir <efi partition> /mnt/efi
Packages are installed from mirrors servers, which are defined in /etc/pacman.d/mirrorlist. On the ISO, after
connecting to the internet, reflector updates the mirror list by choosing the 20 most recently synchronized HTTPS
mirrors, sorting them by download rate.
The higher a mirror is placed in the list, the more priority it is given when downloading a package. You might want to inspect the mirror list to see if it is satisfactory. If it is not, edit the file accordingly or run reflector to create a new mirror list specified by custom sort parameters.
The file /etc/pacman.d/mirrorlist of the live ISO image is the only configuration file that will be copied from the
live ISO to the operating system that is being installed. So getting it right is worth some effort now.
The following command will instruct reflector to select the 10 most up to date https mirrors from Germany, Austria, Switzerland, and Netherlands - then sort them by age.
reflector --country Germany,Austria,Switzerland,Netherlands --protocol https --latest 10 --sort age --save /etc/pacman.d/mirrorlist
Install the essential packages
pacstrap -K /mnt base linux linux-firmware exfatprogs e2fsprogs lvm2 neovim git base-devel man-db man-pages texinfo \
terminus-font intel-ucode efibootmgr sbctl openssh wget
Tip
On AMD based systems, replace intel-ucode with amd-ucode
Configure the installed system following the upcoming chapters.
Generate the file system table: genfstab -U /mnt >> /mnt/etc/fstab. Check the file /mnt/etc/fstab.
Change root into the new system arch-chroot /mnt.
Configure the correct time zone ln -sf /usr/share/zoneinfo/<Region>/<City> /etc/localtime.
Example
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
Then update the system clock with hwclock --systohc.
Edit the file /etc/locale.gen and uncomment needed locales. Generate the locales by running locale-gen.
Example
I usually enable the following locales on my systems:
de_DE.UTF-8 UTF-8de_DE ISO-8859-1de_DE@euro ISO-8859-15en_GB.UTF-8 UTF-8en_GB ISO-8859-1en_US.UTF-8 UTF-8en_US ISO-8859-1Create the file /etc/locale.conf and set the LANG variable as well as other environment variables accordingly. The
settings depend on your location and personal preference.
LANG=en_GB.UTF-8
LANGUAGE=en_GB.UTF-8
LC_CTYPE=en_GB.UTF-8
LC_NUMERIC=en_GB.UTF-8
LC_TIME=en_GB.UTF-8
LC_COLLATE=en_GB.UTF-8
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES=en_GB.UTF-8
LC_PAPER=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
Persist the settings of console keyboard layout and font. Create the file /etc/vconsole.conf:
FONT=eurlatgr
KEYMAP=de-latin1-nodeadkeys
Set the hostname in /etc/hostname. The hostname should contain the domain name, if any.
Install Network Manager that should manage the network configuration of our system.
pacman -S networkmanager
Then enable the systemd services for Network Manager.
systemctl enable NetworkManager
systemctl enable systemd-resolved
systemctl enable systemd-timesyncd
Create the file /etc/NetworkManager/conf.d/20-connectivity.conf with the following content
[connectivity]
uri=https://zechert.net/connectivity_check.txt
Create the file /etc/NetworkManager/conf.d/10-dns.conf with the following content
[main]
dns=systemd-resolved
To use the NTP Servers advertised by the DHCP Server, create a new network manager dispatcher script:
/etc/NetworkManager/dispatcher.d/10-update-timesyncd.
#!/bin/sh
[ -z "$CONNECTION_UUID" ] && exit 0
INTERFACE="$1"
ACTION="$2"
case $ACTION in
up | dhcp4-change | dhcp6-change)
[ -n "$DHCP4_NTP_SERVERS" ] || exit 0
mkdir -p /etc/systemd/timesyncd.conf.d
cat <<-THE_END >"/etc/systemd/timesyncd.conf.d/${CONNECTION_UUID}.conf"
[Time]
NTP=$DHCP4_NTP_SERVERS
THE_END
systemctl restart systemd-timesyncd.service
;;
down)
rm -f "/etc/systemd/timesyncd.conf.d/${CONNECTION_UUID}.conf"
systemctl restart systemd-timesyncd.service
;;
esac
Make the script executable with chmod +x /etc/NetworkManager/dispatcher.d/10-update-timesyncd.
Create the following file /etc/systemd/system/networkdown.service:
[Unit]
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/bin/sh -c 'rm -f /etc/systemd/timesyncd.conf.d/*.conf'
RemainAfterExit=yes
[Install]
WantedBy=suspend.target
Enable the service with systemctl enable networkdown
MAC randomization can be used for increased privacy by not disclosing the real MAC address to the network.
Create the file /etc/NetworkManager/conf.d/01-random-mac.conf with the following content:
[device]
wifi.scan-rand-mac-address=yes
[device-mac-randomization]
wifi.scan-rand-mac-address=yes
[connection-mac-randomization]
ethernet.cloned-mac-address=stable
wifi.cloned-mac-address=stable
Create the file /etc/NetworkManager/conf.d/00-ipv6-privacy.conf with the following content:
[connection]
ipv6.ip6-privacy=2
Create the file /etc/sysctl.d/40-ipv6.conf with the following content:
net.ipv6.conf.all.use_tempaddr=2
net.ipv6.conf.default.use_tempaddr=2
NetworkManager uses DUID-UUID from /etc/machin-id for all DHCPv6 connections. This might be a security breach.
Instead, configure NetworkManager to create unique DUIDs for each connection.
Create the file /etc/NetworkManager/conf.d/02-duid.conf with the following content
[connection]
ipv6.dhcp-duid=stable-uuid
Create the file /etc/systemd/resolved.conf.d/30-dnssec.conf with the following content
[Resolve]
DNSSEC=true
Create the file /etc/NetworkManager/conf.d/30-mdns.conf with the following content
[connection]
connection.mdns=0
Create the file /etc/systemd/resolved.conf.d/30-mdns.conf with the following content
[Resolve]
MulticastDNS=no
Create the file /etc/NetworkManager/conf.d/30-llmnr.conf with the following content
[connection]
connection.llmnr=0
Create the file /etc/systemd/resolved.conf.d/30-llmnr.conf with the following content
[Resolve]
LLMNR=no
Edit the file /etc/mkinitcpio.conf and add the necessary hooks for the system.
Add the hook udev keyboard keymap consolefont encrypt lvm2 resume to the list of hooks as follows:
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems resume fsck)
Create the file /etc/cmdline.d/01-cryptlvm.conf with the following content
cryptdevice=UUID=<UUID of encrypted partition>:cryptlvm root=/dev/vgsys/lvroot resume=/dev/vgsys/lvswap
The UUID can be found with the command ls -all /dev/disk/y-uuid. It can be conveniently copied into the
cmdline.d/01-cryptlvm.conf file with the command
ls -all /dev/disk/by-uuid | grep "<encrypted partition>" | awk '{print $9}' >> /etc/cmdline.d/01-cryptlvm.conf
Create the file /etc/cmdline.d/02-root.conf with the following content
root=/dev/vgsys/lvroot
Create the file /etc/cmdline.d/03-resume.conf with the following content
resume=/dev/vgsys/lvswap
UKI creates a single executable that can be directly booted from the UEFI firmware without any bootloader.
Modify the file /etc/mkinitcpio.d/linux.preset.
#) the PRESET_uki= parameter for each item in PRESETS=PRESET_image= to avoid storing a redundant initramfs-*.img fileCreate the directory /efi/EFI/Linux, then create the initcpio mkinitcpio -P.
Make sure that the generation succeeded and two files have been created ls /efi/EFI/Linux, called
arch-linux-fallback.efi and arch-linux.efi.
With efibootmgr check for existing EFI Boot Menu Entries, remove them if required, and create new entries for
Arch Linux.
efibootmgrefibootmgr -Defibootmgr -b XXXX -Befibootmgr -o XXXX,YYYY,ZZZZCreate the following two new entries
efibootmgr --create --disk <efi partition> --loader=/EFI/Linux/arch-linux.efi --label "Arch Linux" --verbose
efibootmgr --create --disk <efi partition> --loader=/EFI/Linux/arch-linux-fallback.efi --label "Arch Linux Fallback" --verbose
Unfortunately the UEFI kernel image is not stored on an encrypted disk, and cannot be. Since the EFI firmware needs to be able to access the image to boot the system. Therefore, the system is at risk by an attacker that can manipulate the kernel image and boot partition. As a remedy to this problem, we will enable secure boot. The boot loader file will be cryptographically signed by a secret key that is stored on our encrypted partition.
We will use the tool sbctl for a user friendly way to configure secure boot.
First, check the current status with sbctl status. You should see that sbctl is not installed, and that secure boot
setup mode is enabled.
Creeate new keys: sbctl create-keys. Then enroll the new keys with sbctl enroll-keys -m.
Caution
The parameter -m in the command sbctl enroll-keys -m will enroll your own keys alongside with the
default microsoft keys. The microsoft keys might be required by any option roms or some firmware in the system.
You can omit the option -m to only enroll your own keys without Microsoft's. But you might create a system that
can no longer boot and might even be hard-bricked! Only do this if you know the risk and know what you are doing. If you want to do this, replace -m by --yes-this-might-brick-my-machine.
sbctl comes with the necessary hooks pre-installed to automatically sign images when needed. Since we have created
new and fresh keys, we need to trigger this now manually once. Run mkinitcpio -P to recreate images and trigger
sbctl into signing the new images.
Set the password for the user root, then create a normal user account.
Modify the sudoers file, so that the group sudo has access to the sudo command.
passwd root
groupadd -r sudo
EDITOR=nvim visudo
useradd -c "<full user name"> -m -s /bin/bash <username>
usermod -aG adm,log,rfkill,sys,wheel,sudo,video,input <username>
chfn <username>
passwd <username>
Confirm the new user can successfully use sudo to elevate permission.
su - <username> (CTRL+d can be used to exit the user account and go back to root)sudo whoami, check if sudo works. The output should be root.CTRL+d or exit.For increased security, disable login as root with passwd --lock root.
Switch to the user account you just created with su - <username>. Run the following commands to install yay, a
AUR package helper.
cd ~
sudo pacman -S git base-devel go
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
yay -S yay
cd ~
rm -rf yay
exit
Change the configuration of pacman in /etc/pacman.conf. Enable the options you want to set, e.g.
Color, VerbosePkgList, ParallelDownloads.
Then install the package pacman -S pacman-contrib and enable the service systemctl enable paccache.timer.
For SSDs only, enable periodic trim.
systemctl enable fstrim.timer
Warning
Enabling TRIM can leak some information about the encrypted system, e.g. presence of encrypted file systems, or even file system types. If this is a concern to you, or you want to achieve plausable deniability, do not enable TRIM on your system.
Install reflector with pacman -S reflector
Edit the options in /etc/xdg/reflector/reflector.conf. Then enable the timer service
systemctl enable reflector.
Reboot the system into the installed Arch Linux.
# exit chroot environment with
exit
# unmount all partitions
umount -R /mnt
# reboot
reboot
Remove your installation media.
After the system rebooted, make sure to set the following symlink!
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Use nmtui to connect to a wireless network, if required.
Create a new ssh keyapair. Alternatively copy an existing one.
ssh-keygen -t ed25519 -C "$(whoami)@$(uname -n)-$(date -I)"
Run a full system upgrade with pacman -Syu.