# Notes on my Arch Linux installation - [Notes on my Arch Linux installation](#notes-on-my-arch-linux-installation) - [Hardware](#hardware) - [Known Issues](#known-issues) - [Preparation](#preparation) - [Pre-installation](#pre-installation) - [Select the drive](#select-the-drive) - [Zap the disk](#zap-the-disk) - [Create the partitions](#create-the-partitions) - [Check the partitions](#check-the-partitions) - [Format EFI partition](#format-efi-partition) - [Encrypt system partition](#encrypt-system-partition) - [Add an additional LUKS key](#add-an-additional-luks-key) - [Backup LUKS header](#backup-luks-header) - [Open the encrypted system partition](#open-the-encrypted-system-partition) - [Encrypt swap partition](#encrypt-swap-partition) - [Create and mount XFS filesystem](#create-and-mount-xfs-filesystem) - [Mount EFI partition](#mount-efi-partition) - [Installation](#installation) - [Install essential packages](#install-essential-packages) - [Generate fstab](#generate-fstab) - [Boot into the system](#boot-into-the-system) - [Configure the system](#configure-the-system) - [Install network manager](#install-network-manager) - [Regenerate initramfs](#regenerate-initramfs) - [Select the CPU architecture](#select-the-cpu-architecture) - [Install microcode](#install-microcode) - [Install systemd-boot](#install-systemd-boot) - [Configure systemd-boot](#configure-systemd-boot) - [Update kernel parameters](#update-kernel-parameters) - [Installing Secure Boot](#installing-secure-boot) - [Using TPM 2.0](#using-tpm-20) - [Post-installation](#post-installation) - [Set up a wireless netwok](#set-up-a-wireless-netwok) - [Create an user](#create-an-user) - [Update pacman mirrors](#update-pacman-mirrors) - [Install an AUR helper](#install-an-aur-helper) - [Install display server](#install-display-server) - [Install window manager](#install-window-manager) - [Install code editor](#install-code-editor) - [Install web browser](#install-web-browser) - [Install docker](#install-docker) - [Set up screen locker](#set-up-screen-locker) - [Set up audio](#set-up-audio) - [Change TrackPoint sensitivity](#change-trackpoint-sensitivity) - [References](#references) ## Hardware * **Lenovo ThinkPad E15G2** (20T8001UTX) * AMD Ryzen 7 4700U * 8GB RAM (+16GB) * 512GB SSD (+1 TB) * 15.6" FHD * Freedos ### Known Issues * [Fn keys does not work until a suspend/resume cycle occurs](https://forums.lenovo.com/t5/Other-Linux-Discussions/Linux-Fn-keys-not-working-Thinkpad-E14-AMD-Gen-2/m-p/5027791) ## Preparation Boot up [Arch Linux ISO](https://archlinux.org/download/) and do the following: * Disable the annoying beep sound: `rmmod pcspkr` * Bring up WiFi via `iwctl station wlan0 connect ` * Have some coffee ☕ ## Pre-installation ### Select the drive ```sh export DRIVE=/dev/nvme0n1 ``` (Use `lsblk` to determine the correct drive to install) ### Zap the disk ```sh sgdisk --zap-all $DRIVE ``` ``` -Z, --zap-all Zap (destroy) the GPT and MBR data structures and then exit. This option works much like -z, but as it wipes the MBR as well as the GPT, it's more suitable if you want to repartition a disk after using this option, and completely unsuitable if you've already repartitioned the disk. ``` ### Create the partitions ```sh sgdisk --clear \ --new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \ --new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \ --new=3:0:0 --typecode=3:8300 --change-name=3:cryptsystem $DRIVE ``` ![Partition types](https://user-images.githubusercontent.com/24392180/131268987-4b91edc6-f989-4fa8-baaa-edfc988182f3.png) ### Check the partitions ```sh lsblk -o +PARTLABEL ``` ``` NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS PARTLABEL loop0 7:0 0 641.6M 1 loop /run/archiso/airootfs sda 8:0 1 7.3G 0 disk └─sda1 8:1 1 7.3G 0 part /run/archiso/bootmnt nvme0n1 259:0 0 476.9G 0 disk ├─nvme0n1p1 259:1 0 550M 0 part EFI ├─nvme0n1p2 259:2 0 8G 0 part cryptswap └─nvme0n1p3 259:3 0 468.4G 0 part cryptsystem ``` ### Format EFI partition ```sh mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI ``` ### Encrypt system partition ```sh cryptsetup luksFormat /dev/disk/by-partlabel/cryptsystem ``` ### Add an additional LUKS key ```sh cryptsetup luksAddKey /dev/disk/by-partlabel/cryptsystem ``` ### Backup LUKS header > If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much of a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. Damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table. Therefore, having a backup of the header and storing it on another disk might be a good idea. ```sh cryptsetup luksHeaderBackup /dev/disk/by-partlabel/cryptsystem --header-backup-file /mnt//.img ``` ### Open the encrypted system partition ```sh cryptsetup open /dev/disk/by-partlabel/cryptsystem system ``` ### Encrypt swap partition > To be able to resume after suspending the computer to disk (hibernate), it is required to keep the swap space intact. Therefore, it is required to have a pre-existent LUKS swap partition or file, which can be stored on the disk or input manually at startup. ```sh cryptsetup luksFormat /dev/disk/by-partlabel/cryptswap cryptsetup open /dev/disk/by-partlabel/cryptswap swap mkswap -L swap /dev/mapper/swap swapon -L swap ``` > The following setup has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot. However, we will eliminate this by storing the LUKS key in TPM. ### Create and mount XFS filesystem ```sh mkfs.xfs -f -L system /dev/mapper/system mount LABEL=system /mnt ``` ### Mount EFI partition ```sh mkdir /mnt/boot mount LABEL=EFI /mnt/boot ``` ## Installation ### Install essential packages ```sh pacstrap /mnt base linux linux-firmware ``` ### Generate fstab ```sh genfstab -L /mnt >> /mnt/etc/fstab ``` ``` -L Use labels for source identifiers (shortcut for -t LABEL). ``` ``` # /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx LABEL=system / xfs rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota 0 1 # /dev/nvme0n1p1 UUID=xxxx-xxxx LABEL=EFI /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2 # /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx #LABEL=swap none swap defaults 0 0 # add this line instead for using the mapped device as swap /dev/mapper/swap swap swap defaults 0 0 ``` ### Boot into the system ```sh arch-chroot /mnt ``` ### Configure the system ```sh pacman -S vim ``` ```sh # Set the time zone ln -sf /usr/share/zoneinfo/Europe/Istanbul /etc/localtime # Set the Hardware Clock from the System Clock, and update the timestamps in /etc/adjtime. hwclock --systohc # Uncomment desired locales vim /etc/locale.gen # Generate the locales locale-gen # Create the hostname vim /etc/hostname # Set the root password passwd ``` ## Install network manager ```sh pacman -S netctl wpa_supplicant dhcpcd dialog ``` ### Regenerate initramfs Create a backup of the original config: ```sh cp /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig ``` Update `HOOKS` in `/etc/mkinitcpio.conf` as follows: ``` HOOKS="base systemd modconf keyboard block sd-encrypt filesystems fsck" ``` Regenerate: ```sh mkinitcpio -p linux ``` ## Select the CPU architecture ```sh export CPU_ARCH=amd # amd or intel ``` ## Install microcode > Processor manufacturers release stability and security updates to the processor microcode. These updates provide bug fixes that can be critical to the stability of your system. Without them, you may experience spurious crashes or unexpected system halts that can be difficult to track down. > All users with an AMD or Intel CPU should install the microcode updates to ensure system stability. ```sh pacman -S $CPU_ARCH-ucode ``` ## Install systemd-boot Make sure the system has booted in UEFI mode and that UEFI variables are accessible: ```sh ls /sys/firmware/efi/efivars ``` Use `bootctl` to install systemd-boot into the EFI system partition: ```sh bootctl install ``` ``` Created "/boot/EFI" Created "/boot/EFI/systemd" Created "/boot/EFI/BOOT" Created "/boot/loader" Created "/boot/loader/entries" Created "/boot/EFI/Linux" Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/systemd/systemd-bootx64.efi" Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/BOOT/BOOTX64.EFI" Created "/boot/xxxxxx" Random seed file /boot/loader/random-seed successfully written (512 bytes). Created EFI boot entry "Linux Boot Manager". ``` ## Configure systemd-boot `/boot/loader/loader.conf`: ``` default arch*.conf timeout 5 editor no console-mode auto ``` > When using the systemd-based initramfs with the `sd-encrypt` mkinitcpio hook, simply specify additional `rd.luks` kernel parameters to unlock the swap partition. `/boot/loader/entries/arch.conf`: ``` title Arch Linux linux /vmlinuz-linux initrd /-ucode.img initrd /initramfs-linux.img options rd.luks.name==system root=/dev/mapper/system rd.luks.name==swap resume=/dev/mapper/swap rw ``` * ``: `lsblk -o NAME,UUID | grep nvme0n1p3 | awk '{print $NF}'` * ``: `lsblk -o NAME,UUID | grep nvme0n1p2 | awk '{print $NF}'` * ``: value of `$CPU_ARCH` ## Update kernel parameters * `audit=0`: disable audit logs * `acpi_backlight=vendor`: prefer vendor specific driver for backlight (see the [other options](https://wiki.archlinux.org/title/Backlight#Kernel_command-line_options)) * `splash`: show splash during boot * `quiet`: enable non-verbose mode ## Installing Secure Boot \* You need to boot in the freshly installed OS (without chroot) before following these steps. Before you proceed, beware of [this](https://www.reddit.com/r/archlinux/comments/pec41w/secure_boot_selfsigned_keys_nvidia_gpu_bricked/). > Secure Boot is a security feature found in the UEFI standard, designed to add a layer of protection to the pre-boot process: by maintaining a cryptographically signed list of binaries authorized or forbidden to run at boot, it helps in improving the confidence that the machine core boot components (boot manager, kernel, initramfs) haven't been tampered with. 1. Clear existing keys and reset Secure Boot to `Setup Mode` on firmware settings. 2. `pacman -S sbctl` 3. `sbctl status` ``` Installed: Sbctl is not installed Setup Mode: Enabled Secure Boot: Disabled ``` 4. `sbctl create-keys` 5. `sbctl enroll-keys` -> `sbctl status` ``` Installed: Sbctl is installed Owner GUID: xxx Setup Mode: Disabled Secure Boot: Disabled ``` 6. `sbctl verify` -> `sbctl sign -s ` 7. `sbctl list-files` ## Using TPM 2.0 > Trusted Platform Module (TPM) is an international standard for a secure cryptoprocessor, which is a dedicated microprocessor designed to secure hardware by integrating cryptographic keys into devices. Check for support: ```sh cat /sys/class/tpm/tpm0/tpm_version_major ``` Install required packages for management: ```sh pacman -S tpm2-tss tpm2-tools ``` List available TPMs: ```sh systemd-cryptenroll --tpm2-device=list ``` ``` PATH DEVICE DRIVER /dev/tpmrm0 NTC0702:00 tpm_tis ``` > Platform Configuration Registers (PCR) contain hashes that can be read at any time but can only be written via the extend operation, which depends on the previous hash value, thus making a sort of blockchain. They are intended to be used for platform hardware and software integrity checking between boots (e.g. protection against Evil Maid attack). They can be used to unlock encryption keys and proving that the correct OS was booted. See [Accessing PCR registers](https://wiki.archlinux.org/title/Trusted_Platform_Module#Accessing_PCR_registers). Enroll the key in the TPM and the LUKS volume and bind the key to PCRs 0 and 7: ```sh systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0,7 /dev/disk/by-partlabel/cryptswap ``` * `PCR0`: Core System Firmware executable code (aka Firmware) * `PCR7`: Secure Boot State ``` New TPM2 token enrolled as key slot 1. ``` Test that the key can open the volume: ```sh /usr/lib/systemd/systemd-cryptsetup attach swap /dev/disk/by-partlabel/cryptswap - tpm2-device=auto ``` Update `/etc/crypttab` to unlock the encrypted swap at boot: ``` # Configuration for encrypted block devices. # swap /dev/disk/by-partlabel/cryptswap - tpm2-device=auto ``` Update kernel parameters (`/boot/loader/entries/arch.conf`) to use TPM for decryption: ``` [...] rd.luks.name==swap rd.luks.options==tpm2-device=auto resume=/dev/mapper/swap [...] ``` If you wish to remove LUKS keys from TPM: `systemd-cryptenroll /dev/disk/by-partlabel/cryptswap --wipe-slot=tpm2` # Post-installation ## Set up a wireless netwok ```sh wifi-menu netctl list netctl enable netctl is-enabled ``` ## Create an user ```sh useradd -G wheel -m orhun passwd orhun pacman -S sudo vi visudo # uncomment "%wheel ALL=(ALL) ALL" ``` ## Update pacman mirrors _(this section needs review)_ ```sh sudo pacman -S reflector reflector --country Germany --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist curl "https://archlinux.org/mirrorlist/?country=TR&protocol=http&protocol=https&ip_version=4" | sudo tee -a /etc/pacman.d/mirrorlist sudo vim /etc/pacman.d/mirrorlist ``` ## Install an AUR helper ```sh pacman -S git wget rust base-devel rustup install stable git clone https://aur.archlinux.org/paru cd paru/ makepkg -si ``` ## Install display server ```sh pacman -S xorg-server xorg-xinit xterm ``` Also, install `xf86-video-amdgpu` or `xf86-video-intel` based on CPU architecture respectively. ## Install window manager ```sh pacman -S i3 ``` Configure i3 and run it with [xinit](https://wiki.archlinux.org/title/Xinit). ## Install code editor ```sh pacman -S neovim ``` ## Install web browser ```sh pacman -S firefox-developer-edition ``` ## Install docker ```sh pacman -S docker usermod -a -G docker orhun systemctl enable --now docker.service ``` ## Set up screen locker Install i3lock: ```sh paru i3lock-fancy ``` Install screenshot utility: ```sh pacman -S menyoki ``` Create a script at `~/scripts/lock.sh` for locking the screen: ```sh #!/usr/bin/env bash i3lock-fancy -g -t "" -- menyoki -q cap --root png -c fast save 2>/dev/null ``` Lock the screen after 5 minutes of inactivity: 1. Install the screen locker: ```sh pacman -S xautolock ``` 2. Create `/etc/systemd/system/screen-locker.service`: ``` [Unit] Description=Lock the screen automatically after a timeout [Service] Type=simple User=orhun Environment=DISPLAY=:0 ExecStart=/usr/bin/xautolock -time 5 -locker /home/orhun/scripts/lock.sh -detectsleep Restart=on-failure RestartSec=5m [Install] WantedBy=graphical.target ``` Lock the screen after suspend: 1. Create `/etc/systemd/system/resume-locker.service`: ``` [Unit] Description=Lock the screen on resume from suspend Before=suspend.target [Service] Type=forking User=orhun Environment=DISPLAY=":0" ExecStart=/usr/bin/bash /home/orhun/scripts/lock.sh [Install] WantedBy=suspend.target WantedBy=sleep.target ``` 2. Keep the lock screen from flashing the desktop: 2.a. Create `/lib/systemd/system-sleep/blank`: ```sh #!/usr/bin/env bash if [ "$1" == "pre" ]; then sleep 2 fi ``` 2.b. `chmod +x /lib/systemd/system-sleep/blank` Lastly, start/enable both services: ```sh systemctl enable --now screen-locker.service systemctl enable --now resume-locker.service ``` ## Set up audio Check the audio device: ```sh lspci | grep -i audio ``` Install pipewire/pulse: ```sh pacman -S alsa-utils pipewire pipewire-pulse systemctl start --user pipewire-pulse.service pactl info ``` Set up bluetooth: ```sh rfkill unblock all pacman -S bluez bluez-utils systemctl start bluetooth.service systemctl enable bluetooth.service ``` Update `/etc/bluetooth/main.conf` to auto power-on the bluetooth device after boot: ``` [Policy] AutoEnable=true ``` Configure bluetooth headset: ``` bluetoothctl [bluetooth]# power on [CHG] Controller XX:XX:XX:XX:XX:XX Class: 0x006c010c Changing power on succeeded [CHG] Controller XX:XX:XX:XX:XX:XX Powered: yes [bluetooth]# agent on Agent is already registered [bluetooth]# default-agent Default agent request successful [bluetooth]# scan on Discovery started [CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes [NEW] Device E8:D0:3C:8B:7B:48 JBL TUNE500BT [bluetooth]# pair E8:D0:3C:8B:7B:48 Attempting to pair with E8:D0:3C:8B:7B:48 [CHG] Device E8:D0:3C:8B:7B:48 Connected: yes [CHG] Device E8:D0:3C:8B:7B:48 ServicesResolved: yes [CHG] Device E8:D0:3C:8B:7B:48 Paired: yes Pairing successful [CHG] Device E8:D0:3C:8B:7B:48 ServicesResolved: no [CHG] Device E8:D0:3C:8B:7B:48 Connected: no [bluetooth]# connect E8:D0:3C:8B:7B:48 Attempting to connect to E8:D0:3C:8B:7B:48 [CHG] Device E8:D0:3C:8B:7B:48 Connected: yes Connection successful [CHG] Device E8:D0:3C:8B:7B:48 ServicesResolved: yes [JBL TUNE500BT]# trust E8:D0:3C:8B:7B:48 [CHG] Device E8:D0:3C:8B:7B:48 Trusted: yes Changing E8:D0:3C:8B:7B:48 trust succeeded [JBL TUNE500BT]# scan off [JBL TUNE500BT]# exit ``` Update `/etc/pulse/default.pa` for auto connecting to the bluetooth headset: ``` ### Automatically switch to newly-connected devices load-module module-switch-on-connect ``` ## Change TrackPoint sensitivity Install `xinput` for configuring devices: ```sh pacman -S xorg-xinput xf86-input-libinput ``` List the available devices by running `xinput` command: ``` ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ ETPS/2 Elantech Touchpad id=12 [slave pointer (2)] ⎜ ↳ ETPS/2 Elantech TrackPoint id=13 [slave pointer (2)] ``` List the properties of the TrackPoint: ```sh xinput list-props "ETPS/2 Elantech TrackPoint" ``` ``` [...] libinput Accel Speed (316): 0.000000 libinput Accel Speed Default (317): 0.000000 libinput Accel Profiles Available (318): 1, 1 [...] ``` Override the `libinput Accel Speed` property in `/etc/X11/xorg.conf.d/20-thinkpad.conf`: ```conf Section "InputClass" Identifier "TrackPoint Configuration" MatchProduct "ETPS/2 Elantech TrackPoint" Option "AccelSpeed" "-0.65" EndSection ``` ## References - https://wiki.archlinux.org/title/Installation_guide - https://wiki.archlinux.org/title/User:Altercation/Bullet_Proof_Arch_Install - https://wiki.archlinux.org/title/GPT_fdisk - https://wiki.archlinux.org/title/Dm-crypt/Device_encryption - https://wiki.archlinux.org/title/Dm-crypt/Swap_encryption - https://wiki.archlinux.org/title/Trusted_Platform_Module#Data-at-rest_encryption_with_LUKS - https://wiki.archlinux.org/title/XFS - https://wiki.archlinux.org/title/Systemd-boot - https://wiki.archlinux.org/title/Microcode - https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate - https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot - https://wiki.archlinux.org/title/Netctl - https://github.com/Foxboron/sbctl - https://wiki.archlinux.org/title/Xorg - https://man.archlinux.org/man/reflector.1#EXAMPLES - https://wiki.archlinux.org/title/Allow_users_to_shutdown - https://wiki.archlinux.org/title/Advanced_Linux_Sound_Architecture - https://wiki.archlinux.org/title/PipeWire - https://wiki.archlinux.org/title/bluetooth_headset - https://wiki.archlinux.org/title/Bluetooth#Auto_power-on_after_boot - https://wiki.archlinux.org/title/Session_lock - https://wiki.archlinux.org/title/docker - https://wiki.archlinux.org/title/TrackPoint