-
Notifications
You must be signed in to change notification settings - Fork 10
Installation
Create a bootable UEFI USB —
Before installation —
Secure erasure
Disk partitioning —
Setup the disk encryption —
Setup the LVM
Formatting the file systems —
Btrfs subvolumes —
Base system
Setup the boot manager —
Graphical environment
After using Ubuntu and Debian for a while, I decided to switch to Arch Linux to provide a simple and lightweight OS. In addition, Arch Linux allows me to keep up to date with the latest versions of packages, which I greatly appreciate.
First of all, you should know that I'm willing to bring a new tutorial to bring my knowledge on some details. After reading about it, I found that the right compromise between safety and comfort was still LVM on LUKS.
The main reason for this choice of encryption is that I like to have a key to unlock all the volumes of the LVM, without going through one (or more) USB keys and risk losing them.
NOTE: don't forget that Arch Wiki remains the ultimate reference.
After this installation, you will have the following disk layout:
+----------------------------+ +-------------------------------------------------+
| EFI system partition (ESP) | | Logical volume |
| | | |
| /boot | | / |
| | | |
| | | /dev/mapper/lvmvg-root |
| (may be on other device) | |-------------------------------------------------|
| | | |
| | | LUKS2 encrypted partition |
| /dev/nvme0n1p1 | | /dev/nvme0n1p2 |
+----------------------------+ +-------------------------------------------------+
where only the ESP is not encrypted as the bootloader needs to access the /boot directory and thus load the initramfs/encryption modules needed to load the rest of the system.
NOTE: within the encrypted partition, we will use a swap file, so that we can easily size and delete it on the fly.
Finally, the /dev/mapper/lvmvg-root logical volume will be format in Btrfs and create two sub-volume:
roothome
On the assumption that:
- X is the volume ID;
- Y is the partition ID.
sudo fdisk /dev/sdX
sudo mkfs.vfat -F32 /dev/sdXY
sudo mlabel -i /dev/sdXY ::LABEL
Replace archlinux by the name of your ISO image of Arch Linux:
sudo dd if=archlinux.iso of=/dev/sdX bs=4M status=progress && sync
-
bs(block size): on modern equipment (less than 5 years old), 4MB is a good bet; -
if: source of the ISO image of Arch Linux; -
of: destination to install the ISO image of Arch Linux; -
status: automatically print periodic updates in the standard output.
To do that, checks the following things:
- USB Flash Drive is first on the priority of boot;
- Secure Boot is disabled.
Before proceeding with the installation of Arch Linux, it is important to:
- change the console font;
- check if you have an Internet access;
- booted in UEFI mode or not.
For the grace of your eyes, we will adjust the font of the console:
pacman -Sy terminus-font
setfont ter-v32n
To verify that your system has Internet access, you can check it by pinging to any site (e.g. Google):
ping -c 3 google.com
To find out if you started in UEFI mode (recommended), simply check that the following command returns a list of defined UEFI variables. Otherwise, it means you have started in BIOS Legacy mode:
efivar -l
Let's enable automatic time synchronization with the remote NTP server:
timedatectl set-ntp true
Before the disk partitioning we need to avoid cryptographic attacks or unwanted file recovery. This is done by performing a secure erasure from the disk by overwriting the entire drive with random data.
NOTE: overwriting the entire drive with random data can take hours or even days, according to the size of your drive.
If like me you have an SSD, consider performing a SSD memory cell clearing to minimize flash memory cache artifacts. Otherwise, I invite you to directly go to the next section.
Since I use a Lenovo ThinkPad, I have a different name for the SSD:
| SSD name | Commonly used SSD name |
|---|---|
| /dev/nvme0n1 | /dev/sdx |
Replace /dev/nvme0n1 with your SSD name.
To achieve a SSD memory cell clearing, hdparms utility only works for devices that understand the ATA protocol (cf. Arch Wiki). So, if like me, you have a NVMe SSD, then you need to install nvme-cli:
sudo pacman -S nvme-cli
sudo nvme format -s 1 /dev/nvme0n1
Replace /dev/nvme0n1 with your SSD name.
Let's fill our disk with random data to protect ourselves in order to protect ourselves against disclosure of usage patterns.
cryptsetup open --type plain -d /dev/urandom /dev/nvme0n1 to_be_wiped
Once done, check that the container exists:
lsblk
dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=4096 status=progress
NOTE: a use of if=/dev/urandom is not required as the encryption cipher is used for randomness.
cryptsetup close to_be_wiped
The partitioning that follows concerns the UEFI installation. Be careful if you want to install Arch Linux in a Legacy BIOS mode.
First of all, I have different names for the partitions, but don't be lost for so little:
| Partition name | Commonly used partition name |
|---|---|
| /dev/nvme0n1p1 | /dev/sdx1 |
| /dev/nvme0n1p2 | /dev/sdx2 |
Our Arch Linux will have two partitions:
| Mount point | Partition name | Partition type | Bootable flag | Suggested size |
|---|---|---|---|---|
| /boot | /dev/nvme0n1p1 | EFI System | Yes | 512 Mo |
| / | /dev/nvme0n1p2 | Linux LVM | No | Remainder of the device |
Where / will be a LVM encrypted partition having a group volume containing a physical volume and root as a logical volume.
Finally, as mentioned in the introduction, we will format the root volume in Btrfs and create two sub-volume:
/root/home
NOTE: according to Theodore Ts'o, principal developer of ext3 and ext4 file systems, ext4 has improved features, it is not a major advance; it uses old technology and is a stop-gap. He adds that Btrfs is the best direction because "it offers improvements in scalability, reliability and ease of management".
Without going into details, Btrfs is stable, allows for better data compression, easily handles snapshots and RAIDs.
In order to know the name of your disk, it is necessary to list the partition tables for the specified devices:
fdisk -l
Let's select our disk to build the table:
gdisk /dev/nvme0n1
Then, create a new empty GTP partition table by pressing the o key.
n
Partition number (1-128, default 1):
First sector (2048-2000409230, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-2000409230, default = 2000409230) or {+-}size{KMGTP}: +512M
Current type is'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to 'EFI System'
n
Partition number (2-128, default 2):
First sector (1050624-2000409230, default = 1050624) or {+-}size{KMGTP}:
Last sector (1050624-2000409230, default = 2000409230) or {+-}size{KMGTP}:
Current type is'Linux filesystem'Hex code or GUID (L to show codes, Enter = 8300): 8e00
Changed type of partition to'Linux LVM'
Before writing the two partitions, check that they are correct by pressing the p key.
You should have such a partition table:
| Number | Start (sector) | End (sector) | Size | Code | Name |
|---|---|---|---|---|---|
| 1 | 2048 | 1050623 | 512.0 MiB | EF00 | EFI System |
| 2 | 1050624 | 2000409230 | 953.4 GiB | 8E00 | Linux LVM |
Now that the partition table is created, all you have to do is write it to the disk by pressing the w key.
In order to enable disk encryption, we will first create a root LUKS volume, open it and then format it.
To keep it short, LUKS is a container format that will be used to encrypt containers, where our encryption key will be stored.
To encrypt our / partition, we will use the cryptsetup tool:
cryptsetup --hash sha512 --use-random --verify-passphrase luksFormat /dev/nvme0n1p2 --type luks2
Are you sure? YES
Enter passphrase (twice)
NOTE: the majority of current CPU platforms being 64 bits, I recommend using SHA-512 which allows better performance than the SHA-256 for keys of size ≥ 256 bytes (default size for cryptsetup).
The / partition being encrypted, we will open the LUKS container on /dev/nvme0n1p2 disk and name it cryptlvm:
cryptsetup open /dev/nvme0n1p2 cryptlvm --type luks2
Enter passphrase
The decrypted container is now available at /dev/mapper/cryptlvm.
LVM is a logical volume manager for the Linux kernel. It is thanks to it that we can easily resize our partitions if necessary.
pvcreate /dev/mapper/cryptlvm
vgcreate lvmvg /dev/mapper/cryptlvm
lvcreate -l 100%FREE lvmvg -n root
As partitions are created, each of them must be formatted with an appropriate file system:
mkfs.fat -F32 /dev/nvme0n1p1
mkfs.btrfs -L btrfs /dev/mapper/lvmvg-root
Subvolumes are part of the filesystem with its own and independent file/directory hierarchy, where each subvolumes can share file extents.
NOTE: a snapshot is also a subvolume, but with a given initial content of the original subvolume.
mount /dev/mapper/lvmvg-root /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
umount /mnt
mkdir /mnt/{boot,home}
SSD_MOUNTS="autodefrag,compress=lzo,discard,inode_cache,noatime,nodev,rw,space_cache,ssd"
mount -o subvol=root,$SSD_MOUNTS /dev/mapper/lvmvg-root /mnt
mount -o subvol=home,$SSD_MOUNTS,nosuid /dev/mapper/lvmvg-root /mnt/home
mount -o discard,noatime,nodev,noexec,nosuid,rw /dev/nvme0n1p1 /mnt/boot
Small details on the options given with the -o flag:
-
autodefrag: enable automatic file defragmentation for small random writes in files with a maximum file size of 64K; -
compress=lzo: compresses files with the lzo type which is a lossless data compression algorithm that is focused on decompression speed; -
discard: enable discarding of freed file blocks using TRIM operation (useful for SSD devices); -
inode_cache: enable free inode number caching (may cause an overflow problem when the free space checksums do not match one page); -
noatime: allows measurable performance gains by eliminating the need for the system to write to the file system for files that are simply read; -
nodev: disallows creating and accessing device nodes (used in particular for special files in /dev); -
noexec: does not allow the execution of executable binaries in the mounted file system; -
nosuid: specifies that the filesystem cannot contain set userid files; -
rw: allows reading and writing; -
space_cache: control the free space cache. This greatly improves performance when reading block group free space into memory; -
ssd: by default,Btrfswill enable or disable SSD allocation heuristics depending on whether a rotational or non-rotational device is in use.
NOTE: some of these options are not useful to you if you don't use an SSD.
Before changing anything, it is good to make a backup of this file:
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bk
To update the mirrors, we are going to use 8 threads to select the 200 most recently synchronized HTTP or HTTPS mirrors, sort them by download speed, and overwrite the file /etc/pacman.d/mirrorlist:
pacman -S reflector
reflector --latest 200 --threads 8 --verbose --protocol http --protocol https --sort rate --save /etc/pacman.d/mirrorlist
pacstrap /mnt base btrfs-progs dialog linux linux-firmware wpa_supplicant
Small details about the given packages to pacstrap:
-
base: package groups which include basic libraries likegccandlinux; -
btrfs-progs: userspace utilities to manage btrfs filesystems; -
dialog: tool to display dialog boxes from shell scripts (useful forwifi-menu); -
linux: the kernel; -
linux-firmware: the firmware; -
wpa_supplicant: support for WEP, WPA and WPA2.
In this section, we will configure the system base in order to have a decent environment.
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
To create the swap file, we will create a zero length file, set the No_COW attribute and make sure compression is disabled:
truncate -s 0 /swapfile
chattr +C /swapfile
btrfs property set /swapfile compression none
To determine the perfect size for your swap memory, refer to this table:
| RAM | Recommended swap space | Recommended swap space for hibernation |
|---|---|---|
| ⩽ 2 GB | 2 * RAM | 3 * RAM |
| 2 GB - 8 GB | RAM | 2 * RAM |
| 8 GB - 64 GB | ≥ 4GB | 1.5 * RAM |
| > 64 GB | ≥ 4GB | hibernation not recommended |
Source: RedHat's recommendation.
As I've got 16 GB of RAM, I will use a swap file of 24G:
dd if=/dev/zero of=/swapfile bs=1M count=24576 status=progress && sync
Set the permissions for the file (a world-readable swap file is a huge local vulnerability):
chmod 600 /swapfile
Format the /swapfile file to swap and activate it:
mkswap /swapfile
swapon /swapfile
Finally, add an entry for the swap file in the fstab:
sudo echo "/swapfile none swap defaults 0 0" >> /etc/fstab
ln -sf /usr/share/zoneinfo/Europe/Brussels /etc/localtime
Generate /etc/adjtime:
hwclock --systohc
Replace en_US by your location in the next command and execute it.
sed -i '/en_US.UTF-8 UTF-8/s/^#//g' /etc/locale.gen
Generate the locales:
locale-gen
Set the LANG variable in /etc/locale.conf:
echo "LANG=en_US.UTF-8" >> /etc/locale.conf
echo "FONT=ter-132n" >> /etc/vconsole.conf
Install and enable network management daemon:
sudo pacman -S networkmanager
systemctl enable NetworkManager
In this example, the computer hostname is ThinkPad. Replace it with whatever you like.
echo ThinkPad > /etc/hostname
Add matching entries to /etc/hosts:
echo "127.0.0.1 localhost" >> /etc/hosts
echo "::1 localhost" >> /etc/hosts
echo ":127.0.1.1 ThinkPad.localdomain ThinkPad" >> /etc/hosts
passwd
In order to avoid using root all the time, it is important to create your user account with the command below, by replacing Who Cares with your full name and someone with your username:
useradd -m -G storage,video,wheel -c 'Who Cares' -s /bin/bash someone
passwd someone
Small details about the given groups to someone:
-
storage: pre-systemd group, to give access to removable drives; -
video: pre-systemd group, to give access to video capture devices; -
wheel: administration group, commonly used to give privileges to perform administrative actions.
Finally, allow users to sometimes have root privileges in order to perform some administrative tasks:
sudo sed -i '/# %wheel ALL=(ALL) ALL/s/^# //' /etc/sudoers
nano /etc/mkinitcpio.conf
When using the ramdisk environment, it is necessary to take into account LVM, Btrfs support and others.
-
Add
vfatin theMODULESsection. -
Add
encrypt lvm2 resumein theHOOKSsection beforefilesystems. -
Remove
fsckfrom theHOOKSsection: Thus,systemdwillfsckall filesystems having afsckpass number greater than 0 (either from/etc/fstabor a user-supplied unit file). -
Add
btrfsat the end ofHOOKS.
To summarize, you must have this in your MODULES and HOOKS sections:
MODULES=(vfat)
HOOKS=(base udev autodetect modconf block encrypt lvm2 resume filesystems keyboard btrfs)
Finally, recreate the initramfs image:
mkinitcpio -p linux
Since we have an EFI system and we will probably not use all the features of GRUB, we will install systemd-boot for our simple UEFI boot manager that executes configured EFI images.
bootctl install
echo "default arch" > /boot/loader/loader.conf
echo "timeout 0" >> /boot/loader/loader.conf
echo "console-mode max" >> /boot/loader/loader.conf
echo "editor no" >> /boot/loader/loader.conf
Small details about the given parameters entered:
-
default: default entry to select; -
timeout: menu timeout in second, useful to allow people who have multiple operating systems; -
console-mode: changes UEFI console mode; -
editor: whether to enable the kernel parameters editor or not. Strongly recommended to set this option tonoto avoid bypass root password and gain root access.
To add the loader, it is necessary to distinguish 2 cases:
- For AMD processors the microcode updates are available in
linux-firmware, which is installed as part of the base system. - For Intel processors, it is necessary to install the
intel-ucodepackage and add the lineinitrd /intel ucode.imgas shown below:
sudo pacman -S intel-ucode
echo "title Arch Linux" > /boot/loader/entries/arch.conf
echo "linux /vmlinuz-linux" >> /boot/loader/entries/arch.conf
echo "initrd /intel-ucode.img" >> /boot/loader/entries/arch.conf
echo "initrd /initramfs-linux.img" >> /boot/loader/entries/arch.conf
echo "options cryptdevice=UUID=$(blkid /dev/nvme0n1p2 -s UUID -o value):lvm:allow-discards root=/dev/mapper/lvmvg-root rootfstype=btrfs rootflags=subvol=root resume=/dev/mapper/lvmvg-root resume_offset=$(filefrag -v /swapfile | sed '4q;d' | awk '{print $4}' | cut -d'.' -f1) quiet splash rw" >> /boot/loader/entries/arch.conf
Where the <UUID> in cryptdevice corresponds to the UUID of the encrypted root (e.g. /dev/nvme0n1p2).
Small details about the given parameters entered:
-
title: operating system name; -
linux: path tovmlinuz(statically linked executable file that contains the Linux kernel); -
initrd: path toinitramfs; -
options: command line options to pass to the EFI program or kernel parameters.
Small details about the options given to the cryptdevice:
-
allow-discards: enables TRIM support on the SSDs; -
rootfstype: root file system type; -
resume: allows you to resume after suspending the computer from the disk, keeping the swap space intact.
Congratulations, we are ready for a first reboot, don't forget to remove installation media:
exit
umount -R /mnt
reboot
The installation of Arch linux being done, this section can be optional for you, since your desires for the GUI are probably different from mine.
However, if you are interested in trying my graphical environment, then this section may be useful for you.
NOTE: This section includes the installation of the main base packages I use, and therefore does not include an exhaustive list.
To do things right to the end, I invite you to adopt sway, an i3-compatible Wayland compositor:
pacman -S sway
Complementary to sway, install third-party packages:
pacman -S grim light mako redshift-wlr-gamma-control-git slurp swayidle swaylock waybar wofi wf-recorder
Small details about third-party packages:
-
grim: region selector for a Wayland compositor; -
light: control backlights; -
mako: lightweight notification daemon for a Wayland compositor; -
redshift-wlr-gamma-control-git: adjusts the color temperature for Wayland; -
slurp: allows you to take images for a Wayland compositor; -
swayidle: idle management daemon for a Wayland compositor; -
swaylock: screen locker for a Wayland compositor; -
waybar: highly customizable Wayland bar for Sway and Wlroots based compositors; -
wofi: Program launcher for a Wayland compositor; -
wf-recorder: screen recorder for Wlroots based compositors.
Unless you want to install all your packages manually, you should use an AUR helper and more specifically yay:
sudo pacman -S git
git clone https://aur.archlinux.org/yay
cd yay
makepkg -sri
cd .. && rm -r yay
To avoid problems, I recommend using the development version:
yay -S wl-clipboard-git
As a terminal, I use alacritty, a cross-platform, GPU-accelerated terminal emulator:
pacman -S alacritty
For the Shell, I like to use ZSH for its many features:
pacman -S zsh zsh-completions
Regarding configuration management and zsh plugins, oh-my-zsh is recommended:
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
GNU Emacs, of course:
pacman -S emacs
I use qutebrowser, a keyboard-driven, vim-like browser based on PyQt5:
pacman -S qutebrowser
pacman -S gnome-keyring-query networkmanager-dmenu-git nmap
Small details about third-party packages:
-
gnome-keyring-query: provides limited command-line access to the Gnome keyring. -
nmap: utility for network discovery and security auditing. -
networkmanager-dmenu: dmenu for network manager.
pacman -S ntfs-3g
For what I do, gimp and inkscape, satisfies me:
pacman -S gimp inkscape
Using GNU Stow, installing the configuration of my dotfiles is easy:
pacman -S stow
git clone https://github.com/rememberYou/dotfiles.git
cd dotfiles
chmod +x stowsym.sh
./stowsym.sh -i
ln -sf ~/.config/bash/.bashrc ~
ln -sf ~/.config/zsh/zshenv ~/.zshenv
I prefer mpv, because it has a video output based on OpenGL:
pacman -S mpv
If like me you need to write French on a qwerty keyboard, then xkb-qwerty-fr allows you to provide a French qwerty keymap:
yay -S xkb-qwerty-fr
Firstly, install cups, the standards-based, open source printing system:
yay -S cups
Then, enable and start the service:
systemctl enable org.cups.cupsd.service
systemctl start org.cups.cupsd.service
Finally, install the CUPS driver for your printer (e.g. Brother MFC-J4710DW):
yay -S brother-mfc-j4710dw
Let's use ALSA to manage device drivers and lowest-level support for audio hardware:
sudo pacman -S alsa-utils
In order to be able to manage several simultaneous inputs, and to allow networked audio, let's install PulseAudio as a sound server:
sudo pacman -S pulseaudio
Finally, let's install audacity in case we need to do sound processing:
sudo pacman -S audacity
Managing icons can be a real mess. That's why I recommend installing the Nerd Fonts which have a large collection of icons:
yay -S nerd-fonts-complete
Even if I use GNU Emacs, I like to read my RSS/Atom feds with newsboat, for its performance:
pacman -S newsboat
For everyday needs, cronie does the job well:
pacman -S cronie
A good practice is to regularly back up the installed packages, in order to easily reinstall the list of packages during a future reinstallation of your system.
To do this, create the location where you want to make your backups and edit the current crontab:
mkdir -p ~/Backups/packages
crontab -e
where the rules to be added to the crontab are:
5 */2 * * * /usr/bin/yay -Syuw --noconfirm
*/50 * * * * echo "$(yay -Qnq)" > ~/Backups/packages/native.list
*/50 * * * * echo "$(yay -Qmq)" > ~/Backups/packages/foreign.list