Sommaire

Mon serveur Debian se met à jour tout seul, et c'est tant mieux en ce moment

Hier, j’ai vu qu’OpenAI a découvert 948 failles permettant à un utilisateur sans droits de devenir root, chacune avec un exploit fonctionnel. Ce matin, je vois qu’Ars Technica raconte une autre faille, vieille d’une dizaine d’années, qui permet de se connecter en SSH à certains systèmes sans mot de passe.

Sur deux jours seulement.

Je ne sais pas vous, mais je ne peux pas suivre ce rythme. Déjà avant, ça pouvait être compliqué de tout suivre. Alors quand on veut juste faire tourner un VPS ou un homelab, que ce n’est pas notre métier de surveiller les bulletins de sécurité, et qu’en plus les agents IA sont lâchés dans la nature, c’est perdu d’avance.

Dans mon cas, j’ai arrêté d’essayer il y a plusieurs mois. Mes machines sous Debian appliquent elles-mêmes leurs correctifs de sécurité grâce à un outil qui s’appelle unattended-upgrades. Je vous raconte comment je l’ai configuré, et surtout ce qu’il fait et ne fait pas.

Une faille corrigée ne protège que ceux qui mettent à jour

Ce qui m’a frappé dans l’article d’OpenAI, ce n’est pas tant le nombre. C’est une phrase vers la fin : pour eux, un simple compte utilisateur sur un système qui n’a pas reçu les derniers correctifs doit être considéré comme fonctionnellement équivalent à un accès root.

Il faut bien lire la nuance. Ces 948 failles sont locales : il faut déjà avoir un pied sur la machine pour les exploiter. Ce n’est pas « n’importe qui sur Internet peut prendre la main sur votre serveur ». Mais le jour où un service exposé se fait compromettre, la marche suivante vers root est beaucoup plus basse qu’on ne l’imagine.

La bonne nouvelle, c’est que ces failles se corrigent. Pendant les dix jours de leur analyse, plus d’une centaine étaient déjà corrigées, ou en passe de l’être par d’autres contributeurs. Sauf qu’un correctif publié ne vous sert à rien tant qu’il n’est pas installé sur votre machine. Entre les deux, il y a vous, et votre rapidité à lancer un apt upgrade.

D’où l’idée de ne plus avoir à y penser du tout.

unattended-upgrades, c’est quoi ?

unattended-upgrades est un outil de Debian (et d’Ubuntu) qui installe automatiquement les mises à jour des paquets. Unattended veut dire « sans surveillance » : il tourne tout seul, tous les jours, sans qu’on ait besoin d’être là.

Dit autrement, c’est comme si quelqu’un se connectait chaque nuit à votre serveur pour faire apt update puis apt upgrade pour les paquets que vous avez choisis.

C’est ce dernier point qui compte. On ne lui dit pas « mets tout à jour », on lui dit quelles sources il a le droit d’appliquer. Et c’est là que se joue l’essentiel de la configuration.

Pour l’installer, rien de bien sorcier :

sudo apt install unattended-upgrades

Ce que j’ai choisi : la sécurité, et rien d’autre

Il y a deux familles de mises à jour sur un serveur Debian :

  • les mises à jour de sécurité, qui corrigent des failles ;
  • les autres : corrections de bugs, nouvelles versions de paquets, etc.

J’ai choisi de n’automatiser que les premières. L’idée est simple : un correctif de sécurité, je veux qu’il soit appliqué vite, et je ne vais de toute façon pas le relire avant. Le reste peut attendre que je m’en occupe, et c’est là qu’une mise à jour a le plus de chances de changer un comportement, de casser un service.

La configuration vit dans /etc/apt/apt.conf.d/50unattended-upgrades. Voici l’essentiel de la mienne :

Unattended-Upgrade::Origins-Pattern {
        "origin=Debian,codename=${distro_codename},label=Debian-Security";
        "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};

Unattended-Upgrade::Package-Blacklist {
};

Unattended-Upgrade::AutoFixInterruptedDpkg "true";

Le bloc Origins-Pattern, c’est la liste des sources autorisées. Ici, uniquement les dépôts de sécurité de Debian. ${distro_codename} est remplacé automatiquement par le nom de votre version de Debian, pas besoin de le changer à chaque montée de version.

Package-Blacklist permet d’exclure des paquets précis si un jour l’un d’eux pose problème. La mienne est vide. Et AutoFixInterruptedDpkg demande à l’outil de réparer une installation interrompue (une coupure de courant au mauvais moment, par exemple) plutôt que de rester bloqué.

Il faut ensuite activer l’exécution quotidienne, dans /etc/apt/apt.conf.d/20auto-upgrades :

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

La première ligne rafraîchit la liste des paquets chaque jour, la seconde lance unattended-upgrades chaque jour.

Et sur Ubuntu ?
Le principe est le même, mais le fichier par défaut est un peu différent et utilise un bloc Allowed-Origins. Sur Ubuntu, la configuration installée par défaut se limite en général déjà aux mises à jour de sécurité : jetez-y un œil avant de la modifier.

Le redémarrage, la partie qu’on oublie

Revenons aux 948 failles d’OpenAI. Elles sont dans le noyau Linux. Et un nouveau noyau, même installé, ne sert à rien tant que la machine n’a pas redémarré : c’est l’ancien qui continue de tourner.

Autrement dit, on peut avoir des mises à jour automatiques parfaitement configurées, voir les paquets s’installer chaque nuit, et rester exposé pendant des semaines parce que le serveur ne redémarre jamais.

unattended-upgrades sait gérer ça. J’ai ajouté ces trois lignes à la configuration :

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "01:50";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";

Le serveur redémarre uniquement si une mise à jour l’exige (un nouveau noyau, typiquement), et à 01:50, en pleine nuit. La dernière ligne est une petite sécurité : si quelqu’un est connecté à la machine à ce moment-là, il ne redémarre pas.

Évidemment, ça suppose que vos services redémarrent proprement avec la machine. Sur un serveur qui fait tourner quelque chose de critique 24h/24, c’est une décision à prendre en connaissance de cause. Pour un homelab ou un petit VPS perso, une minute d’indisponibilité en pleine nuit me semble largement acceptable.

D’ailleurs, attention à bien aligner vos différentes opérations nocturnes. Je donne un exemple : j’ai aussi des backups PBS qui tournent la nuit, j’ai donc plutôt envie d’espacer ces deux actions pour éviter un redémarrage en plein backup :)

Tester avant de laisser tourner

Avant de laisser l’outil vivre sa vie, il vaut mieux vérifier que la configuration est valide. Une erreur de syntaxe dans ces fichiers est vite arrivée.

sudo unattended-upgrade --dry-run --debug

Le --dry-run simule une exécution sans rien installer, et --debug affiche le détail : les sources prises en compte, les paquets qui seraient mis à jour. Si la commande se termine sans erreur, c’est bon signe.

Et quand on a plusieurs machines ?

Configurer tout ça à la main sur une machine, ça va. Sur quatre, ça devient pénible. Et le risque, c’est d’oublier la cinquième.

Comme le reste de mon homelab, je gère ça avec Ansible. J’ai écrit un petit rôle unattended_upgrades qui installe le paquet, dépose les deux fichiers de configuration, puis lance le --dry-run pour vérifier que tout est valide. Je l’applique ensuite aux VM concernées.

Le jour où j’ajoute une VM, une ligne dans un playbook suffit. Et le jour où je veux changer l’heure de redémarrage, je la change à un seul endroit.

Ce que ça ne fait pas

C’est le moment de nuancer, parce qu’unattended-upgrades n’est pas une baguette magique.

Il ne met pas à jour vos conteneurs. Il gère les paquets du système, pas les images Docker qui tournent dessus. Si votre service tourne dans un conteneur, c’est l’image qu’il faut mettre à jour, et ça se fait ailleurs. Petit clin d’œil à la faille SSH d’Ars Technica : elle touche notamment Alpine Linux, une distribution très utilisée comme base d’images Docker. Debian n’est pas concernée par celle-ci, mais vos conteneurs peuvent l’être.

Il ne s’occupe pas des autres mises à jour. C’est un choix de ma configuration : les corrections de bugs et nouvelles versions restent à faire de temps en temps. Moins urgent, mais pas à oublier pour autant. D’ailleurs, en ce moment je songe à changer, car vu que mon homelab n’est pas vital et que j’ai des backups, je me dis que ça pourrait m’enlever une charge mentale d’automatiser le reste.

Ce n’est pas une stratégie de sécurité à lui tout seul. C’est une couche parmi d’autres. Un pare-feu, un SSH bien configuré, fail2ban, etc. Tout ce que je raconte dans ce que je configure juste après l’installation de Proxmox reste valable. Les mises à jour automatiques réduisent le temps pendant lequel une faille connue reste ouverte chez vous. Elles n’empêchent personne de frapper à la porte. On parle de défense en profondeur.

Bref

Ça fait plusieurs mois que c’est en place sur mon homelab, et je n’ai remarqué aucun souci. Ce qui est, au fond, exactement ce qu’on attend de ce genre d’outil : qu’on l’oublie.

Je ne lis pas les bulletins de sécurité tous les matins, et je ne vais pas commencer maintenant que les IA trouvent des failles par centaines. J’en vois passer pendant ma veille, ou sur Reddit périodiquement. Mais en tout cas, je sais que les correctifs, eux, arrivent tout seuls sur mon homelab chaque nuit.

Si vous avez un VPS ou un petit serveur qui traîne quelque part, et que vous ne vous souvenez plus de la dernière fois que vous l’avez mis à jour, c’est peut-être le bon moment pour installer unattended-upgrades.