Initramfs et GRUB

Initramfs

initramfs est un schéma pour charger une image temporaire de systèmes de fichiers permettant le démarrage du noyau Linux.

Il faut mettre keyboard avant modconf et ajouter keymap encrypt lvm2 après block pour initramfs.

vim /etc/mkinitcpio.conf
HOOKS=(base udev autodetect keyboard modconf block keymap encrypt lvm2 filessytems fsck)
mkinitcpio -p linux

Référence : Wiki Arch Linux sur mkinitcpio

GRUB

GRUB est un boot loader qui vous nous permettre de choisir sur quel systeme on souhaite démarrer une machine. Nous l'avons téléchargé précédement.

Partition chiffrée

Nous allons commencer par trouver les UUID de la partition root et efi :

blkid
/dev/nvme0n1p1: UUID="C423-D675" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI system partition" PARTUUID="b1070c21-2d6f-434f-80c3-37cdd3e5899b"
/dev/nvme0n1p4: BLOCK_SIZE="512" UUID="7C66315266310E80" TYPE="ntfs" PARTUUID="9ae311e5-026b-418b-be9b-4bfbabcf914d"
/dev/nvme0n1p5: UUID="546c759f-924d-4811-b853-84c328ca55f2" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="618fc4b6-6cf9-834d-82b0-978c6d4c6a8d"
/dev/nvme0n1p6: UUID="ad022385-b683-4e48-8e66-3cb027b67a9a" TYPE="crypto_LUKS" PARTUUID="af351b03-8486-e648-8358-8008f9b0b747"
/dev/nvme0n1p7: UUID="e473a1cb-95f7-4cfd-8770-9fcc07f0a52b" TYPE="crypto_LUKS" PARTUUID="3eaa5115-7707-d349-ab7b-c887854f8872"
/dev/sr0: UUID="731ac0004d532055" LABEL="CCCOMA_X64FRE_EN-US_DV9" BLOCK_SIZE="2048" TYPE="udf"
/dev/sda1: LABEL="ARCH_202104" UUID="4A6B-045F" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="001304a7-01"
/dev/loop0: TYPE="squashfs"
/dev/mapper/crypt_pool: UUID="B4xto1-7Fwb-layI-wWdY-yoxu-68CF-7WZYUt" TYPE="LVM2_member"
/dev/nvme0n1p3: PARTLABEL="Basic data partition" PARTUUID="2079ff68-8dc3-46f5-a18a-80077802e160"
/dev/nvme0n1p2: PARTLABEL="Microsoft reserved partition" PARTUUID="38cadc6a-a4d2-4b59-98ac-76fa03d0f95a"
/dev/mapper/lvmpool-home: UUID="50ec36ca-ab6a-42f9-aa33-6e17f181a8c9" BLOCK_SIZE="4096" TYPE="ext4"
/dev/mapper/crypt_root: UUID="85dfd718-6b00-4dd8-bd69-cf0ad366f28f" BLOCK_SIZE="4096" TYPE="ext4"

Ici, l'UUID de root est ad022385-b683-4e48-8e66-3cb027b67a9a et celui de efi est C423-D675.

Dans la configuration de grub (/etc/default/grub), nous allons modifier GRUB_CMDLINE_LINUX pour qu'il ait le format suivant :

GRUB_ONLINE_LINUX="cryptdevice=UUID=${ROOT_UUID}:crypt_root root=/dev/mapper/crypt_root"

Dans le cas où le SSD supporte TRIM (référence), mettre :

GRUB_ONLINE_LINUX="cryptdevice=UUID=${ROOT_UUID}:crypt_root:allow-discards root=/dev/mapper/crypt_root"

Windows 10

Dans /etc/grub.d/40_custom, Nous allons ajouter Windows 10 à GRUB. $FS_UUID est l'uuid de la partition efi :

#!/bin/sh

set -e

tail -n +3 $0

if [ "${grub_platform}" == "efi" ]; then
    menuentry "Windows 10" {
        insmod part_gpt
        insmod fat
        insmod search_fs_uuid

        search --fs-uuid --set=root $FS_UUID
        chainloader /EFI/VeraCrypt/DcsBoot.efi
    }
fi

On va maintenant générer GRUB :

grub-install --target=x86_64-efi --recheck
grub-mkconfig -o /boot/grub/grub.cfg

Secure Boot

Il est possible de changer les commandes executés par GRUB au démarrage d'une machine et ainsi boot avec root sans mot de passe (Référence).

Nous ne verrons ici que la sécurisation de la version 2 de GRUB, la version 1 étant relativement peu utilisée.

Nous allons voir comment protéger la modification des commandes GRUB, afin de protéger notre machine au démarrage mais de ne pas avoir à entrer un mot de passe tout le temps. Notre machine est déjà chiffrée, ça suffit.

N'utilisez pas l'instruction password, elle requiert un mot de passe en clair. Nous utiliserons plutot grub-mkpasswd-pbkdf2 pour le hasher.

grub-mkpasswd-pbkdf2

Dans /etc/grub.c/40_custom, ajouter à la fin :

# Password
set superusers="<nom de l'utilisateur>"
password_pbkdf2 <nom de l'utilisateur> <le hash généré par grub-mkpasswd-pbkdf2>

Cela donne par exemple :

# Password
set superusers="supersaloperie"
password_pbkdf2 supersaloperie grub.pbkdf2.sha512.10000.3527FF766CC755FA99FD7BD74F30A5DF3E4C6DE0F2C48C9F573C53DA75D03FAC09B7A82FDA0276802393BEDB0BAE8C3AC4F882D3E87BAAC6E82F9EB5C959D4B4.FAE05D6223B15D24FFED8AD0489C421271B119D7C4F6921DF8A429E0EFD312EF279E3A720453C8066D39183B70016702AFE9C23A37B6AB877D5CB3328084798E

superusers acceuille une liste d'utilisateurs, séparés par des espace, virgules, point-virgules ou pipes (|). Si la liste est vide, cela désactive l'accès à la CLI et à la modification des commandes.

Afin que des entrées puissent être utilisées sans mot de passe, il est possible de rajouter --unrestricted après un menuentry. De la même manière, on peut restreindre l'accès à une entrée à un utilisateur en particulier avec --users "<les utilisateurs>" :

set superusers="supersaloperie"
password_pbkdf2 supersaloperie grub.pbkdf2.sha512.10000.[...]
password saloperie insecure

menuentry "Runnable by anyone" --unrestricted {
    echo "Saloperie de Wiki"
    halt
}

menuentry "Only supersaloperie" --users "" {
    echo "Super Saloperie"
    halt
}

menuentry "supersaloperie et saloperie" --users saloperie {
    echo "Que les saloperies"
    reboot
}

Pensez donc à passer dans tous vos fichiers de configuration (/etc/grub.d/) et ajouter --unrestricted ou --users <users> si vous le souhaitez. Quand cela est fait, recréer le fichier de configuration de grub :

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

Redemarrage sur l'OS precedement demarre

Dans certains cas il peut être intéressant de pouvoir enregistrer le dernier OS lancé afin de le lancer à nouveau au prochain redémarrage (AKA les MAJ Windows, si vous êtes en dual boot notamment). Pour arriver à ce résultat trois choix s'offrent à vous :

  • lancer la commande de génération de grub citée plus haut : grub-mkconfig -o /boot/grub/grub.cfg en précisant GRUB_DEFAULT=saved devant
  • modifier le fichier /etc/default/grub pour y ajouter cette même variable : GRUB_DEFAULT=saved et générer le fichier de config
  • deprecié ou modifier le fichier /boot/grub/grub.cfg, qui est généré par la commande juste au dessus

Dans le dernier cas voici les étapes pour parvenir à vos fins :

  • au début du fichier vous devriez retrouvez ce bout de code, dans lequel default doit être égal à ${saved_entry} dans le else
### BEGIN /etc/grub.d/00_header ###
insmod part_gpt
insmod part_msdos
if [ -s $prefix/grubenv ]; then
  load_env
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${saved_entry}" <---- verifiez bien cette ligne
fi
  • à chaque option du menu de grub un peu plus bas, dans les sections ### BEGIN /etc/grub.d/10_linux ### et/ou ### BEGIN /etc/grub.d/30_os-prober ###, etc ... la ligne savedefault doit être la première ligne, voici un exemple avec Windows :
menuentry 'Windows 10 (sur /dev/sdax)' --class windows --class os $menuentry_id_option 'osprober-chain-UUID' {
	savedefault          <-------------- cette ligne la
	insmod part_msdos
	insmod ntfs
	set root='hd1,msdos4'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-ieee1275='ieee1275//disk@0,msdos4' --hint-bios=hd1,msdos4 --hint-efi=hd1,msdos4 --hint-baremetal=ahci1,msdos4  UUID
	else
	  search --no-floppy --fs-uuid --set=root UUID
	fi
	parttool ${root} hidden-
	drivemap -s (hd0) ${root}
	chainloader +1
}

Pensez à bien vérifier que la fonction savedefault est bien présente dans votre fichier.

Références :