Utilisation d'un kernel Mainline sous Ubuntu

Salut à tous. Petite mise à jour après une longue absence pour vous parler de Kernel Linux dans sa version mainline, et de son installation sous Ubuntu quand vous utiliser SecureBoot (surement sans le savoir).

Introduction

Commençons par une simple question, pourquoi?

Plusieurs raison pour installer le kernel mainline:

  • Une version plus récente que le kernel fourni par Ubuntu est disponible, et celle-ci apporte des améliorations sur un ou plusieurs drivers dont vous avez besoin.
  • Vous développer un driver et avez besoin de la toute dernière version pour celui-ci.
  • Vous aimez vivre dangeureusement.

Personellement, ma nouvelle carte graphique, une Radeon RX5500 XT 8Go, basé sur l'architecture RDNA de AMD va bientôt arriver à la maison. Et coté driver, la dernier version 5.6 du kernel Linux apporte beaucoup d'amélioration. Voir sur le site Phoronix les pages Running The Linux 5.6 Kernel With AMD Radeon Graphics et Linux 5.6 Is The Most Exciting Kernel In Years.

Donc, j'anticipe un petit peu l'installation de cette version du kernel Linux sous Ubuntu 19.10.

Installation

L'installation du kernel mainline sur Ubuntu 19.10 est relativement simple. Il suffit de télécharger les packages .deb sur le site officiel des kernel Mainline pour Ubuntu.

Aller sur la page MainlineBuilds et naviguer vers le répertoire du dernier kernel disponible ici (5.6.2 à l'heure d'écrire cette petite page).

Puis télécharger tous les fichiers .deb nécessaire à votre architecture et vos besoins (kernel normal vs. lowlatency) ainsi que les fichiers CHECKSUMS. La liste si dessous pour mon cas:

CHECKSUMS
CHECKSUMS.gpg
linux-headers-5.6.2-050602_5.6.2-050602.202004020822_all.deb
linux-headers-5.6.2-050602-lowlatency_5.6.2-050602.202004020822_amd64.deb
linux-image-unsigned-5.6.2-050602-lowlatency_5.6.2-050602.202004020822_amd64.deb
linux-modules-5.6.2-050602-lowlatency_5.6.2-050602.202004020822_amd64.deb

Après téléchargement, verifiez les signatures des fichiers puis installez les avec la commande suivante:

bureau:~/Téléchargements$ gpg --recv-key "60AA7B6F30434AE68E569963E50C6A0917C622B0"
...

bureau:~/Téléchargements$ gpg --verify CHECKSUMS.gpg CHECKSUMS
gpg: Signature faite le jeu. 02 avril 2020 16:31:29 CEST
gpg:                avec la clef RSA E50C6A0917C622B0
gpg: Bonne signature de « Kernel PPA <kernel-ppa@canonical.com> » [inconnu]
gpg: Attention : cette clef n'est pas certifiée avec une signature de confiance.
gpg:          Rien n'indique que la signature appartient à son propriétaire.
Empreinte de clef principale : 60AA 7B6F 3043 4AE6 8E56  9963 E50C 6A09 17C6 22B0

bureau:~/Téléchargements$ sha256sum -c --ignore-missing CHECKSUMS
linux-headers-5.6.2-050602_5.6.2-050602.202004020822_all.deb: Réussi
linux-headers-5.6.2-050602-lowlatency_5.6.2-050602.202004020822_amd64.deb: Réussi
linux-image-unsigned-5.6.2-050602-lowlatency_5.6.2-050602.202004020822_amd64.deb: Réussi
linux-modules-5.6.2-050602-lowlatency_5.6.2-050602.202004020822_amd64.deb: Réussi
sha256sum: Attention : 28 lignes ne sont pas correctement formatées

Si tout est OK, et seulement dans ce cas, alors vous pouvez installer:

bureau:~/Téléchargements$ sudo dpkg -i linux-*-5.6.2-*.deb

Et voilà, c'est installé.

Un petit conseil, avant de redémarrer votre ordinateur, assurez-vous que le menu de démarrage Grub est bien affiché au boot. Vérifiez que vous avez bien cette configuration dans le fichier /etc/default/grub:

GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=3

Si ce n'étais pas le cas, modifiez le ficher et re-générez la configuration de Grub avec la commande suivante:

bureau:~$ sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Sourcing file `/etc/default/grub.d/kdump-tools.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.6.2-050602-lowlatency
Found initrd image: /boot/initrd.img-5.6.2-050602-lowlatency
Found linux image: /boot/vmlinuz-5.3.0-46-generic
Found initrd image: /boot/initrd.img-5.3.0-46-generic
Found linux image: /boot/vmlinuz-5.3.0-45-generic
Found initrd image: /boot/initrd.img-5.3.0-45-generic
Adding boot menu entry for EFI firmware configuration
done

Maintenant, vous pouvez rebooter.

En cas de soucis, par exemple une erreur de chargement du kernel 5.6, selectionnez votre précédent kernel, Ubuntu, with Linux 5.3.0-46-generic dans le sous-menu Advanced options for Ubuntu et démarrez normalement.

Si votre nouveau kernel a bien démarrer, vous avez terminer. Enjoy! Sinon, passez au chapitre suivant.

SecureBoot

Si vous lisez ce chapitre, c'est que tout ne s'est pas bien passé et que vous avez surement été insulté par Grub sous prétexte que le fichier vmlinuz-5.6.2-050602-lowlatency has invalid signature.

Rassurez-vous, il y a une solution que j'ai trouvé sur le blog ubuntu. Pour faire court, j'ai simplement suivi les étapes suivantes indiqué sur cette page (le chapitre Certificates in shim):

  1. Création d'un fichier de configuration pour OpenSSL. (Assurez-vous de bien avoir extendedKeyUsage avec la bonne valeur dedans.)
  2. Création des clés publique et privée, MOK.der & MOK.priv, avec OpenSSL.
  3. Création de la clé publique MOK.pem pour l'outil sbsign.
  4. Signature du kernel.
  5. Enrollement de la clé MOK.der dans shim.

Voici le fichier de configuration OpenSSL utilisé, MOK.cnf:

# This definition stops the following lines choking if HOME isn't
# defined.
HOME                    = .
RANDFILE                = $ENV::HOME/.rnd
[ req ]
distinguished_name      = req_distinguished_name
x509_extensions         = v3
string_mask             = utf8only
prompt                  = no

[ req_distinguished_name ]
countryName             = FR
stateOrProvinceName     = Paris
localityName            = Paris
0.organizationName      = whatyouwant
commonName              = Secure Boot Signing
emailAddress            = example@example.com

[ v3 ]
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer
basicConstraints        = critical,CA:FALSE
extendedKeyUsage        = codeSigning,1.3.6.1.4.1.311.10.3.6,1.3.6.1.4.1.2312.16.1.2
nsComment               = "OpenSSL Generated Certificate"

Et la séquence de commandes shell exécutée:

bureau:~$ openssl req -config ./MOK.cnf \
    -new -x509 -newkey rsa:2048 \
    -nodes -days 36500 -outform DER \
    -keyout "MOK.priv" \
    -out "MOK.der"
...
bureau:~$ openssl x509 -in MOK.der -inform DER -outform PEM -out MOK.pem
bureau:~$ sudo sbsign --key MOK.priv --cert MOK.pem \
    --output /boot/vmlinuz-5.6.2-050602-lowlatency.signed \
    /boot/vmlinuz-5.6.2-050602-lowlatency
...
bureau:~$ sudo mokutil --import MOK.der

Après appel de mokutil, vous devez rebooter pour finaliser l'enrollement de votre clé de signature dans shim qui est le module UEFI chargé avant Grub.

Lors du reboot, un écran bleu (non pas le Blue Screen of Death de Windows) apparait vous permettant de finalizer l'ajout de votre clé. Suivez les étapes à l'écran.

Ensuite, vous arrivez dans Grub. Appuyez sur Echap pour arrêter le décompte. Puis tapez la touche e pour éditer la première entrée.

Vers les dernières lignes, ajoutez .signed à la ligne commençant par linux.

Enfin, appuyez sur F10 ou Ctrl+x pour démarrer avec ce kernel signé.

Et voilà, normalement vous avez démarré sur votre nouveau kernel Mainline Linux 5.6.

Maintenant, remplacez le kernel non signé par la version que vous avez vous-même signé:

bureau:~$ sudo mv /boot/vmlinuz-5.6.2-050602-lowlatency{.signed,}

C'est fini.

Garder cette clé, elle vous permettra de signer les prochains kernels Mainline que vous installerez.

Signature automatique des prochains kernel

Suite à ces manipulations, j'ai ajouté un petit script dans le répertoire /etc/kernel/postinst.d/. Ce script auto-sign-kernel va permettre de signer automatiquement tous les kernels NON-signé que vous installerez comme précedement:

#!/bin/sh -e

KEY=/root/moksign/MOK.priv
CRT=/root/moksign/MOK.pem

version="$1"

# passing the kernel version is required
if [ -z "${version}" ]; then
    echo >&2 "W: auto-sign: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number"
    exit 2
fi

# sbsigntool package is mandatory

command -v sbverify >/dev/null 2>&1 || exit 0
command -v sbsign >/dev/null 2>&1 || exit 0

# check if kernel is already signed
name="/boot/vmlinuz-$version"
check=`sbverify --list $name 2>&1`

if [ "$check" == "No signature table present" ]; then

    # not signed, so sign it with registered MOK key

    echo "Signing kernel $name using personnal MOK key ..."
    sbsign --key $KEY --cert $CRT --output $name.signed $name
    mv ${name}{.signed,}
    echo "Done."

else

    echo "Kernel already signed, no need to sign it."

fi

Voilà, c'est terminé. Si tout se passe bien, quand vous installerez le prochain kernel Mainline, il sera automatiquement signé par ce script avec les clés publique et privée indiquées par les variables KEY & CRT, à modifier selon votre convenance.

Bonne journée.

Commentaires

links

social