I had a dream… Kpatch !
Bon, c’est vrai, je le reconnais, je m’emballe légèrement. 🙄
Enfin une solution prometteuse permettant d’appliquer les mises à jour de sécurité (et autres) du noyau à chaud, ce qui veut dire sans redémarrage du serveur.
Avant, il existait Ksplice, une solution propriètaire détenue par la société Oracle mais ça c’était avant !
Depuis quelques mois, RedHat et Suse se sont lancés dans la bataille pour chacun fournir leur solution alternative.
- Pour RedHat : kpatch
- Pour Suse : kgraft
Pour ma part, je n’ai pas eu l’occasion de « jouer » avec kgraft, si vous avez déjà côtoyé la bête, n’hésitez pas à partager votre retour d’expérience.
Comment ça fonctionne ?
Je vais faire très simple et très rapide :
kpatch permet de remplacer une fonction par une autre à l’aide d’un module noyau.
Pour la version longue et complexe, je vous invite à parcourir le GitHub de kpatch. Tout y est très bien expliqué ; les étapes, ce que kpatch peut et ne peut pas faire, etc… Il existe un schéma qui résume assez bien le fonctionnement de kpatch :
Kpatch et Debian, pas si simple…
Sur le site de kpatch, il y a une procédure d’installation pour Fedora 20 et Ubuntu 14.04 mais hélas, rien pour Debian 7.5.
En voyant de la documentation pour Ubuntu je me suis dit :
Si ça fonctionne sur une Ubuntu, ça fonctionnera forcément sur une Debian !
Ben oui voyons, Ubuntu n’est « que » basée sur la version unstable de Debian.
Pardi, c’est parti !
Diantre, mais parfois qu’est-ce que je peux être naïf (pour rester poli) !
Debian et kpatch, un petit résumé
Dans un premier temps, j’ai essayé de faire fonctionner kpatch sur une Debian 7.5 (alias Wheezy) mais ce fut laborieux. Par laborieux je veux dire que Wheezy est trop ancienne pour que kpatch puisse fonctionner « out of the box ».
kpatch a des pré-requis que Wheezy n’est pas apte à fournir par défaut :
- gcc 4.8.0
- parce que gcc doit compiler simultanément kpatch avec les options -ffunction-sections et -pg
- noyau 3.7
- parce que kpatch utilise l’implémentation de la hashtable, apparue uniquement depuis la version 3.7
En plus de ces versions à respecter, kpatch nécessite que certaines options du noyau soient compilées.
C’est pour les raisons sus-citées, que j’ai décidé de continuer avec une Debian 8.0 (alias Jessie).
En faisant ce choix, je suis passé outre les questions de pinning et de backports. Reste à compiler un noyau avec les bonnes options mais ceci est un moindre mal !
Un noyau « Made in Debian »
Dans la procédure ci-dessous, j’ai essayé de rester le plus cohérent possible avec la méthodologie Debian.
Récupération des sources du noyau actuel depuis les dépôts Debian.
# aptitude install linux-source-$(uname -r | sed "s/-.*//g") build-essential fakeroot # cd /usr/src && tar xf linux-source-$(uname -r | sed "s/-.*//g").tar.xz && ln -s linux-source-$(uname -r | sed "s/-.*//g") linux && cd linux
Copie du fichier de configuration actuel dans les sources fraîchement téléchargées.
# cp /boot/config-$(uname -r | sed "s/-.*//g") .config
Activation des options nécessaires pour le noyau.
# for OPTION in CONFIG_KALLSYMS_ALL CONFIG_FUNCTION_TRACER ; do sed -i "s/# $OPTION is not set/$OPTION=y/g" .config ; done
Modification du SUBLEVEL, compilation du noyau et création des paquets Debian.
# sed -i "s/^SUBLEVEL.*/SUBLEVEL =/" Makefile # make -j`getconf _NPROCESSORS_CONF` deb-pkg KDEB_PKGVERSION=3.14.15-2
Installation des nouveaux paquets et redémarrage du serveur.
# cd .. && dpkg -i linux-*.deb && reboot
Le noyau actuel de Jessie est en version 3.14, sans la modification du SUBLEVEL, la version passera en 3.14.7 (une histoire de SUBLEVEL dans le Makefile).
Kpatch, l’installation
Le plus dur a été fait, kpatch n’a pas encore de paquet mais son installation s’effectue très facilement avec l’aide de git. Certains des paquets ci-dessous sont certainement déjà présents si vous venez de compiler votre noyau.
# aptitude install libelf-dev dpkg-dev make gcc ccache git && apt-get build-dep linux
Afin de gagner du temps dans les futures compilations « kpatchienne », il est nécessaire d’augmenter la taille du cache de ccache.
# ccache --max-size=5G
Récupération des sources et installation de kpatch.
# cd /usr/src && git clone https://github.com/dynup/kpatch.git && cd kpatch && make && make install
Depuis aujourd’hui, il n’est plus nécessaire de modifier le fichier kpatch-build pour que ce dernier soit fonctionnel avec Debian (cf. PR #285) 😎
À vos marques, patchez !!
Dans la documentation officielle, le patch consiste à modifier l’affichage de /proc/meminfo. Et bien nous, nous allons modifier l’affichage de /proc/version, on est des foufous !! Voici le patch en question :
--- a/fs/proc/version.c 2014-07-02 04:24:52.451131328 +0200 +++ b/fs/proc/version.c 2014-07-02 04:32:29.427126922 +0200 @@ -8,6 +8,7 @@ static int version_proc_show(struct seq_file *m, void *v) { seq_printf(m, linux_proc_banner, + "I love Katy Perry", utsname()->sysname, utsname()->release, utsname()->version);
Un petit avertissement avant d’aller plus loin :
L’étape suivante sera consommatrice en espace disque. kpatch-build créé un répertoire de travail dans $HOME/.kpatch, il est donc nécessaire d’avoir au moins 20Go d’espace disque disponible sur cette partition. Si vous êtes dans le même cas que moi et que votre partition ne contient pas assez d’espace, alors vous pouvez créer un lien symbolique de .kpatch vers le répertoire de votre choix.
Le patch est prêt, il ne reste plus qu’à créer un module noyau avec kpatch-build (soyez patient, cette étape nécessite plusieurs minutes).
# kpatch-build -c /boot/config-$(uname -r) -v /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /usr/src/version-katy-perry.patch
Une fois la compilation terminée, un fichier kpatch-version-katy-perry.ko doit apparaître à l’endroit ou la commande kpatch-build a été lancée. Quelques informations sur le module :
# kpatch info kpatch-version-katy-perry.ko
Résultat :
Patch information for kpatch-version-katy-perry.ko: filename: /root/kpatch-version-katy-perry.ko license: GPL depends: kpatch vermagic: 3.14 SMP mod_unload modversions parm: replace:replace all previously loaded patch modules (bool)
Le moment que vous attendez depuis que cet inter »minable » billet a débuté, le chargement du module !
# kpatch load kpatch-version-katy-perry.ko
Résultat :
loading core module: /usr/local/lib/modules/3.14/extra/kpatch/kpatch.ko loading patch module: kpatch-version-katy-perry.ko
Et dans le fichier /var/log/kern.log, que se passe t’il ?
[ 2097.493524] kpatch: tainting kernel with TAINT_USER [ 2097.493527] kpatch: loaded patch module 'kpatch_version_katy_perry'
On peut vérifier que le module soit bien chargé.
# kpatch list
Résultat :
Loaded patch modules: kpatch_version_katy_perry Installed patch modules:
Ça se présente bien pour le moment.
Verdict, houlala, j’ai peur !
# cat /proc/version
Résultat :
I love Katy Perry version Linux (root@sd-56804) (gcc version 4.9.0 (Debian 4.9.0-7) ) 3.14
Alors oui, c’est très très moche, c’est à ne surtout pas faire mais c’était pour l’exemple. Il suffit de désactiver le module pour que tout redevienne comme avant.
# kpatch unload kpatch_version_katy_perry
Résultat :
disabling patch module: kpatch_version_katy_perry unloading patch module: kpatch_version_katy_perry
Vérification que le retour arrière a bien été effectif.
# cat /proc/version
Résultat :
Linux version 3.14 (root@sd-56804) (gcc version 4.9.0 (Debian 4.9.0-7) ) #6 SMP Tue Jul 1 19:43:36 CEST 2014
L’exemple était très simple, mais libre à vous de patcher des fonctions bien plus complexes !
Conclusion
Ce fut un long billet, avec tout plein d’informations et pas des plus simples, j’espère que tout a fonctionné sans trop de soucis sur votre serveur. Le projet n’est pas encore complétement stable, libre à vous de l’utiliser en production.
Il va de soit que tous les outils de compilation installés ne doivent pas se trouver sur un serveur de production, compilez vos modules sur un serveur dédié à cet effet et déployez-les sur vos serveurs de production !
Le prochain billet lié à kpatch sera certainement sur l’installation de ce dernier sur une Debian Wheezy, ça risque d’être drôle ! 😈
Liens
- Projet kpatch sur GitHub
- Projet kgraft
- Les PR que j’ai effectué sur le projet (mode PUB)
- Les issues que j’ai ouvert sur le projet (mode PUB)
Gaëtan Trellu (goldyfruit)
Derniers articles parGaëtan Trellu (goldyfruit) (voir tous)
- Qinling, let’s the journey begin! - 23 mai 2019
- systemd-networkd, l’âge de la maturité ? - 13 mars 2018
- Hyper-V, Nova, VxLAN et Open vSwitch, enfin une belle histoire ! - 31 décembre 2017
Kpatch, une alternative libre pour patcher son noyau à chaud ! par Gaëtan Trellu (goldyfruit) est sous Licence Creative Commons Internationale Attribution 4.0.