Debian 13 : mise à niveau APT ratée — restaurer un paquet sans effet domino

Cet article vous a aidé ?

Vous avez mis à niveau une machine Debian 13, un paquet a mal tourné, et maintenant le système se comporte comme s’il jouait une tragédie : services instables, erreurs de symboles étranges, voire une unité non amorçable si vous avez été malchanceux. Vous ne voulez pas un retour complet. Vous voulez remettre un paquet à sa version précédente. Et vous ne voulez pas non plus qu’APT « aide » en rétrogradant la moitié de votre pile, parce que vous connaissez déjà le film et que la fin finit toujours en heures sup.

Voici la méthode adaptée à la production : identifier exactement ce qui a changé, choisir la bonne version, la rétrograder avec un impact contrôlé sur les dépendances, puis la pinner/mettre en hold pour qu’elle reste en place jusqu’à ce que vous soyez prêt. En chemin, nous parlerons de snapshots, d’arêtes de dépendances et pourquoi « simplement apt install l’ancien .deb » est la voie royale pour devenir une histoire de mise en garde.

Règles de base : ce que signifie réellement « restaurer un paquet » sur Debian

Debian n’a pas de bouton « restauration de paquet » intégré parce qu’APT n’est pas une machine à remonter le temps ; c’est un solveur de dépendances. Restaurer un seul paquet est possible, mais vous négociez avec des relations :

  • Dépendances : le paquet que vous voulez peut exiger une bibliothèque plus récente que l’ancienne version, ou inversement.
  • Compatibilité ABI : les bibliothèques et les éléments face au noyau ont des promesses de compatibilité… jusqu’à ce qu’elles n’en aient plus, ou que votre application utilise un cas limite.
  • État des dépôts : la version souhaitée doit être disponible depuis une source configurée ou votre cache local.
  • Politique : APT choisira « la meilleure » candidate selon les pins, l’origine, la priorité et la suite. Si vous ne définissez pas de politique, vous obtenez des vibes.

L’objectif n’est pas « forcer l’installation d’un ancien .deb. » L’objectif est : rétrograder un paquet vers une version connue pour être fonctionnelle, tout en évitant une cascade incontrôlée de rétrogradations ou de suppressions.

Deuxième objectif : faire en sorte que le système s’explique. Si vous ne pouvez pas prédire ce que APT fera, vous ne faites pas une restauration — vous jouez.

Blague n°1 : APT, c’est comme un stagiaire très confiant : rapide, serviable, et absolument capable de réorganiser toute votre maison pour trouver l’agrafeuse.

Mode opératoire de diagnostic rapide

Quand vous êtes sous pression, ne commencez pas par « essayer des rétrogradations aléatoires ». Commencez par les vérifications minimales qui révèlent la topologie des dépendances et du packaging de l’incident.

Première étape : identifier ce qui a changé et ce qui est actuellement cassé

  • Quelle version du paquet est installée maintenant ?
  • Quelle version était installée avant ?
  • Quel service ou binaire échoue, et pourquoi (symboles, config, permissions, ABI) ?
  • dpkg est-il dans un état à moitié configuré ?

Deuxième étape : déterminer si une restauration est faisable sans réaction en chaîne

  • Le paquet cible dépend-il de bibliothèques désormais plus récentes que l’ancienne version n’attendait pas ?
  • La rétrogradation le forcera-t-elle à provoquer des rétrogradations de bibliothèques dont d’autres paquets ont besoin ?
  • L’ancienne version est-elle encore disponible depuis vos dépôts configurés ou votre cache ?

Troisième étape : mettre en œuvre une restauration contrôlée

  • Simulez avec APT et inspectez les changements proposés.
  • Rétrogradez en sélectionnant explicitement la version.
  • Pinez/lockez pour empêcher la remise à niveau.
  • Faites une vérification minimale : état du service, logs et une requête de sanity.

Quatrième étape : prévenir la récurrence

  • Faire des snapshots avant les mises à jour (système de fichiers ou VM).
  • Étager les mises à jour (hôte canari d’abord).
  • Tracer les deltas de version dans la gestion des changements, pas dans la mémoire de quelqu’un.

Faits et contexte qui rendent le comportement d’APT moins mystérieux

Ce ne sont pas des réponses pour la soirée quiz. C’est le modèle mental dont vous avez besoin quand APT commence à proposer « suppression de 37 paquets » et appelle ça une fonctionnalité.

  1. APT est un résolveur, dpkg est l’installateur. APT décide de ce qui devrait se passer ; dpkg exécute, suit l’état, et peut rester à moitié terminé si quelque chose l’interrompt.
  2. « Depends » est strict, « Recommends » est (majoritairement) optionnel. Debian traitait historiquement Recommends comme optionnel, puis APT a pris l’habitude de les installer par défaut, ce qui surprend ceux qui ont appris Debian auparavant.
  3. Les dépendances versionnées sont courantes dans les piles cœur. Les bibliothèques exigent souvent « >= x.y » et parfois « << x.z » (rare, mais piquant). Ces contraintes dictent jusqu’où vous pouvez reculer.
  4. Les priorités de pin contrôlent la sélection des candidates. Ce n’est pas magique : les pins créent un ordre partiel ; APT choisit la candidate de priorité la plus élevée qui satisfait les dépendances.
  5. Le « stable » de Debian est conservateur ; « testing » évolue. Si votre système Debian 13 tire depuis des suites mixtes ou des dépôts tiers, vous exécutez en réalité une distribution personnalisée.
  6. Les rétrogradations sont prises en charge, mais pas sans friction. APT les fera, mais de nombreux mainteneurs testent principalement les montées de version. Vous nagez à contre-courant.
  7. Les scripts de mainteneur peuvent modifier l’état en dehors des fichiers. Les postinst peuvent activer des services, créer des utilisateurs, migrer des données ou réécrire des configs. Rétrograder un paquet ne restaure pas toujours ces effets secondaires.
  8. « apt-get » vs « apt » n’est pas que du feeling. La commande plus récente apt est plus conviviale pour les humains ; apt-get est stable pour les scripts. En incident, préférez la prévisibilité.
  9. Debian gère multiarch depuis des années. Un même nom de paquet peut avoir plusieurs architectures installées (comme :amd64 et :i386), ce qui peut compliquer les restaurations « d’un seul paquet ».

Les 12+ tâches pratiques : commandes, sorties et décisions

Chaque tâche inclut : une commande exécutable, une sortie d’exemple, ce que cela signifie, et la décision que vous en tirez. Vous n’aurez pas besoin de toutes, mais vous devez savoir laquelle répond à quelle question.

Task 1: Confirm dpkg isn’t half-configured

cr0x@server:~$ sudo dpkg --audit
The following packages are only half configured, probably due to problems configuring them the first time.
 libssl3:amd64

Ce que ça signifie : Votre système n’est pas dans un état de paquet propre. Rétrograder avec dpkg à mi-chemin est la recette pour « ça marche sur mon terminal » suivi d’un redémarrage plein de regrets.

Décision : Réparez l’état de dpkg d’abord : exécutez sudo dpkg --configure -a et résolvez les erreurs avant de tenter des rétrogradations.

Task 2: Get the installed version and the candidate version

cr0x@server:~$ apt-cache policy libssl3
libssl3:
  Installed: 3.3.1-1
  Candidate: 3.3.2-1
  Version table:
     3.3.2-1 500
        500 http://deb.debian.org/debian trixie/main amd64 Packages
 *** 3.3.1-1 100
        100 /var/lib/dpkg/status

Ce que ça signifie : Installed diffère de Candidate. Vous pouvez rétrograder/mettre à niveau selon ce qui est disponible. La Version table montre d’où viennent les versions et leurs priorités de pin.

Décision : Si la version souhaitée n’est pas listée, vous devrez ajouter un dépôt qui la fournit, ou la retrouver dans le cache local.

Task 3: Find what upgraded recently (APT history)

cr0x@server:~$ sudo zgrep -h "Start-Date\|Upgrade:" /var/log/apt/history.log*
Start-Date: 2025-12-29  02:13:41
Upgrade: nginx:amd64 (1.26.1-2, 1.26.2-1), nginx-common:amd64 (1.26.1-2, 1.26.2-1)
End-Date: 2025-12-29  02:14:12

Ce que ça signifie : Cela vous dit ce qui a effectivement changé, pas ce que vous pensez avoir changé.

Décision : Si le paquet problématique est dans cette liste, la restauration est une hypothèse valable. Sinon, vous pourriez courir après la mauvaise chose (comme une mise à jour de bibliothèque).

Task 4: Check dpkg logs for maintainer script failures

cr0x@server:~$ sudo grep -E "install |upgrade |configure " /var/log/dpkg.log | tail -n 8
2025-12-29 02:13:45 upgrade nginx:amd64 1.26.1-2 1.26.2-1
2025-12-29 02:13:46 status half-configured nginx:amd64 1.26.2-1
2025-12-29 02:13:47 status installed nginx:amd64 1.26.2-1

Ce que ça signifie : Si vous voyez « half-configured » qui ne se résout jamais, vous avez probablement un problème de postinst (syntaxe de config, permissions, échec de reload systemd).

Décision : Si un script mainteneur a cassé, la restauration peut aider, mais réparer la config peut être plus rapide et plus sûr que rétrograder.

Task 5: Inspect why a package is installed and who depends on it

cr0x@server:~$ apt-cache rdepends --installed nginx | head -n 12
nginx
Reverse Depends:
  nginx-extras
  nginx-full
  myapp-web

Ce que ça signifie : Rétrograder nginx affectera tout ce qui en dépend.

Décision : Si un paquet interne critique dépend d’une version minimale de nginx, rétrograder nginx peut vous forcer à rétrograder ce paquet aussi. Décidez si c’est acceptable.

Task 6: Show dependency constraints (the ones that bite)

cr0x@server:~$ apt-cache show nginx | sed -n '1,80p'
Package: nginx
Version: 1.26.2-1
Depends: nginx-common (= 1.26.2-1), libc6 (>= 2.38), libpcre2-8-0 (>= 10.34)

Ce que ça signifie : Les dépendances verrouillées par version ((= 1.26.2-1)) signifient que vous ne pouvez pas rétrograder nginx seul ; il faut aussi rétrograder le paquet apparié.

Décision : Planifiez la restauration au niveau de « l’ensemble de paquets source » lorsque vous voyez des dépendances d’égalité strictes.

Task 7: Check what versions are available for downgrade

cr0x@server:~$ apt list -a nginx 2>/dev/null | sed -n '1,6p'
nginx/trixie 1.26.2-1 amd64
nginx/trixie 1.26.1-2 amd64

Ce que ça signifie : Le dépôt offre les deux versions. Bien : vous pouvez demander à APT une version exacte sans chasser des .deb.

Décision : Si la version souhaitée manque, arrêtez et résolvez d’abord le problème de disponibilité (suite de dépôt, snapshot ou cache).

Task 8: Dry-run the downgrade and inspect the blast radius

cr0x@server:~$ sudo apt-get -s install nginx=1.26.1-2 nginx-common=1.26.1-2
Reading package lists... Done
Building dependency tree... Done
The following packages will be DOWNGRADED:
  nginx nginx-common
0 upgraded, 0 newly installed, 2 downgraded, 0 to remove and 0 not upgraded.
Inst nginx [1.26.2-1] (1.26.1-2 Debian:13.0/trixie [amd64])
Inst nginx-common [1.26.2-1] (1.26.1-2 Debian:13.0/trixie [amd64])

Ce que ça signifie : Résultat parfait : seuls les paquets cibles se rétrogradent. Pas de suppressions, pas de rétrogradations surprises de bibliothèques.

Décision : Procédez si la simulation est étroite. Si APT veut supprimer des paquets ou rétrograder des libs cœur, n’avancez pas sans plan (pinning, version alternative, ou restauration via snapshot).

Task 9: Execute the downgrade with explicit versions

cr0x@server:~$ sudo apt-get install nginx=1.26.1-2 nginx-common=1.26.1-2
Reading package lists... Done
Building dependency tree... Done
The following packages will be DOWNGRADED:
  nginx nginx-common
Need to get 0 B/1,233 kB of archives.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
dpkg: warning: downgrading nginx:amd64 from 1.26.2-1 to 1.26.1-2

Ce que ça signifie : Dpkg effectue la rétrogradation ; c’est un comportement supporté.

Décision : Surveillez les erreurs des scripts de mainteneur. Si elles surviennent, récupérez les logs immédiatement et décidez de corriger la config, relancer la configuration, ou revenir en arrière avec des snapshots.

Task 10: Verify the service and surface errors quickly

cr0x@server:~$ systemctl status nginx --no-pager -l
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-12-29 02:21:06 UTC; 12s ago
       Docs: man:nginx(8)

Ce que ça signifie : Le service est actif. Ne vous arrêtez pas là — le statut n’est pas la correction, c’est juste un pouls.

Décision : S’il n’est pas actif, inspectez ensuite les logs journal.

Task 11: Read the journal for the package’s failure mode

cr0x@server:~$ sudo journalctl -u nginx -b --no-pager -n 30
Dec 29 02:20:58 server nginx[1422]: nginx: [emerg] unknown directive "http2_push_preload" in /etc/nginx/conf.d/site.conf:12
Dec 29 02:20:58 server systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE

Ce que ça signifie : Ce n’est pas un problème binaire/ABI. C’est un décalage de configuration. Rétrograder peut « réparer » cela, mais la vraie correction est de concilier la config avec la syntaxe supportée.

Décision : Décidez s’il faut restaurer la config ou l’adapter à la nouvelle version. Rétrograder un serveur web pour accommoder une config obsolète est généralement le mauvais choix.

Task 12: Verify shared library / symbol errors (classic post-upgrade pain)

cr0x@server:~$ /usr/bin/myapp-web
/usr/bin/myapp-web: symbol lookup error: /lib/x86_64-linux-gnu/libssl.so.3: undefined symbol: EVP_MD_get_type

Ce que ça signifie : Mismatch ABI. Votre binaire attend un symbole absent de la version de la bibliothèque installée (ou inversement).

Décision : Identifiez quel paquet fournit la bibliothèque et choisissez un couple de versions compatibles (ou rebuild l’app). Rétrograder uniquement le paquet applicatif peut ne pas suffire si la bibliothèque a changé.

Task 13: Map a file to its owning package (when you only know the broken .so)

cr0x@server:~$ dpkg -S /lib/x86_64-linux-gnu/libssl.so.3
libssl3:amd64: /lib/x86_64-linux-gnu/libssl.so.3

Ce que ça signifie : Le symbole cassé se trouve dans libssl3. C’est la cible de restauration, ou l’app doit être recompilée contre le nouvel ABI.

Décision : Vérifiez les versions disponibles de libssl3, et qui en dépend avant de toucher une bibliothèque crypto cœur.

Task 14: Inspect who depends on a core library before touching it

cr0x@server:~$ apt-cache rdepends --installed libssl3 | head -n 20
libssl3
Reverse Depends:
  openssh-client
  curl
  nginx
  myapp-web

Ce que ça signifie : Rétrograder libssl3 peut affecter plusieurs paquets critiques. C’est là que « restaurer un paquet » devient « changer les fondations ».

Décision : Si la liste des reverse-deps inclut des outils sensibles pour la sécurité (ssh, curl), préférez recompiler l’app ou utiliser l’isolation par conteneur plutôt que de rétrograder la bibliothèque système.

Task 15: Find cached .debs already on the box (when repos moved on)

cr0x@server:~$ ls -1 /var/cache/apt/archives | grep -E '^nginx_'
nginx_1.26.1-2_amd64.deb
nginx_1.26.2-1_amd64.deb

Ce que ça signifie : Vous avez peut-être déjà le .deb exact dont vous avez besoin sans changer de dépôts. Utile pour une restauration rapide en incident.

Décision : Si vous installez depuis le cache, préférez toujours APT avec la version explicite pour conserver la cohérence de la gestion des dépendances.

Task 16: See what APT would remove if you attempt a downgrade (red flag)

cr0x@server:~$ sudo apt-get -s install libssl3=3.3.0-2
Reading package lists... Done
Building dependency tree... Done
The following packages have unmet dependencies:
 openssh-client : Depends: libssl3 (>= 3.3.1-1) but 3.3.0-2 is to be installed
E: Unable to correct problems, you have held broken packages.

Ce que ça signifie : La rétrogradation est incompatible avec d’autres paquets installés. APT refuse, ce qui est un cadeau.

Décision : Ne forcez pas avec dpkg. Soit vous restaurez aussi les paquets dépendants (si acceptable), soit vous choisissez une autre stratégie (recompiler l’app, conteneur, ou restauration via snapshot).

Choisir la cible de restauration : version, origine et périmètre

Rétrograder « le paquet qui a cassé » est souvent une erreur parce que la cassure visible n’est que le premier domino. La vraie cause est généralement l’un de ces cas :

  • Choc ABI de bibliothèque (openssl, libc, zlib, libstdc++) : erreurs de symboles ou plantages.
  • Changement de schéma de configuration (nginx, unités systemd, configs de bases de données) : le service ne démarre pas, les logs signalent des directives inconnues ou des valeurs invalides.
  • Changement de comportement d’outillage (packaging python, outils node, changements openssh) : vos scripts échouent silencieusement ou se comportent différemment.
  • Incompatibilité kernel/userspace (drivers, outils eBPF) : particulièrement avec des modules hors-arbre ou des agents constructeur.

Décidez : restaurez-vous l’app, la bibliothèque, ou les deux ?

Mon biais : rétrogradez l’application avant de toucher au plomberie OS. Rétrograder des paquets applicatifs tend à être localisé. Rétrograder des bibliothèques crypto et libc, c’est étendre l’incident vers « pourquoi ne pouvons-nous plus ssh ? »

Cependant parfois l’app est correcte et la bibliothèque est la régression. Dans ce cas vous avez trois options pratiques :

  1. Monter en version (préféré si une version corrigée existe). Si le bug est en 1.2.3 et que 1.2.4 le corrige, la restauration est une distraction.
  2. Recompiler l’app contre le nouvel ABI si vous contrôlez la compilation. Cela évite les rétrogradations système.
  3. Rétrograder la bibliothèque uniquement si (a) le dépôt offre un ensemble compatible et (b) les reverse-deps peuvent le tolérer.

Décidez : quel dépôt « possède » la version que vous voulez

En territoire Debian, les versions disponibles dépendent de vos sources configurées et de leurs priorités. Mélanger des suites (stable/testing/unstable) est possible, mais c’est comme mélanger des grades d’essence en haussant les épaules.

Utilisez apt-cache policy et apt list -a pour voir ce qui est réellement disponible. Si la version n’est pas disponible, vous ne pouvez pas rétrograder proprement avec APT sans changer vos sources ou utiliser des paquets en cache.

Rétrograder en sécurité : minimiser le rayon d’impact

Voici le flux qui vous évite l’enfer des dépendances :

  1. Simuler la rétrogradation avec apt-get -s.
  2. Inspecter la liste d’actions : paquets rétrogradés, paquets supprimés, paquets nouvellement installés.
  3. Rétrograder avec des versions explicites pour l’ensemble de paquets (souvent inclut -common ou -data).
  4. Immédiatement pinner/mettre en hold les paquets pour empêcher APT de les « réparer » lors de la prochaine mise à jour.
  5. Vérifier le comportement en runtime : service, logs et une requête réelle.

Simulez sérieusement

La simulation n’est pas optionnelle. En production, vous ne « testez » pas des opérations de paquet. Vous les prédisez.

Si APT veut supprimer des paquets, lisez la liste attentivement. La suppression peut être rationnelle (conflits), mais c’est aussi comme ça qu’on finit par supprimer son agent de monitoring puis passer deux heures à « déboguer un problème de performance » sans graphiques.

Sachez quand vous arrêter et utiliser un snapshot

Si la restauration exige la rétrogradation de composants cœur comme libc6, systemd, openssl ou le noyau, vous ne faites plus une « restauration d’un paquet ». Vous effectuez un retour partiel de distribution. C’est là que les snapshots système/VM brillent : ils restaurent un état système cohérent.

Blague n°2 : La restauration la plus rapide est celle pour laquelle vous avez pris un snapshot hier. La seconde plus rapide est celle que vous pouvez expliquer à votre futur vous sans pleurer.

Pinning et hold : empêcher APT de « corriger » votre correctif

Rétrograder est l’étape un. Le maintenir rétrogradé est l’étape deux. L’étape deux est là où les gens échouent silencieusement, puis sont surpris lors de la prochaine fenêtre de mises à jour non surveillées.

Utilisez un hold pour la contention immédiate

Un hold est brutal, rapide et réversible. Il empêche les mises à niveau de ce paquet.

cr0x@server:~$ sudo apt-mark hold nginx nginx-common
nginx set on hold.
nginx-common set on hold.

Signification : Ces paquets ne seront pas mis à niveau tant que vous ne les aurez pas libérés.

Décision : Utilisez les holds pour contenir l’incident. Puis implémentez le pinning si vous avez besoin d’une politique plus durable.

Utilisez le pinning APT quand vous avez besoin d’une politique, pas d’un pansement

Le pinning est préférable lorsque vous exécutez des dépôts mixtes ou lorsque vous voulez autoriser les mises à jour en général mais forcer un paquet spécifique à rester à une version choisie.

Créez un fichier preferences, par exemple :

cr0x@server:~$ sudo tee /etc/apt/preferences.d/nginx-rollback.pref >/dev/null <<'EOF'
Package: nginx nginx-common
Pin: version 1.26.1-2
Pin-Priority: 1001
EOF

Signification : Une priorité > 1000 indique à APT qu’il peut sélectionner cette version même si c’est une rétrogradation.

Décision : Utilisez des pins de haute priorité avec parcimonie. Vous surchargez le résolveur ; faites-le avec un commentaire dans la gestion des changements et un rappel pour les supprimer plus tard.

Confirmez que le pin est actif

cr0x@server:~$ apt-cache policy nginx | sed -n '1,12p'
nginx:
  Installed: 1.26.1-2
  Candidate: 1.26.1-2
  Version table:
     1.26.2-1 500
        500 http://deb.debian.org/debian trixie/main amd64 Packages
 *** 1.26.1-2 1001
        500 http://deb.debian.org/debian trixie/main amd64 Packages
        100 /var/lib/dpkg/status

Signification : Candidate égale votre version pining. C’est ce que vous voulez.

Décision : Si Candidate est toujours la version plus récente, votre fichier preferences est incorrect (mauvais nom de paquet, chaîne de version erronée, ou une autre priorité de pin le surclasse).

Trois mini-récits d’entreprise issus du terrain

1) Incident causé par une mauvaise hypothèse : « C’est juste le paquet app »

L’équipe gérait une flotte de nœuds web Debian avec un petit service Go devant un proxy terminant TLS. Après une mise à jour de routine, les checks de santé ont commencé à échouer sur quelques hôtes, puis davantage. L’erreur sur laquelle tout le monde s’est focalisé figurait dans les logs de l’app : échecs de handshake TLS. L’hypothèse s’est formée rapidement : « la mise à jour de l’app a cassé TLS. »

Quelqu’un a restauré le paquet app sur deux hôtes. Aucun changement. Quelqu’un d’autre a restauré le proxy. Toujours cassé. Le responsable de l’incident a commencé à pousser des restaurations plus larges, une par une, parce que les systèmes restaient joignables et le tableau de bord métier non. La fenêtre de mise à niveau s’est transformée en roulette russe.

La vraie cause était un décalage de bibliothèque introduit par une mise à jour partielle : un hôte a redémarré au milieu d’une mise à jour (événement d’alimentation dans une rangée de racks), laissant dpkg dans un état incohérent. Certains nœuds avaient la nouvelle bibliothèque crypto et un paquet dépendant plus ancien ; d’autres avaient l’inverse. Le proxy allait bien, l’app allait bien. L’alignement ABI non.

Quand ils ont enfin regardé dpkg --audit et le log dpkg, c’était évident. La correction n’était pas « restaurer l’app ». C’était « finir proprement la mise à jour » sur les nœuds à moitié mis à jour, puis redémarrer les services. La leçon : le message d’erreur pointait vers TLS, mais le mode de défaillance était l’état du packaging.

Par la suite, ils ont ajouté une porte : aucun déploiement automatisé ne se poursuit tant que dpkg n’est pas propre et que la dernière transaction APT n’est pas terminée. C’était ennuyeux. Ça a aussi empêché une répétition.

2) Optimisation qui s’est retournée contre eux : « Accélérons les mises à jour en mixant des suites »

Un groupe plateforme voulait des fonctionnalités plus récentes dans un composant — appelons-le un reverse proxy ou un driver de base de données — sans attendre le rythme de stable. Ils ont fait ce que beaucoup de personnes intelligentes font sous pression : ajouté une ligne testing à sources.list et l’ont pinée « basse ». L’intention était de cherry-pick un paquet occasionnellement. La réalité : les graphes de dépendances ne respectent pas vos intentions.

Ça a marché pendant des mois. Puis une mise à jour de routine a tiré une bibliothèque plus récente depuis testing parce qu’elle avait une priorité de pin plus élevée que prévu pour l’origine de ce paquet (règle de préférence subtile mal alignée). Le proxy a été mis à jour, ses modules ont tiré une dépendance de bibliothèque plus exigeante, et soudain plusieurs autres paquets étaient éligibles à la mise à jour. APT a fait son travail : trouvé une solution cohérente. La solution n’était simplement pas cohérente avec la sécurité opérationnelle.

Deux semaines plus tard, ils ont tenté de restaurer « le seul paquet que nous avions pris depuis testing ». APT a proposé de rétrograder la bibliothèque, ce qui impliquait de rétrograder d’autres paquets qui s’étaient adaptés à la version plus récente. La restauration est devenue une lutte entre suites. Chaque « correctif » rendait la mise à jour suivante plus difficile.

La réparation finale n’a rien d’héroïque. Ils ont supprimé la suite mixte, sont revenus à une seule suite plus une politique de backport contrôlée, et ont utilisé des pins explicites avec date d’expiration (oui, littéralement un ticket leur rappelant de supprimer le pin). L’amélioration fut réelle : les mises à jour sont redevenues prévisibles. L’« optimisation » avait troqué la vitesse à court terme contre l’instabilité à long terme.

3) Pratique ennuyeuse mais correcte qui a sauvé la mise : snapshots et hôte canari

Un système adjacent à la finance avait des exigences strictes d’uptime et de contrôle des changements. L’équipe n’était pas flashy. Elle était prudente. Avant toute mise à jour, leur processus était : snapshot, mise à jour d’un canari, exécution de smoke tests, puis poursuite. Tout le monde roulait des yeux devant la paperasse jusqu’au jour où ça a compté.

Une mise à niveau Debian 13 a introduit une régression dans un paquet utilisé pour la génération de PDF. Le service démarrait, mais la sortie était subtilement incorrecte pour certaines polices. Si vous pensez « qui s’en soucie », les auditeurs s’en sont souciés. Le canari l’a détecté parce que le smoke test incluait la génération d’un document représentatif et le hachage de celui-ci. Pas un test unitaire ; un test en conditions réelles.

Au lieu de paniquer, ils ont pinner cette seule version, restauré uniquement ce paquet sur le canari, confirmé la correction de la sortie, puis appliqué la même restauration aux nœuds de production. Pas de cascade. Pas de suppressions aléatoires. Pas de drame.

Entre-temps, ils ont ouvert un ticket interne pour évaluer la nouvelle version du paquet et déterminer s’il fallait patcher la config ou attendre un build corrigé. Le snapshot n’a jamais eu besoin d’être restauré, mais savoir qu’il existait a changé toute la posture de l’incident. Le calme bat l’ingéniosité.

Erreurs communes : symptômes → cause → correctif

Cette section est l’endroit où les incidents arrêtent de se répéter. Traitez-la comme une liste de pièges.

1) « APT veut supprimer la moitié du système »

Symptômes : Lors d’une tentative de rétrogradation, APT propose de supprimer des blocs entiers (desktop, pile python, base de données).

Cause : Vous tentez d’installer une version qui entre en conflit avec l’ensemble de dépendances installé ; souvent causé par des suites mixtes, des dépôts tiers, ou des dépendances verrouillées par version.

Correctif : Arrêtez. Simulez et inspectez. Pinez la version spécifique souhaitée et assurez-vous que l’ensemble de dépendances correspondant existe dans la même suite de dépôt. Si des libs cœur sont impliquées, préférez la restauration via snapshot ou la montée en version.

2) « Dépendances non satisfaites, paquets bloqués cassés »

Symptômes : APT rapporte des dépendances non satisfaites ; dpkg ne peut pas corriger les problèmes.

Cause : Vous avez une mise à jour partielle, des pins brisés, ou des priorités de dépôts conflictuelles. Parfois un paquet est en hold et bloque un chemin de mise à jour/rétrogradation requis.

Correctif : Vérifiez les holds avec apt-mark showhold. Validez les priorités de pin avec apt-cache policy. Réparez l’état de dpkg avec dpkg --configure -a et apt-get -f install si approprié.

3) « Le service ne démarre pas après la mise à jour ; la restauration le « répare » »

Symptômes : unité systemd échoue ; les logs montrent une directive inconnue ou une option de config invalide.

Cause : Dérive de configuration. Votre configuration dépend d’un comportement supprimé ou modifié dans la nouvelle version. La restauration restaure l’ancien parseur, pas la correction.

Correctif : Mettez à jour la config pour qu’elle corresponde à la version actuelle, ou gérez explicitement la config versionnée. Utilisez journalctl pour identifier la ligne et la directive exactes. La restauration n’est qu’une mesure de confinement temporaire.

4) « Symbol lookup error »

Symptômes : exécutables échouent avec des erreurs de symboles non définis dans les bibliothèques partagées.

Cause : Incompatibilité ABI entre le binaire et la version de la bibliothèque ; fréquent avec des binaires compilés localement ou des agents fournis par des éditeurs.

Correctif : Préférez recompiler/réinstaller le binaire pour la nouvelle bibliothèque. Si vous devez rétrograder une bibliothèque, vérifiez les reverse-deps et évitez de rétrograder les outils de sécurité cœur.

5) « La rétrogradation a réussi, mais la prochaine mise à niveau le re-casse »

Symptômes : Tout fonctionne après la rétrogradation, puis les mises à jour non surveillées ramènent la mauvaise version.

Cause : Aucun hold ou pin appliqué ; APT considère toujours la version plus récente comme candidate.

Correctif : Utilisez apt-mark hold pour la contention immédiate, puis implémentez le pinning avec /etc/apt/preferences.d/ pour un contrôle plus long.

6) « dpkg verrouillé, mises à jour bloquées »

Symptômes : APT indique qu’un verrou est détenu ; les opérations échouent.

Cause : Un autre processus apt/dpkg tourne (unattended-upgrades, apt-daily), ou un processus précédent a planté en laissant un verrou mais l’état dpkg est le vrai problème.

Correctif : Vérifiez les processus en cours, ne supprimez pas simplement les fichiers de verrou. Arrêtez les timers si nécessaire, puis réparez l’état de dpkg.

Checklists / plan étape par étape

Checklist A: Contenir l’incident (5–15 minutes)

  1. Confirmez ce qui est cassé (service en panne ? erreur binaire ? sortie incorrecte ?).
  2. Vérifiez l’état de dpkg (dpkg --audit). Réparez si nécessaire.
  3. Identifiez ce qui a changé (apt history, tail du log dpkg).
  4. Décidez si une restauration est appropriée (problème de config vs ABI vs vraie régression).
  5. Simulez la rétrogradation pour mesurer le rayon d’impact (apt-get -s install pkg=ver).

Checklist B: Restaurer un paquet sans dommages collatéraux

  1. Listez les versions disponibles : apt list -a package.
  2. Vérifiez les dépendances : apt-cache show package.
  3. Vérifiez les reverse-deps : apt-cache rdepends --installed package.
  4. Simulez la rétrogradation avec des versions explicites pour tous les paquets fortement couplés (souvent -common, -data).
  5. Exécutez la rétrogradation avec des versions explicites.
  6. Mettez en hold ou pinner immédiatement.
  7. Vérifiez le service et les logs.

Checklist C: Prévenir la prochaine chute en domino

  1. Supprimez les suites mixtes sauf si vous avez une politique explicite pour elles.
  2. Utilisez des mises à jour canaries et des smoke tests reflétant les charges réelles.
  3. Faites des snapshots avant les mises à jour (VM, LVM, btrfs, ZFS — ce que vous avez).
  4. Tracez les pins et holds comme mesures temporaires avec propriétaires et dates d’expiration.

FAQ

1) Puis-je rétrograder un paquet avec dpkg directement ?

Vous le pouvez, mais en général vous ne devriez pas. Dpkg ne résout pas les dépendances. Si vous installez un ancien .deb qui entre en conflit avec des dépendances installées, vous créerez un état système cassé que APT devra alors démêler. Préférez apt-get install pkg=version pour que la résolution des dépendances reste cohérente.

2) Pourquoi APT veut-il rétrograder plein d’autres paquets ?

Parce que la version demandée change les contraintes de dépendances. Si l’ancienne version exige des bibliothèques plus anciennes ou est en conflit avec des versions plus récentes, APT tente de trouver un ensemble cohérent. Le solveur fait son travail ; vous lui demandez de résoudre un problème plus difficile que prévu. C’est votre signal pour simuler, inspecter et éventuellement changer de stratégie.

3) Quelle est la différence entre un hold et un pin ?

Un hold bloque les changements d’un paquet (mise à niveau/rétrogradation) sauf si vous le libérez explicitement. Le pin influence la sélection de la candidate et peut être aussi chirurgical ou dangereux que vous le rendez. Les holds sont parfaits pour la contention rapide ; les pins servent la politique.

4) Comment voir si un paquet est en hold ?

cr0x@server:~$ apt-mark showhold
nginx
nginx-common

Si un paquet que vous devez déplacer est en hold, ce hold peut être la raison pour laquelle APT indique « held broken packages ». Débloquez avec délibération, pas impulsivement.

5) Et si l’ancienne version n’est plus dans mes dépôts ?

Vérifiez d’abord /var/cache/apt/archives. Si elle n’y est pas, vous avez besoin d’un dépôt qui fournit la version (par exemple un miroir interne contrôlé ou un service de snapshot). Évitez les .debs aléatoires depuis Internet ; la chaîne d’intégrité et la clôture de dépendances comptent.

6) Est-ce sûr de restaurer des bibliothèques comme libssl ou libc ?

Parfois, mais rarement le meilleur choix initial. Ces bibliothèques ont de larges dépendances et sont sensibles côté sécurité. Si une seule app casse à cause d’une mise à jour de bibliothèque, préférez recompiler l’app ou l’isoler (conteneur, chroot) plutôt que de rétrograder la crypto système ou libc.

7) Comment savoir quel paquet fournit un .so défaillant ?

Utilisez dpkg -S /path/to/file. Cela mappe un fichier au paquet propriétaire. Ensuite vous pouvez inspecter les versions et décider si le paquet de bibliothèque est votre vraie cible de restauration.

8) Et si l’échec est dû à un changement de config et non au binaire ?

Alors la restauration est une béquille temporaire. Corrigez la config pour qu’elle soit compatible avec la nouvelle version du paquet. Utilisez journalctl -u service pour la directive/ligne exacte. Vérifiez aussi les nouveaux configs par défaut dans /usr/share/doc ou les fichiers de conffile dans /etc que vous avez peut-être ignorés lors de la mise à jour.

9) Dois-je utiliser apt ou apt-get pendant les incidents ?

J’utilise apt-get pour le travail d’incident parce que son interface est stable et prévisible, surtout pour les simulations (-s) et la reproductibilité scriptée. apt est bien, mais la convivialité n’est pas la même chose que le contrôle.

10) Comment auditer ce qu’APT a changé la nuit dernière ?

Utilisez /var/log/apt/history.log et /var/log/dpkg.log. Ils vous disent ce qu’APT a planifié et ce que dpkg a réellement fait. Si ces deux fichiers sont en désaccord, c’est un indice (interruption, échecs de scripts mainteneur, ou intervention manuelle).

Conclusion : prochaines étapes à faire aujourd’hui

Rétrograder un seul paquet sur Debian 13 sans effondrement de dépendances n’est pas de la magie noire. C’est de la politique, de la simulation et de la retenue. Votre playbook :

  1. Rendez dpkg propre avant de toucher à quoi que ce soit d’autre.
  2. Prouvez ce qui a changé via les logs, pas via la mémoire.
  3. Simulez la rétrogradation et refusez les grands rayons d’impact.
  4. Rétrogradez avec des versions explicites pour les paquets fortement couplés.
  5. Mettez en hold/pinez immédiatement, puis vérifiez avec des tests de charge réels.
  6. Après l’incendie, retirez les dépôts mixtes ad hoc et adoptez snapshots + canaris.

Une citation à garder collée sur votre écran, car elle est aussi vraie dans le packaging que partout ailleurs : Hope is not a strategy. — Edsger W. Dijkstra

Si vous ne faites rien d’autre : commencez à prendre des snapshots avant les mises à jour et faites toujours des simulations de rétrogradation. Cela seul vous évitera le prochain « APT a proposé de supprimer mon agent de monitoring », qui est une forme moderne unique d’aveuglement auto-infligé.

← Précédent
E-mail : Déferlante de spam entrants — survivre à l’attaque sans bloquer les vrais utilisateurs
Suivant →
Verr Maj et rage des mots de passe : la plus petite touche au plus grand chaos

Laisser un commentaire