Aller au contenu
Administration Linux medium

Ubuntu Server 26.04 LTS : ce qui change pour un serveur

44 min de lecture

Ubuntu Server 26.04 LTS « Resolute Raccoon » est sortie le 23 avril 2026. Pour un serveur, le changement le plus important n'est pas technique, il est contractuel : la maintenance de sécurité gratuite ne couvre que le dépôt main, environ 2 300 paquets. Or docker.io, redis, fail2ban et prometheus sont dans universe, hors garantie dès le premier jour. Viennent ensuite trois ruptures qui cassent des scripts : les coreutils réécrits en Rust, sudo remplacé par sudo-rs, et apt-key purement supprimé. Ce guide chiffre le trou de couverture, liste ce qui casse, et démonte deux pièges célèbres que le terrain contredit.

  • Mesurer la couverture de sécurité réelle de votre serveur avec pro security-status, et voir ce que universe laisse dehors.
  • Identifier ce que les coreutils en Rust changent vraiment, et revenir à GNU avec la commande qui fonctionne.
  • Reconnaître les ruptures qui cassent les vieux tutoriels : apt-key, cgroup v1, /tmp, le prompt de sudo.
  • Comprendre pourquoi la montée de 24.04 vers 26.04 n'est pas proposée aujourd'hui, et quand elle le sera.
  • Neutraliser l'appel réseau vers Canonical déclenché à chaque connexion SSH.
  • Trancher entre Ubuntu Server et Debian sur des faits vérifiables, pas sur des habitudes.

Avant de parler des ruptures, il faut savoir combien de temps la version tiendra. C'est là que se cache le premier contresens : la quasi-totalité des articles en ligne annonce 10 ans, parfois 12. C'est périmé.

Canonical découpe désormais la vie d'une LTS en trois tranches : 5 ans de maintenance standard, puis 5 ans d'ESM (Expanded Security Maintenance, la couverture étendue vendue avec Ubuntu Pro), puis 5 ans de Legacy add-on, soit 15 ans au total. Retenez surtout que seule la première tranche est gratuite, et qu'elle ne s'applique pas à tous vos paquets, ce que la section suivante démontre.

Ce tableau se lit comme une liste de choses à retester avant migration. Chaque saut de version majeure est un risque de régression de configuration, en particulier sur les serveurs web et les bases de données.

ComposantUbuntu 24.04 LTSUbuntu 26.04 LTS
Noyau Linuxsérie 6.8série 7.0
systemd255259
APT2.7.143.2
OpenSSH9.6p110.2p1
sudosudo 1.9.15sudo-rs 0.2.13
coreutilsGNU 9.4uutils 0.8.0
PostgreSQL1618
Python3.123.14
PHP8.38.5
nginx1.241.28.3

Deux valeurs de ce tableau justifient à elles seules une relecture de vos scripts d'exploitation : sudo-rs et uutils. Ce sont des réécritures complètes en Rust, pas des montées de version. Le noyau 7.0 est également celui qui provoque la régression PostgreSQL évoquée plus bas.

Le trou de sécurité universe, dès le premier jour

Section intitulée « Le trou de sécurité universe, dès le premier jour »

Voici le cœur du sujet, et le point que presque personne n'écrit. Beaucoup d'administrateurs croient qu'une Ubuntu LTS leur offre cinq ans de correctifs de sécurité sur tout ce qu'ils installent. C'est faux, et la nuance change tout sur un serveur de production.

L'archive Ubuntu est découpée en composants. Le composant main rassemble environ 2 300 paquets que Canonical s'engage à maintenir pendant cinq ans, gratuitement. Le composant universe en compte plus de 36 000, maintenus par la communauté et couverts en « best effort », c'est-à-dire sans aucun engagement.

Le contresens le plus répandu est de croire qu'ESM prend le relais après cinq ans. C'est faux pour universe : c'est ESM-apps qui le couvre, et ESM-apps s'applique dès la première année. Autrement dit, un serveur qui utilise universe a besoin d'Ubuntu Pro immédiatement, pas dans cinq ans.

Tranchemain (~2 300 paquets)universe (plus de 36 000)
Années 1 à 5maintenance standard, gratuiteESM-apps, donc Ubuntu Pro requis dès le jour 1
Années 6 à 10ESM-infra (Pro)ESM-apps (Pro)
Années 11 à 15Legacy add-onLegacy add-on

Reste à savoir où vivent les paquets que vous installez vraiment. La vérification est directe, et le résultat est brutal : docker.io, redis, fail2ban et prometheus sont tous dans universe. La nuance mérite d'être notée, car elle est contre-intuitive : le runtime containerd est dans main, donc couvert, alors que le paquet docker.io qui le pilote ne l'est pas.

Sur la 26.04 du lab, apt-cache policy donne le composant réel de chaque paquet :

docker.io -> http://archive.ubuntu.com/ubuntu resolute-updates/universe
certbot -> http://archive.ubuntu.com/ubuntu resolute/universe
nginx -> http://archive.ubuntu.com/ubuntu resolute-updates/main
openssh-server -> http://archive.ubuntu.com/ubuntu resolute-updates/main

Traduisez cela en langage d'exploitation : une stack Docker + Redis + fail2ban sur Ubuntu LTS n'est pas couverte par la maintenance de sécurité gratuite. Votre serveur web l'est, votre serveur SSH l'est, mais le paquet docker.io ne l'est pas.

C'est aussi la raison économique de deux habitudes que tout le monde suit sans se demander pourquoi : Docker publie son propre dépôt APT, et l'EFF pousse le snap certbot. Ces éditeurs ne veulent pas dépendre d'un paquet distribué en « best effort ». En passant par leur dépôt officiel, vous récupérez un engagement de mise à jour que le paquet Ubuntu ne vous donne pas. Le mécanisme des dépôts tiers est détaillé dans le guide administrer les paquets avec APT.

Le client Ubuntu Pro est préinstallé sur l'image serveur, et la commande pro security-status affiche le calcul en toutes lettres. Voici la sortie de la 26.04 du lab, après avoir installé docker.io :

Fenêtre de terminal
pro security-status
687 packages installed:
684 packages from Ubuntu Main/Restricted repository
3 packages from Ubuntu Universe/Multiverse repository
This machine is receiving security patching for Ubuntu Main/Restricted
repository until 2031.
This machine is NOT attached to an Ubuntu Pro subscription.
Ubuntu Pro with 'esm-infra' enabled provides security updates for
Main/Restricted packages until 2036.
Ubuntu Pro with 'esm-apps' enabled provides security updates for
Universe/Multiverse packages until 2036.

Lisez la ligne du milieu, c'est là qu'est le trou : la machine reçoit des correctifs pour main et restricted jusqu'en 2031. Pour les 3 paquets venus de universe (Docker et ses dépendances), aucune date, aucun engagement. La ligne esm-apps n'est pas une offre pour plus tard, c'est la seule couverture existante de ces paquets, et elle demande une souscription.

Le piège de l'image cloud : universe déclaré mais absent

Section intitulée « Le piège de l'image cloud : universe déclaré mais absent »

Un détail du lab explique enfin le fameux « Unable to locate package » sur une machine neuve. Sur l'image cloud fraîchement démarrée, universe est bien déclaré dans /etc/apt/sources.list.d/ubuntu.sources (Components: main universe restricted multiverse), mais son index n'est pas livré avec l'image. Résultat, avant tout apt update :

Fenêtre de terminal
apt-cache policy docker.io
docker.io:
Installed: (none)
Candidate: (none)
Version table:

Le paquet semble ne pas exister alors que le dépôt est actif. Il ne manque qu'un sudo apt update, qui va télécharger l'index de universe : apt-cache policy docker.io répond alors correctement avec la version 29.1.3. La leçon d'exploitation est simple : sur une image cloud, apt update n'est pas une politesse, c'est ce qui rend la moitié de l'archive visible.

C'est le changement le plus casse-gueule de 26.04, et le plus mal documenté. Les coreutils sont les commandes de base que tout script utilise sans y penser : ls, cat, sort, wc, stat, date. En 26.04, elles ne sont plus celles de GNU mais celles du projet uutils, une réimplémentation en Rust.

Partout, y compris dans les notes officielles, on lit que « cp, mv et rm restent GNU ». La mesure sur la machine réelle donne une liste un peu plus longue, et surtout plus surprenante. Sur la 26.04 du lab, contre la 24.04 témoin :

26.04 24.04 (témoin)
ls ls (uutils coreutils) 0.8.0 ls ls (GNU coreutils) 9.4
cat cat (uutils coreutils) 0.8.0 cat cat (GNU coreutils) 9.4
sort sort (uutils coreutils) 0.8.0 sort sort (GNU coreutils) 9.4
cp cp (GNU coreutils) 9.7 cp cp (GNU coreutils) 9.4
mv mv (GNU coreutils) 9.7 mv mv (GNU coreutils) 9.4
rm rm (GNU coreutils) 9.7 rm rm (GNU coreutils) 9.4
df df (GNU coreutils) 9.7 df df (GNU coreutils) 9.4

Le décompte complet, mesuré : cinq commandes seulement restent GNU, à savoir cp, mv, rm, df et true. Tout le reste du userland est uutils 0.8.0. Et l'asymétrie, vérifiée deux fois (cible du lien symbolique et --version du binaire), vaut d'être connue : /usr/bin/true est GNU, alors que /usr/bin/false est uutils.

Si vous voulez refaire cette classification vous-même, ne la faites pas au shell. Taper true --version ne prouve rien du tout : true, false, printf, echo et test sont des builtins du shell, la commande n'atteint jamais /usr/bin/. Le lab l'a rencontré en direct, avec cette sortie qui ne veut rien dire :

printf bash: line 1: printf: --: invalid option

La seule méthode fiable est d'interroger le binaire par son chemin absolu :

Fenêtre de terminal
/usr/bin/true --version | head -1 # true (GNU coreutils) 9.7
/usr/bin/false --version | head -1 # false (uutils coreutils) 0.8.0

Toute classification uutils/GNU publiée sans cette précaution est fausse pour ces cinq commandes. C'est probablement pour cela que les listes qui circulent divergent.

Voici la bonne nouvelle, et elle est rarement dite : le paquet gnu-coreutils 9.7 est présent par défaut sur une 26.04 vierge. Il fournit /usr/bin/gnuls, gnusort, gnuwc, gnucat et leurs semblables. Dépanner un script cassé ne demande donc aucune installation :

Fenêtre de terminal
gnuls --version | head -1
ls (GNU coreutils) 9.7

Si un script d'exploitation dépend d'un comportement GNU précis, remplacer ls par gnuls dans ce script est la correction la plus courte, et elle ne touche pas au reste du système. C'est le contournement chirurgical, à préférer à une bascule globale.

Revenir à GNU : la commande officielle ne fonctionne pas

Section intitulée « Revenir à GNU : la commande officielle ne fonctionne pas »

Pour basculer tout le système vers GNU, la documentation donne apt install coreutils-from-gnu --allow-remove-essential. Cette commande échoue. Le lab s'y est cassé les dents, et voici pourquoi.

Les deux paquets coreutils-from-gnu et coreutils-from-uutils fournissent tous les deux le paquet virtuel coreutils-from et entrent tous les deux en conflit avec lui. Le solveur d'APT n'en déduit pas qu'il faut retirer l'un pour poser l'autre, et s'arrête :

E: Unable to satisfy dependencies. Reached two conflicting assignments:
1. coreutils-from-gnu:amd64=0.0.0~ubuntu25 is selected for install
2. coreutils-from-gnu:amd64=0.0.0~ubuntu25 is not selected for install because:
1. coreutils-from-uutils:amd64 is selected for install
2. coreutils-from-uutils:amd64 Conflicts coreutils-from

Ce n'est pas une régression du nouveau solveur d'APT 3 : l'échec est identique avec -o APT::Solver=internal. Ce n'est pas non plus un accident de lab : le bug est ouvert chez Canonical sous le numéro 2146618, avec exactement le même message. La seule commande qui fonctionne demande explicitement le retrait de l'autre paquet dans la même transaction :

Fenêtre de terminal
sudo apt install --allow-remove-essential coreutils-from-gnu coreutils-from-uutils-

Le suffixe - collé au nom d'un paquet signifie « retire-le dans la même transaction ». L'option --allow-remove-essential est nécessaire parce que le métapaquet coreutils est marqué Essential. Après quoi la vérification est sans appel, et le mécanisme est visible :

Fenêtre de terminal
ls --version | head -1 # ls (GNU coreutils) 9.7
ls -la /usr/bin/ls # /usr/bin/ls -> gnuls

Notez le mécanisme, il surprend : la bascule passe par des diversions dpkg, pas par update-alternatives. La manipulation est réversible en inversant les deux noms (coreutils-from-uutils coreutils-from-gnu-).

Les divergences réelles : 10 sur 93, et zéro sur les codes de retour

Section intitulée « Les divergences réelles : 10 sur 93, et zéro sur les codes de retour »

La question qui compte en production n'est pas « est-ce du Rust », c'est « qu'est-ce qui va casser ». Le lab a rejoué 93 sondes sur la même machine, avant et après bascule, donc à distribution, noyau et locale identiques. Résultat : 10 sorties divergentes, et 0 code de retour différent.

Ce zéro est la meilleure nouvelle du lot, et il mérite d'être dit aussi fort que les écarts : un set -e, un if, un && ne changeront pas de comportement. Vos scripts ne vont pas se mettre à échouer en masse.

Les autres écarts sont moins graves mais méritent d'être connus, surtout si vous filtrez des messages d'erreur :

Casuutils 0.8.0GNU 9.7
Fichier absentstat: cannot stat '/x': ... (os error 2)stat: cannot statx '/x': ...
Option inconnueerror: unexpected argument '--xyz' foundls: unrecognized option '--xyz'
base64 -d invalidebase64: error: invalid inputbase64: invalid input
pr -t -2remplissage espaces + tabulationremplissage tabulations

Le message d'option inconnue vient de la bibliothèque clap de Rust. Un script de supervision qui cherche grep "unrecognized option" ne trouve plus rien, et croit donc que tout va bien. Le remplissage de pr casse tout parsing en largeur fixe.

À l'inverse, et c'est une information utile, une longue liste de comportements ne diverge pas : le tri selon la locale, sort -h, sort -V, sort -k, head -c, wc sur entrée vide, date -d 'next friday', seq, tr, cut, du. Les cas les plus sensibles des scripts d'administration passent.

Une trouvaille du lab, faite en lisant dmesg pour un autre test. Le profil AppArmor who, en mode enforce, refuse au binaire uutils l'accès à son propre fichier de traduction. Le profil de confinement n'a pas suivi le passage à uutils :

apparmor="DENIED" operation="open" class="file" profile="who"
name="/usr/share/coreutils/locales/uucore/en-US.ftl" comm="who" requested_mask="r"

Le problème de fond est connu et suivi sous le bug 2123870 : plusieurs profils AppArmor sont incompatibles avec le nouveau schéma des coreutils. La commande who sort quand même en code 0 (elle se dégrade sans se plaindre), mais chaque appel écrit un refus dans le journal d'audit. Sur un serveur qui appelle who régulièrement, par exemple depuis un script de supervision des sessions, ces refus AppArmor polluent durablement les journaux et brouillent la lecture des vrais incidents de sécurité. C'est un bug de packaging, pas une décision.

Même histoire que les coreutils, sur un binaire encore plus sensible. La 26.04 livre sudo-rs 0.2.13, une réécriture en Rust, à la place du sudo historique de Todd Miller. Le binaire /usr/bin/sudo pointe désormais vers /usr/lib/cargo/bin/sudo.

Le prompt change, et ça casse les automatisations

Section intitulée « Le prompt change, et ça casse les automatisations »

Ce qui casse, ce n'est pas sudo lui-même, c'est le texte qu'il affiche. Comparaison directe entre les deux machines du lab :

26.04 (sudo-rs)24.04 (sudo 1.9.15)
Invite[sudo: authenticate] Password:[sudo] password for testadmin:
Mauvais mot de passesudo: Authentication failed, try again.Sorry, try again.
sudo -nsudo: interactive authentication is requiredsudo: a password is required

Le motif [sudo] password for que tout le monde attend n'apparaît plus nulle part. Toute automatisation Expect ou pexpect qui guette ce motif pour envoyer un mot de passe échoue. Ce sont typiquement de vieux scripts de déploiement, des jobs d'orchestration maison, ou des tests d'intégration. Ils ne remontent pas d'erreur claire, ils restent bloqués jusqu'au timeout.

La nuance que la doc rate : sudoreplay n'a pas disparu

Section intitulée « La nuance que la doc rate : sudoreplay n'a pas disparu »

La documentation annonce que sudo-rs n'a pas de journalisation d'entrées/sorties, et donc pas de sudoreplay, l'outil qui rejoue une session enregistrée. C'est vrai sous ce nom-là. Mais le lab montre que l'original survit, exactement comme les gnu* des coreutils : le paquet sudo 1.9.17p2 reste installé et fournit ses binaires suffixés .ws (pour sudo.ws, le projet d'origine) :

/usr/bin/sudo.ws sudo Sudo version 1.9.17p2
/usr/bin/sudoreplay.ws sudo sudoreplay.ws version 1.9.17p2
/usr/bin/cvtsudoers.ws sudo

Si votre conformité impose l'enregistrement des sessions privilégiées, vous n'êtes donc pas bloqué : sudoreplay.ws est là, et le retour complet au sudo historique passe par update-alternatives. Notez au passage que sudo-ldap est supprimé : une élévation de privilèges adossée à LDAP doit désormais passer par PAM.

Au-delà des deux réécritures Rust, 26.04 retire plusieurs choses sur lesquelles s'appuient des milliers de pages de documentation encore en ligne. Les repérer vous évitera de perdre une heure sur une commande qui n'existe plus.

C'est le plus fréquent. APT est en 3.2.0 et apt-key n'existe plus du tout. Ce n'est pas une dépréciation avec un avertissement, c'est une suppression :

$ apt-key add /dev/null
bash: line 1: apt-key: command not found
$ dpkg -S /usr/bin/apt-key
dpkg-query: no path found matching pattern /usr/bin/apt-key

Aucun paquet ne fournit le fichier. Sur 24.04 (APT 2.7.14), la commande existait encore. Conséquence directe : tout tutoriel qui ajoute un dépôt tiers avec curl ... | apt-key add - est mort sur 26.04, et c'est encore la méthode montrée par une majorité de billets de blog. La bonne pratique consiste à déposer la clé dans /etc/apt/keyrings/ et à la référencer avec Signed-By:, comme expliqué dans le guide administrer les paquets avec APT.

En échange, APT 3.x apporte un historique des transactions qui manquait cruellement : apt history-list, history-info, history-undo, history-rollback, ainsi que apt modernize-sources pour convertir les sources au format deb822.

Le support de cgroup v1 a été retiré de systemd en amont, à la version 258, et le systemd 259 livré par la 26.04 n'en a donc plus. Sur la 26.04, /sys/fs/cgroup est exclusivement en cgroup2fs, et aucune hiérarchie v1 n'existe. Une nuance importante, pour ne pas répéter une erreur qui circule : c'est systemd qui a abandonné cgroup v1, pas le noyau. Le fichier /proc/filesystems liste toujours cgroup. Écrire « le noyau ne supporte plus cgroup v1 » serait donc faux. En pratique, un vieux runtime de conteneurs ou un agent de supervision qui lit /sys/fs/cgroup/memory/... ne trouvera plus rien. Signalons aussi que 26.04 est la dernière version à prendre en charge les scripts SysV : c'est votre dernière fenêtre pour les convertir en unités systemd.

Autre changement de comportement direct, aligné sur Debian 13 : /tmp est désormais un tmpfs, donc en mémoire vive, donc vidé à chaque redémarrage. Sur la 26.04 du lab, findmnt /tmp le confirme, et un fichier témoin déposé avant un vrai reboot avait bien disparu au retour :

TARGET SOURCE FSTYPE OPTIONS
/tmp tmpfs tmpfs rw,nosuid,nodev,nr_inodes=1048576,inode64,usrquota

Sur la 24.04 témoin, /tmp n'est pas un point de montage : il est sur le disque, et il persiste. Tout job qui laisse un état dans /tmp entre deux exécutions, ou qui y écrit un gros dump, doit être revu. Le sujet est traité en détail, avec les moyens d'agrandir ou de désactiver ce tmpfs, dans le guide Debian 13 Trixie, où le changement est identique.

Deux substitutions plus discrètes, mais qui déroutent au moment du diagnostic. La synchronisation de l'heure passe de systemd-timesyncd à chrony 4.8, mais uniquement sur les nouvelles installations : une 24.04 migrée conservera systemd-timesyncd. Sur l'image neuve du lab, chrony est actif et activé, tandis que systemd-timesyncd est not-found, le paquet n'est même pas installé. Chercher l'état de l'horloge avec systemctl status systemd-timesyncd ne donnera donc rien, il faut passer par chronyc tracking. Enfin, Dracut remplace initramfs-tools pour la génération de l'initrd, l'image de démarrage minimale chargée avant le système de fichiers racine. Vos scripts de hook initramfs-tools maison ne seront pas repris automatiquement.

Monter une 24.04 en 26.04 : pas encore, et c'est normal

Section intitulée « Monter une 24.04 en 26.04 : pas encore, et c'est normal »

Beaucoup d'équipes prévoient la migration de leur parc 24.04 dès la sortie de la 26.04. Le lab a posé la question directement à la machine, et la réponse surprend.

Sur la 24.04 témoin du lab, avec la configuration par défaut (Prompt=lts dans /etc/update-manager/release-upgrades) :

Fenêtre de terminal
do-release-upgrade -c
Checking for a new Ubuntu release
There is no development version of an LTS available.
To upgrade to the latest non-LTS development release
set Prompt=normal in /etc/update-manager/release-upgrades.
[code de retour réel : 1]

La 26.04 n'est pas proposée. La raison est une règle de Canonical, pas un bug : le passage LTS vers LTS n'est ouvert qu'après le premier point release, c'est-à-dire la 26.04.1. Le but est de laisser trois mois de correctifs s'accumuler avant d'envoyer un parc entier dessus.

Les deux autres chemins ont été capturés, et l'un des deux est un piège :

  • Avec Prompt=normal, la machine propose New release '25.10' available. Ce n'est pas la 26.04, c'est une version intermédiaire non-LTS, supportée neuf mois. Basculer un serveur là-dessus pour « avoir une version récente » est une erreur d'exploitation.
  • Avec do-release-upgrade -d, la 26.04 est bien proposée (New release '26.04 LTS' available.), mais -d signifie mode développement. C'est utile pour tester sur une machine jetable, jamais en production.

Le chemin est LTS vers LTS suivante, sans saut de version : une 22.04 doit passer par la 24.04 avant d'espérer la 26.04. En attendant l'ouverture officielle, trois prérequis se préparent aujourd'hui.

  1. Mettre le système complètement à jour, y compris les phased updates. Ces mises à jour déployées progressivement par lots sont invisibles d'un apt upgrade classique, et leur absence fait échouer la vérification préalable.

    Fenêtre de terminal
    sudo apt update
    sudo apt dist-upgrade -o APT::Get::Always-Include-Phased-Updates=true
  2. Redémarrer si le système le demande. Un noyau en attente d'activation bloque l'opération.

    Fenêtre de terminal
    ls /run/reboot-required && sudo reboot
  3. Inventorier les PPA et dépôts tiers. Ils sont désactivés pendant la montée de version, et Canonical les désigne comme la première cause d'échec. Sachez lesquels vous devrez réactiver, et sous quelle forme, avant de commencer.

    Fenêtre de terminal
    grep -rl "^Types:\|^deb " /etc/apt/sources.list.d/

Voici un point d'audit que peu d'administrateurs connaissent, et que le lab a prouvé au lieu de le supposer. À chaque connexion, 13 scripts de /etc/update-motd.d/ sont exécutés en root par pam_motd pour composer le message d'accueil. L'un d'eux, 50-motd-news, est actif par défaut et contacte motd.ubuntu.com.

Le script est piégeur à analyser : il avale les erreurs de wget et sort en code 0 quoi qu'il arrive. Un echo $? ne prouve donc rien, ni dans un sens ni dans l'autre. Le lab a contourné le problème en instrumentant wget pour journaliser ses arguments, puis en confirmant à tcpdump. Voici le User-Agent réellement émis :

wget/1.25.0 Ubuntu/26.04/LTS GNU/Linux/7.0.0-27-generic/x86_64
12th/Gen/Intel(R)/Core(TM)/i7-12650H cloud_id/nocloud

Décodez ce que votre serveur transmet à chaque connexion : la version exacte de la distribution, la version du noyau, l'architecture, le modèle exact du processeur, et l'identifiant du fournisseur cloud. La capture tcpdump confirme les requêtes DNS pour motd.ubuntu.com et le nom d'hôte en clair dans le SNI de la poignée de main TLS.

Sur un réseau cloisonné, un environnement souverain ou une infrastructure soumise à une revue de conformité, c'est un flux sortant non déclaré vers un tiers, déclenché par une action banale. Cela mérite au minimum d'être documenté, et le plus souvent d'être coupé.

La neutralisation tient en une ligne, et elle a été vérifiée à la capture réseau : après ce changement, le lab observe zéro appel wget et zéro paquet vers Canonical.

Fenêtre de terminal
sudo sed -i 's/^ENABLED=1/ENABLED=0/' /etc/default/motd-news
grep ENABLED /etc/default/motd-news # doit afficher ENABLED=0

Détail amusant pour qui ira lire le script : il contient un bug de code mort. Son instruction case teste le motif https://* avant https://motd.ubuntu.com, or le premier motif attrape déjà tout. La branche censée ajouter /$codename/$arch à l'URL n'est donc jamais atteinte, ce que l'argv capturé confirme : l'URL réellement demandée est la racine du site.

Canonical publie une liste de problèmes connus pour chaque version. Trois d'entre eux mordent en production, et le lab en contredit un frontalement.

L'unité systemd d'Apache pose MemoryDenyWriteExecute=yes par défaut, une protection qui interdit à un processus d'allouer de la mémoire à la fois inscriptible et exécutable. C'est exactement ce dont le JIT de PHP (compilateur à la volée) a besoin. Jusque-là, la documentation officielle et le lab sont d'accord.

Ils divergent sur le symptôme. La documentation annonce un message d'erreur clair, Allocation of JIT memory failed. Le lab a monté un test A/B/C/D complet avec PHP 8.5.4, opcache.jit=tracing et un buffer de 64 Mo, sur la même machine :

TestConfigurationRésultat
AFichier statique, MemoryDenyWriteExecute=yesHTTP 200
BPHP + JIT, MemoryDenyWriteExecute=yes (défaut Ubuntu)HTTP 000
CPHP sans JIT, MemoryDenyWriteExecute=yesHTTP 200
DPHP + JIT, MemoryDenyWriteExecute=noHTTP 200

Le coupable est bien le couple MemoryDenyWriteExecute=yes + JIT, la documentation a raison sur ce point. Mais le message annoncé n'apparaît jamais. Ce que le lab observe, c'est un HTTP 000, c'est-à-dire aucune réponse du tout : le worker meurt avant de répondre, et le journal d'erreur d'Apache ne contient que ceci :

mprotect() failed [13] Permission denied

La nuance est loin d'être cosmétique. Le service reste active aux yeux de systemd, votre supervision reste au vert, et seul le client voit une réponse vide. Un administrateur qui cherche Allocation of JIT memory failed dans ses journaux, comme la documentation l'y invite, ne trouvera rien et passera à côté de la cause.

Deux contournements, au choix. Le plus propre est de basculer vers php-fpm, qui ne subit pas la restriction de l'unité Apache. Le plus rapide est un drop-in systemd, posé avec systemctl edit :

Fenêtre de terminal
sudo systemctl edit apache2
[Service]
MemoryDenyWriteExecute=no
Fenêtre de terminal
sudo systemctl restart apache2
systemctl show apache2 -p MemoryDenyWriteExecute # doit afficher =no

Assumez ce que vous faites : vous retirez une protection mémoire pour rendre le JIT possible. Sur un serveur exposé, php-fpm est le meilleur choix.

Deux autres points à connaître avant de migrer une base ou un serveur de fichiers. PostgreSQL subit une régression de débit et de latence liée à un changement du noyau Linux 7.0 ; le contournement officiel est l'activation des huge pages (huge_pages = on), qui réduit le coût de gestion de la mémoire virtuelle. Par ailleurs, l'héritage des ACL POSIX est cassé avec mkdir -p : les répertoires intermédiaires créés par cette commande peuvent recevoir des permissions plus ouvertes que prévu. Si vous vous appuyez sur des ACL par défaut pour cloisonner un partage, vérifiez le résultat avec getfacl après création, ne présumez rien.

Ces deux affirmations sont partout, y compris dans des billets récents sur 26.04. Le lab les a testées. Les deux sont fausses, et les corriger vous évitera de bâtir vos procédures sur une croyance.

« cloud-init écrase votre configuration réseau au reboot »

Section intitulée « « cloud-init écrase votre configuration réseau au reboot » »

C'est le classique absolu. On vous prévient qu'une IP statique posée à la main dans netplan sera écrasée au prochain redémarrage par cloud-init.

Le lab a posé un fichier 99-lab-statique.yaml dans /etc/netplan/, puis fait un vrai reboot (identifiant de démarrage vérifié). Résultat : le fichier est toujours là, intact. Mieux, 50-cloud-init.yaml n'a même pas été réécrit, sa date de modification n'a pas bougé. Un simple redémarrage ne déclenche aucune réécriture.

Le vrai déclencheur est le reprovisionnement, c'est-à-dire une instance neuve aux yeux de cloud-init : clonage d'une VM, création depuis un modèle d'image, ou cloud-init clean. Le lab a simulé exactement ce cas :

Ce que vous avez modifiéAprès cloud-init clean + reboot
Une édition dans 50-cloud-init.yamlEffacée
Un fichier séparé 99-lab-statique.yamlSurvit

La leçon exacte est donc plus fine que la légende : cloud-init ne touche qu'à son propre fichier, 50-cloud-init.yaml. Éditer ce fichier est l'erreur ; poser votre propre fichier 99-*.yaml ne craint rien, même au reprovisionnement. La bonne pratique reste la même, mais vous la suivez maintenant pour la bonne raison. La configuration réseau elle-même est détaillée dans le guide Netplan.

Si vous devez vraiment neutraliser cloud-init côté réseau, par exemple sur une image de base d'entreprise, le remède est vérifié : avec ce fichier, une modification de 50-cloud-init.yaml survit même à un cloud-init clean suivi d'un reboot.

/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
network: {config: disabled}

« needrestart redémarre vos services en douce »

Section intitulée « « needrestart redémarre vos services en douce » »

Deuxième croyance, tout aussi répandue : needrestart, l'outil appelé par un hook APT après chaque mise à jour, redémarrerait tout seul les services liés à une bibliothèque mise à jour.

C'est faux sur Ubuntu. Le lab a remonté la chaîne de configuration. Dans /etc/needrestart/needrestart.conf, la ligne qui fixe le mode est commentée :

40:#$nrconf{restart} = 'i';

Le répertoire conf.d/ ne contient qu'un README : aucun override Ubuntu. Le défaut appliqué est donc celui du code, lisible ligne 149 de /usr/sbin/needrestart : restart => 'i', c'est-à-dire interactif. needrestart demande, il ne redémarre pas en silence. Le comportement est identique sur 24.04.

Attention au faux test qui alimente la légende : réinstaller openssh-server redémarre bien le service ssh, mais c'est le script postinst du paquet qui le fait, pas needrestart. Ce qui reste vrai, en revanche, mérite d'être noté : en mode non interactif (une mise à jour automatisée, un pipeline), cette invite bloque le script au lieu de le laisser continuer. C'est le vrai problème d'exploitation, et il est différent de celui qu'on raconte.

La question revient à chaque nouveau projet. Voici une comparaison adossée aux faits de ce guide, sans militantisme. Les deux distributions partagent la même base APT et la même culture, elles ne se distinguent que sur quelques axes, mais ces axes comptent.

CritèreUbuntu Server 26.04 LTSDebian 13 Trixie
Couverture de sécuritémain seulement (~2 300 paquets), 5 ans gratuitstoute l'archive main, sans découpage équivalent (contrib et non-free exclus)
Paquets serveur courantsDocker, Redis, fail2ban en universe, donc hors garantiedans l'archive couverte
Noyaurécent (série 7.0), HWE optionnelconservateur (série 6.12)
Images cloudomniprésentes, souvent disponibles en premierdisponibles, parfois plus tard
Snapsnapd installé par défaut, LXD uniquement en snapabsent par défaut
Bruit commercialMOTD, appel réseau à Canonical, messages Ubuntu Proaucun
Support commercialUbuntu Pro, certifications FIPS et CISvia prestataires tiers

Le critère décisif est le premier. Si votre production repose sur des paquets de universe et que vous ne prenez pas Ubuntu Pro, Debian vous couvre mieux sur ces paquets précis. Si vous avez besoin de certifications, d'un support éditeur ou d'images cloud disponibles partout et tout de suite, Ubuntu garde l'avantage. Pour poser le cadre général du choix, lisez choisir une distribution serveur, et pour l'équivalent Debian de ce guide, Debian 13 Trixie.

Sur un serveur, le noyau par défaut est le noyau GA (General Availability), figé pour toute la durée de la LTS. Le noyau HWE (Hardware Enablement) est celui qui suit le matériel récent, et il est roulant : il est poussé vers le HWE suivant tous les six mois. Choisir le HWE « pour supporter du matériel récent », c'est donc signer pour un changement de noyau semestriel sur une machine censée être stable pendant cinq ans. Ne le faites que si votre matériel l'exige réellement, et documentez ce choix.

Oubliez le débat desktop sur Firefox, il n'a aucune pertinence ici. Sur l'image serveur du lab, snapd est installé et actif mais aucun snap n'est installé, et apt purge snapd fonctionne proprement en libérant 147 Mo. Trois faits méritent en revanche votre attention. LXD n'existe qu'en snap, il n'y a pas de paquet deb : si vous virtualisez avec LXD, vous gardez snapd. Le client Livepatch est un snap dès que vous activez Ubuntu Pro. Enfin, le point le plus dangereux : le snap Docker redémarre le démon à chaque rafraîchissement automatique, donc coupe vos conteneurs. C'est une raison de plus, en pratique, d'installer Docker depuis le dépôt APT officiel de Docker plutôt que par snap.

Dernier point de vigilance, souvent mal vendu. Livepatch applique des correctifs de sécurité au noyau sans redémarrer, ce qui séduit sur un parc en production. Deux réserves : il ne couvre que les vulnérabilités de sévérité haute et critique, et sa documentation impose explicitement de mettre à jour et redémarrer tous les 13 mois. Livepatch ne supprime pas les redémarrages, il les décale. Planifiez-les quand même. La routine des correctifs au quotidien est décrite dans mises à jour de sécurité.

Ce tableau regroupe les symptômes les plus fréquents sur une 26.04 neuve ou migrée. Cherchez-y avant de partir en investigation : dans la grande majorité des cas, le coupable est un des changements documentés plus haut, pas un bug de votre application.

SymptômeCause probableSolution
Unable to locate package docker.io sur une image cloudIndex de universe non livré avec l'imagesudo apt update avant toute installation
apt-key: command not foundapt-key supprimé en APT 3.xClé dans /etc/apt/keyrings/ + champ Signed-By:
Parsing de ls cassé en cron ou en CIuutils colorise malgré un LS_COLORS videRetirer --color=always, ou appeler gnuls
Script Expect bloqué sur sudoPrompt [sudo: authenticate] Password: (sudo-rs)Adapter le motif attendu, ou passer par une règle NOPASSWD
grep "unrecognized option" ne trouve plus rienMessages d'erreur clap (Rust)Adapter le motif, ou basculer sur GNU
apt install coreutils-from-gnu échoueConflit sur le virtuel coreutils-fromapt install --allow-remove-essential coreutils-from-gnu coreutils-from-uutils-
Refus AppArmor répétés sur le profil whoProfil non mis à jour pour uutilsBug de packaging, sans impact fonctionnel ; surveiller le correctif
Fichiers disparus de /tmp après un reboot/tmp en tmpfs (mémoire vive)Écrire ailleurs, ou masquer tmp.mount
Apache répond vide sur les pages PHP, service activeMemoryDenyWriteExecute=yes + JIT PHPphp-fpm, ou systemctl edit apache2 avec MemoryDenyWriteExecute=no
systemctl status systemd-timesyncd : not-foundRemplacé par chronychronyc tracking
do-release-upgrade ne propose pas 26.0426.04.1 pas encore sortie (27 août 2026)Attendre ; ne pas utiliser -d en production
Mise à jour automatisée bloquée sans erreurInvite needrestart en mode interactifNEEDRESTART_MODE=l dans l'environnement du script
  • Ubuntu 26.04 LTS « Resolute Raccoon » est sortie le 23 avril 2026. Le cycle est de 15 ans (5 standard + 5 ESM + 5 Legacy), pas 10 ni 12 comme l'écrit encore la majorité du web.
  • La maintenance de sécurité gratuite ne couvre que main (~2 300 paquets). universe (plus de 36 000) est en « best effort », sans engagement, dès le jour 1.
  • docker.io, redis, fail2ban et prometheus sont dans universe : une stack Docker + Redis + fail2ban n'est pas couverte sans Ubuntu Pro, qui est gratuit jusqu'à 5 machines en usage personnel. Contre-intuitif : containerd, lui, est dans main.
  • Les coreutils sont en Rust (uutils 0.8.0). Seules cinq commandes restent GNU : cp, mv, rm, df et true. GNU est déjà installé sous le préfixe gnu (gnuls), aucune installation nécessaire pour dépanner.
  • La divergence dangereuse est ls --color=always, qui émet des codes ANSI même avec LS_COLORS vide : tout parsing en cron ou en CI casse en silence. En revanche, aucun code de retour ne change sur les 93 sondes du lab.
  • La commande de rollback documentée échoue. La seule qui fonctionne est apt install --allow-remove-essential coreutils-from-gnu coreutils-from-uutils-.
  • sudo-rs change le prompt ([sudo: authenticate] Password:), ce qui casse les automatisations Expect. L'original survit sous sudo.ws, et sudoreplay.ws existe toujours.
  • apt-key est supprimé, cgroup v1 abandonné par systemd, /tmp est un tmpfs, chrony remplace timesyncd : tout tutoriel antérieur est à relire.
  • Au 12 juillet 2026, une 24.04 ne se voit pas proposer la 26.04 : la 26.04.1 est planifiée le 27 août 2026. Les PPA et dépôts tiers sont la première cause d'échec de migration.
  • Le MOTD contacte Canonical à chaque connexion SSH en transmettant distribution, noyau, architecture, modèle de processeur et identifiant cloud. ENABLED=0 dans /etc/default/motd-news coupe le flux.
  • Deux légendes tombent au test : cloud-init n'écrase pas votre netplan à un simple reboot (seul le reprovisionnement est en cause), et needrestart ne redémarre rien en silence (son défaut est interactif).

Ce guide croise un lab et les publications officielles. Les liens ci-dessous permettent de vérifier chaque affirmation à la source, et de suivre l'évolution des points encore mouvants, en particulier l'ouverture de la migration depuis 24.04.

Les notes de version officielles, à lire en premier :

Le modèle de support, cœur du sujet de ce guide :

  • Cycle de vie des versions Ubuntu : la page qui atteste les 15 ans (5 standard, ESM jusqu'en 2036, Legacy jusqu'en 2041), et non les 10 ans encore écrits partout.
  • Expanded Security Maintenance (ESM) : la source qui prouve le trou universe. On y lit que le flux esm-apps couvre universe pendant dix ans à compter de la sortie de la LTS, là où esm-infra ne prend main qu'après les cinq ans gratuits.
  • Ubuntu Pro : les conditions de la souscription, dont la gratuité jusqu'à 5 machines en usage personnel.
  • Mettre à niveau sa version d'Ubuntu Server : la règle officielle qui explique pourquoi la 26.04 ne vous est pas encore proposée, et qui désigne les dépôts tiers comme première cause d'échec.

Les bugs qui confirment les observations du lab :

  • Bug Launchpad #2146618 : l'échec de coreutils-from-gnu, avec l'erreur de dépendances exactement reproduite dans ce guide. Ce n'est pas une singularité de notre machine.
  • Bug Launchpad #2123870 : les profils AppArmor incompatibles avec le nouveau schéma des coreutils, contexte du refus observé sur le profil who.

Les points de vigilance à l'exploitation :

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn