Installation

Booter sur un live usb Arch Linux

Préparation

On passe le clavier en AZERTY :

loadkeys fr

On règle l’horloge :

timedatectl set-timezone Europe/Paris
timedatectl set-ntp true

Partitionnement

On liste les disques :

fdisk -l

On choisit le disque qui nous convient et on crée 3 (ou 4) partitions :

  • Une partition EFI (pour l’UEFI)
  • Une partition boot (pour le bootloader)
  • Une partition root ( / )
  • Optionnelement ne partition home ( /home )

On fait le partitionnement avec parted

parted /dev/sdX

La partition EFI fera 500MiB.

Avec partition /home :

mklabel gpt
mkpart primary fat32 1MiB 501MiB  #La partition EFI
set 1 esp on
mkpart primary ext4 501MiB 20.5GiB #La partition root d'environ 20GiB
mkpart primary ext4 20.5GiB 100% #La partition home prenant le reste de place
q

Sans partition /home :

mklabel gpt
mkpart primary fat32 1MiB 551MiB  #La partition EFI
set 1 esp on
mkpart primary ext4 551MiB 100% #La partition root
q

Chiffrement des partitions

On choisit une passphrase (assez longue) pour la partition /root (et une pour la partition /home si vous avez une) et on chiffre la (les) partition(s). On utilise de l’AES avec une clé de 512 bits et un temps de dérivation de clé de 5000 ms avec l’algorithme Argon2id.

cryptsetup -v --type luks -c aes-xts-plain64 -s 512 -h sha512 --pbkdf argon2id -i 5000 -y luksFormat /dev/sdX2
cryptsetup -v --type luks -c aes-xts-plain64 -s 512 -h sha512 --pbkdf argon2id -i 5000 -y luksFormat /dev/sdX3

On monte la (les) partition(s) :

cryptsetup open /dev/sdX2 racine
cryptsetup open /dev/sdX3 maison

Formatage des partitions

On formate les partitions en ext4 (sauf la partition EFI qui est en fat32) :

mkfs.fat -F32 /dev/sdX1
mkfs.ext4 /dev/mapper/racine
mkfs.ext4 /dev/mapper/maison

Installation d’Arch Linux

On monte les différentes partitions dans /mnt :

mount /dev/mapper/racine /mnt
mkdir /mnt/home && mount /dev/mapper/maison /mnt/home # Si on a /home
mkdir -p /mnt/boot/efi && mount /dev/sda1 /mnt/boot/efi

On installe les paquets de bases et le noyau hardened (pour le noyau classique, remplacer linux-hardened par linux) :

pacstrap /mnt base base-devel linux-hardened linux-hardened-headers linux-firmware

On génère ensuite notre fstab :

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

Configuration de Arch Linux

On utilise la commande chroot pour utiliser notre nouvelle installation comme racine :

arch-chroot /mnt

On choisit le nom de la machine à configurer (ici on prends pour exemple NomMachine) :

echo NomMachine > /etc/hostname
echo '127.0.0.1 NomMachine.localdomain NomMachine' >> /etc/hosts

On configure l’horloge :

ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
hwclock --systohc

On génère les locales du système :

  • En français :

    sed -i 's/#fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen
    locale-gen
    echo LANG="fr_FR.UTF-8" > /etc/locale.conf
    export LANG=fr_FR.UTF-8
    
  • En anglais :

    sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
    locale-gen
    echo LANG="en_US.UTF-8" > /etc/locale.conf
    export LANG=en_US.UTF-8
    

On configure le clavier en AZERTY :

echo KEYMAP=fr > /etc/vconsole.conf

On choisit un mot de passe pour le compte root :

passwd

Gestion du boot et du déchiffrement

On installe efibootmgr et un éditeur de texte :

pacman -S efibootmgr <EDITEUR DE TEXTE>

Comme nous n’avons pas fait de partition à part pour /boot nous allons créer une image noyau unifiée afin de pouvoir rendre notre installation bootable.

Petit aparté sur le fonctionnement du boot d’un système Linux

Généralement, pour démarrer un système Linux, l’UEFI (le microprogramme de la carte mère) commence par démarrer un bootloader, un programme dont le but est de “préparer” le système pour ensuite démarrer le noyau Linux. Le bootloader est un fichier .efi situé sur la première partition du disque. Il permet de charger un microcode pour le CPU (un ensemble de patch fourni par le constructeur du CPU pour assurer sa stabilité), initramfs (qui permet de créer un premier système de fichier pour accèder au système de fichier racine) et enfin un noyau Linux. Il permet aussi de passer des paramètres au noyau avant le démarrage. Pour plus d’informations voir https://wiki.archlinux.org/title/Arch_boot_process

Certains bootloaders, comme GRUB ou systemd-boot, permettent de choisir entre plusieurs noyaux ou systèmes d’exploitation (dans le cas d’un multiboot).

Dans notre cas, nous allons faire en sorte de pouvoir nous passer d’un bootloader (réduction de la surface d’attaque) et puisse booter directement sur le noyau. Pour cela nous allons compiler le microcode CPU, initramfs, le noyau et ses arguments dans un seul fichier .efi qui pourra directement être lancé par la carte mère.

Installation du microcode

Installation du microcode pour les processeurs Intel et AMD :

pacman -S amd-ucode     # pour AMD
pacman -S intel-udcode  # pour Intel

Si vous installez Arch sur une clé bootable, vous pouvez installer les microcodes pour Intel et AMD afin de supporter les différents processeurs.

Arguments de lancement du noyau

On récupère l’UUID de la partition / :

lsblk -f /dev/sdX2

On édite le fichier /etc/kernel/cmdline :

  • On ajoute les options pti=on, page_alloc.shuffle=1et rw.
  • On ajoute les informations permettant de déchiffrer le disque cryptdevice=UUID=<UUID de la partition>:racine root=/dev/mapper/racine (l’UUID est celui de la ligne ou FSTYPE vaut crypto_LUKS dans la commande lsblk -f /dev/sdX)
  • Enfin on ajoute les options loglevel=3 quiet bgrt_disable

Votre fichier devrait ressembler à ceci :

pti=on page_alloc.shuffle=1 rw cryptdevice=UUID=XXXXXXXX-XXXX-4XXX-XXXX-XXXXXXXXXXXX:racine root=/dev/mapper/racine mem_sleep_default=deep loglevel=3 quiet bgrt_disable

Si vous utilisez un SSD, ce qui est probable, vous pouvez améliorer les performances en lecture et en écriture de dm-crypt en désactivant les lectures et écritures asynchrones et les mécanismes de queuing : remplacez la partie cryptdevice=UUID=<UUID de la partition>:racine root=/dev/mapper/racine en cryptdevice=UUID=<VOTRE UUID>:racine:no-read-workqueue,no-write-workqueue root=/dev/mapper/racine"

Génération des images .efi

On édite le fichier /etc/mkinitcpio.conf et on ajoute les hooks keymap et encrypt qui nous permettrons de déchiffrer notre partition root au boot :

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

Si on a une partition pour /home, on modifie le fichier /etc/fstab afin de ne pas utiliser l’UUID de /dev/mapper/maison pour le monter. On commente donc la ligne correpondante et on rajoute une dernière ligne contenant

/dev/mapper/maison /home ext4 rw,relatime,data=ordered 0 2

Si vous avez un SSD et que vous souhaitez améliorer sa longévité, vous pouvez remplacer les relatime par des noatime dans /etc/fstab, cela désactivera l’horodatage des accès aux fichiers et réduira le nombre d’écritures sur le disque.

Nous allons maintenant créer un preset mkinitcpio pour générer une image unifiée bootable, pour cela on édite le fichier /etc/mkinitcpio.d/linux-hardened.preset et on met le contenu suivant :

# mkinitcpio preset file for the 'linux-hardened' unified image

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux-hardened"
ALL_microcode="/boot/*-ucode.img"

PRESETS=('default' 'fallback')

default_image="/boot/initramfs-linux-hardened.img"
default_uki="/boot/efi/EFI/Linux/archlinux-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

fallback_image="/boot/initramfs-linux-hardened-fallback.img"
fallback_options="-S autodetect"
fallback_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
fallback_uki="/boot/efi/EFI/Linux/archlinux-linux-fallback.efi"

Ce preset va nous permettre de générer deux fichiers efi /boot/efi/EFI/Linux/archlinux-linux.efi et /boot/efi/EFI/Linux/archlinux-linux-fallback.eficontenant le microcode de notre processeur, initramfs et notre noyau.

On génère les images efi :

mkdir -p /boot/efi/EFI/Linux
mkinitcpio -p linux-hardened

Ajout des entrées UEFI

On ajoute les entrées UEFI de nos images pour pouvoir les sélectionner dans notre carte mère

efibootmgr --create --disk /dev/sdX --part 1 --label "Arch Linux" --loader 'EFI\Linux\archlinux-linux.efi' --unicode
efibootmgr --create --disk /dev/sdX --part 1 --label "Arch Linux Fallback" --loader 'EFI\Linux\archlinux-linux-fallback.efi' --unicode

À ce stade votre système devrait être bootable.

Mise en place de Secure Boot

Maintenant que notre système peut booter, nous allons mettre en place secure boot.

Secure boot est un mécanisme de sécurité qui permet de vérifier que le noyau et les modules chargés au boot sont de confiance. Pour cela il s’assure que les fichiers chargés sont signés avec une clé cryptographique. Cela permet de s’assurer qu’ils n’ont pas été modifiés par un attaquant.

La première étape pour mettre en place secure boot est d’installer un outil de gestion des signatures et des clés. Pour cela on va installer sbctl :

pacman -S sbctl

On va ensuite générer des clés qui nous permettrons de signer nos fichiers efi :

sbctl create-keys

On va ensuite enregister nos clés dans la carte mère :

sbctl enroll-keys

Il est possible que vous ayez besoin de redémarrer votre système et d’aller dans l’UEFI pour passer en mode setup ou audit (suivant la façon dont le constructeur de votre carte mère l’appelle) pour avoir la possibilité d’enregistrer les clés.

Si l’enregistrement des clés échoue, vous pouvez essayer d’utiliser sbctl enroll-keys --microsoft pour enregistrer les clés de Microsoft en plus de celles que vous avez généré. En effet certains péripheriques ont leur firmware signé avec les clés de Microsoft et votre ordinateur pourrait ainsi refuser de démarrer…

Il ne reste plus qu’à signer nos fichiers efi :

sbctl sign -s /boot/efi/EFI/Linux/archlinux-linux.efi
sbctl sign -s /boot/efi/EFI/Linux/archlinux-linux-fallback.efi

On peut maintenant vérifier que les fichiers sont bien signés :

sbctl verify

Il ne reste plus qu’à rebooter, activer secure boot dans l’UEFI et vérifier que le système boot correctement.

Pour s’assurer que tout est bien configuré, on peut utiliser sbctl status pour vérifier que secure boot est bien activé et les clés enregistrées.

La commande sbctl sign-all permet de signer tous les fichiers efi qui ont déjà été signés. Si vous avez modifié certains des fichiers efi, par exemple avec mkinitcpio, vous pouvez utiliser cette commande pour les signer de nouveau.

Déchiffrement du disque via SSH

Si vous souhaitez pouvoir utiliser votre ordinateur à distance (en l’allumant via WakeOnLAN par exemple), il vous faudra pouvoir déchiffrer les disques avant même de pouvoir lancer le noyau. Pour cela, on peut utiliser dropbear, un client SSH qui se lance avec le bootloader.

Installation des dépendances

pacman -S mkinitcpio-dropbear mkinitcpio-utils mkinitcpio-netconf

Génération des clés

On génère une paire de clés Ed25519 qui serviront à la connexion SSH :

ssh-keygen -t ed25519 -f ~/.ssh/dropbear_ssh

On copie la clé publique dans le dossier de configuration de dropbear :

cp ~/.ssh/dropbear_ssh.pub /etc/dropbear/root_key

Copiez la clé privée sur l’appareil qui vous servira à déchiffrer votre disque.

Configuration de mkinitcpio

On ajoute les hooks netconf, dropbear et encryptssh dans /etc/mkinitcpio.conf :

HOOKS=(base udev autodetect modconf block netconf dropbear keyboard keymap encryptssh filesystems fsck)

Modifiez le fichier /etc/kernel/cmdline et ajoutez lui un champ ip

ip=192.168.1.1:::::eth0:none

Le champ ip à le format suivant : ip=<ip>::<gateway>:<mask>::<interface>:<none|dhcp>.

Par exemple pour que votre ordinateur démarre avec l’adresse ip 192.168.1.22 sur le réseau 192.168.1.0/24 avec une gateway en 192.168.1.254 :

ip=192.168.1.22::192.168.1.254:255.255.255.0::eth0:none

Pour détecter automatiquement la configuration réseau et utiliser le DHCP :

ip=:::::eth0:none

Génération des images .efi

On regénère ensuite nos fichiers efi

mkinitcpio -p linux-hardened

Déchiffrement du disque

Au prochain démarrage, vous aurez la possibilité de vous connecter à votre ordinateur en SSH via la clé que vous aurez généré et vous n’aurez qu’à rentrer la clé de déchiffrement de votre disque pour que votre ordinateur démarre.

Installation des paquets de base et tweaks

Réseau

Si vous souhaitez installer d’autres paquets sur votre installation, vous allez avoir besoin d’un accès à internet, c’est pourquoi avant de quitter le média d’installation, on installe NetworkManager :

pacman -S networkmanager
systemctl enable NetworkManager

Hardened Malloc

Si vous souhaitez vous prémunir un peu plus contre les failles de sécurités liées à la mémoire (buffer overflow et consors), vous pouvez remplacer l’implémentation de malloc de glibc par celle fournie par l’équipe de GrapheneOS : hardened_malloc.

Hardened malloc n’est pas disponible sur les dépots officiels d’Arch Linux mais est présent sur les dépôts communautaires (https://aur.archlinux.org/packages/hardened_malloc). Malheureusement au moment de l’écriture de ce tutoriel la signature du mainteneur n’est plus valide, nous allons donc faire l’installation à la main.

On clone le dépôt et on compile la bibliothèque

git clone https://github.com/GrapheneOS/hardened_malloc/
cd hardened_malloc
git checkout tags/11 # on se place sur la dernière version (dans le cas présent la version 11)
make # on compile hardened_malloc

Pour s’assurer de ne pas avoir de problème, on augmente le nombre de memory maps utilisables sur le système

echo 'vm.max_map_count = 1048576' > /etc/sysctl.d/hardened_malloc.conf

On installe la bibliothèque sur le système

cp out/libhardened_malloc.so /usr/local/lib/libhardened_malloc.so

On fait en sorte de charger hardened_malloc dans chaque programme

echo '/usr/local/lib/libhardened_malloc.so' >> /etc/ld.so.preload

Et voilà, vous avez installé hardened malloc sur votre système, pour le vérifier vous pouvez lancer un programme et vérifier que libhardened_malloc.so est bien chargé

cat /proc/<PID>/maps | grep hardened_malloc