Debian 13 : Rotation des clés SSH — révoquer l’accès proprement et éviter la prolifération des clés (cas n°73)

Cet article vous a aidé ?

Vous avez fait tourner les clés SSH. Tout le monde a hoché la tête. Les tickets sont fermés. Puis un prestataire qui « n’a définitivement plus d’accès » se connecte encore depuis une IP de café que vous n’avez jamais vue.
C’est ainsi que la rotation échoue dans le monde réel : pas au niveau de la cryptographie, mais au niveau humain — copier/coller, dérive, bastions oubliés, et cette machine héritée sous un bureau qui « ne peut pas être redémarrée ».

Debian 13 facilite l’exécution d’une pile OpenSSH saine. La partie difficile est de révoquer l’accès proprement et d’en apporter la preuve. Ce dossier est un playbook de production :
comment inventorier où résident les clés, faire la rotation sans interruption, révoquer précisément et empêcher la prolifération des clés de repousser comme des mauvaises herbes sur un parking abandonné.

Décider ce que vous entendez par « révoqué »

« Nous avons tourné les clés SSH » est une phrase qui peut signifier trois choses différentes, et une seule d’entre elles est opérationnellement satisfaisante.

  • Remplacement de clé : vous avez émis de nouvelles clés et demandé aux gens de les utiliser. Les anciennes clés peuvent encore fonctionner. Ce n’est pas une révocation ; c’est une suggestion polie.
  • Suppression de clé : vous avez enlevé les anciennes clés publiques de authorized_keys (et de partout où elles pouvaient authentifier). C’est une révocation,
    mais seulement pour les chemins dont vous vous êtes souvenu.
  • Invalidation d’accès : vous avez supprimé/bloqué les clés, tué les sessions survivantes si nécessaire, audité les chemins alternatifs (bastions, comptes partagés,
    agent forwarding, jump hosts), et vous pouvez prouver que les anciennes clés n’authentifient plus. C’est ce que vous visez.

Sur Debian 13, OpenSSH est capable, terne et strict si vous le laissez l’être. Profitez-en. Votre ennemi n’est pas la mathématique. Votre ennemi est
la prolifération des clés : la réplication graduelle et invisible des clés dans des endroits aléatoires parce que la façon la plus rapide de « réparer l’accès » est d’ajouter une autre ligne
dans un autre authorized_keys.

Un modèle mental utile : traitez les clés SSH comme des identifiants avec cycle de vie, pas comme des « fichiers que les développeurs gardent dans leur répertoire personnel ».
Cycle de vie signifie inventaire, émission, rotation, expiration, révocation et revue. Si l’un de ces éléments manque, vous n’avez pas un système ; vous avez du folklore.

Une citation que je garde sur un post-it, parce que c’est le boulot :
L’espoir n’est pas une stratégie.
— Gen. Gordon R. Sullivan

Blague #1 : les clés SSH ne « expirent » pas toutes seules. Elles sont comme les avocats : si vous ne les surveillez pas, elles restent soit crues pour toujours, soit deviennent soudainement un incident de sécurité.

Faits intéressants & historique (pourquoi le bazar existe aujourd’hui)

Un peu de contexte aide à diagnostiquer pourquoi votre parc ressemble à s’y méprendre à s’être fait gérer par un comité de ratons laveurs.
Voici des faits concrets qui ont tendance à compter lors du nettoyage post-rotation.

  1. SSH1 vs SSH2 : SSH2 a remplacé SSH1 au début des années 2000 parce que SSH1 présentait des faiblesses de sécurité. « SSH » aujourd’hui signifie pratiquement SSH2, mais des hypothèses héritées persistent dans d’anciens scripts et appliances.
  2. Les clés DSA ont été dépréciées : ssh-dss (DSA) est tombé en désuétude et est désactivé par défaut dans les OpenSSH modernes à cause des contraintes d’algorithme et de politique. Si vous voyez encore des clés DSA dans authorized_keys, vous regardez des couches archéologiques.
  3. Ed25519 est devenu la recommandation par défaut : les clés Ed25519 sont compactes, rapides et généralement préférées aux RSA dans de nombreux environnements. Les projets de rotation combinent souvent mise à niveau d’algorithme et rotation.
  4. authorized_keys a été conçu pour la simplicité : C’est juste un fichier avec des lignes. Cette simplicité rend la prolifération des clés si facile : les outils de distribution sont optionnels, le copier/coller est toujours disponible.
  5. Les certificats existent, mais la plupart des organisations ne les utilisent pas : OpenSSH prend en charge les certificats utilisateur signés par une CA, ce qui réduit drastiquement la prolifération, mais cela demande un peu de réflexion en amont. Beaucoup d’équipes repoussent cette réflexion indéfiniment.
  6. La révocation n’est pas symétrique : Avec des clés publiques brutes, vous révoquez en les supprimant partout. Avec des certificats, vous pouvez révoquer par numéro de série ou ID de clé via une liste de révocation, mais il vous faut l’infrastructure CA.
  7. Agent forwarding a popularisé le « juste passer par le bastion » : Il a aussi rendu les frontières d’identifiants floues. Quand la révocation échoue, l’agent forwarding est souvent incriminé.
  8. StrictModes existe pour une raison : SSH refuse d’utiliser des fichiers de clés aux permissions non sécurisées parce qu’il essaie de vous protéger de vous-même. Quand des gens « règlent » les erreurs de permission en désactivant les vérifications, ils créent généralement une surface d’impact plus large.
  9. Les logs SSH sont utiles mais pas conviviaux : OpenSSH enregistre ce qui s’est passé, pas ce que vous ressentez à ce sujet. Les récupérations d’incident les plus rapides viennent d’équipes qui savent exactement quelles lignes de log correspondent à quels chemins d’authentification.

Playbook de diagnostic rapide

Quand quelqu’un dit « l’ancienne clé fonctionne encore » ou « la nouvelle clé ne fonctionne pas », ne commencez pas à éditer les fichiers à l’aveugle.
Trouvez le goulot d’étranglement en trois vérifications.

1) Identifier où la décision d’authentification est prise

L’utilisateur s’authentifie-t-il directement sur la cible, via un bastion, via un wrapper de commande forcée, ou via un compte géré par la gestion de configuration ?
Si vous vous trompez ici, vous « révoquerez » au mauvais endroit et rien ne changera.

2) Confirmer quelle clé est réellement proposée

Le client SSH proposera volontiers une petite parade de clés à moins que vous ne lui disiez le contraire. Les gens croient souvent tester la nouvelle clé alors que leur agent
propose d’abord une ancienne clé et que celle-ci réussit.

3) Valider la source côté serveur

Sur Debian 13, les clés peuvent provenir de ~/.ssh/authorized_keys, mais aussi des chemins AuthorizedKeysFile, ou de AuthorizedKeysCommand (LDAP/HTTP/quelque chose), ou d’un authorized_keys d’un compte partagé que vous aviez oublié.

Ce n’est qu’après avoir verrouillé ces trois éléments que vous commencez à supprimer des lignes, déployer des changements de configuration et terminer des sessions.

Tâches pratiques (commandes, sorties, décisions)

Ci‑dessous des tâches de production que vous pouvez exécuter sur Debian 13 (ou sur votre poste d’administration) qui vous font passer de « nous avons tourné les clés » à « nous avons révoqué l’accès et l’avons prouvé ».
Chaque tâche inclut : une commande, ce qu’une sortie typique signifie, et la décision suivante.

Tâche 1 — Vérifier la version du serveur OpenSSH (savoir quelles fonctionnalités vous avez)

cr0x@server:~$ sshd -V
OpenSSH_9.7p1 Debian-3, OpenSSL 3.3.1 4 Jun 2024

Signification : Vous êtes sur un OpenSSH moderne avec de bons paramètres par défaut et le support des certificats.
Décision : Préférez les clés Ed25519 ou les certificats utilisateur OpenSSH ; évitez de vous accrocher aux algorithmes hérités « pour compatibilité » sans preuve.

Tâche 2 — Lister les écouteurs SSH actifs (éviter de révoquer le mauvais démon)

cr0x@server:~$ ss -ltnp | grep ssh
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=812,fd=3))
LISTEN 0      128             [::]:22           [::]:*    users:(("sshd",pid=812,fd=4))

Signification : sshd écoute sur le port 22 en IPv4 et IPv6.
Décision : Si vous attendiez un port bastion (par ex. 2222) ou seulement IPv4, conciliez cela maintenant. « Révoquer sur le port 22 » n’aidera pas si les utilisateurs se connectent ailleurs.

Tâche 3 — Confirmer les sources d’authentification de sshd (AuthorizedKeysFile / Command)

cr0x@server:~$ sshd -T | egrep 'authorizedkeys(file|command)|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication'
pubkeyauthentication yes
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2
authorizedkeyscommand none
passwordauthentication no
kbdinteractiveauthentication no

Signification : Les clés proviennent des fichiers locaux dans les répertoires personnels ; aucune commande de clés externe n’est utilisée.
Décision : La révocation implique d’éditer ces fichiers (ou de les remplacer via la gestion de config). Si AuthorizedKeysCommand est configuré, la révocation est centralisée et vous devez corriger la source.

Tâche 4 — Inventorier les utilisateurs locaux avec répertoires personnels (trouver où les clés peuvent exister)

cr0x@server:~$ getent passwd | awk -F: '$6 ~ /^\/home\// {print $1 "\t" $6}'
alice	/home/alice
buildbot	/home/buildbot
deploy	/home/deploy

Signification : Ces utilisateurs ont probablement des répertoires ~/.ssh.
Décision : Délimitez l’audit de clés. N’oubliez pas les comptes de service comme deploy — ce sont souvent des endroits où les « clés temporaires » vivent pour toujours.

Tâche 5 — Trouver chaque authorized_keys sur l’hôte (y compris les chemins bizarres)

cr0x@server:~$ sudo find / -xdev -type f -name 'authorized_keys' -o -name 'authorized_keys2' 2>/dev/null
/home/alice/.ssh/authorized_keys
/home/deploy/.ssh/authorized_keys
/root/.ssh/authorized_keys

Signification : Trois points d’entrée de clés existent localement.
Décision : Si vous révoquez un prestataire, vérifiez-les tous. Root est souvent oublié et souvent abusé.

Tâche 6 — Compter les clés et repérer la dérive évidente (les commentaires comptent)

cr0x@server:~$ sudo awk 'NF && $1 !~ /^#/ {print FILENAME ":" NR ":" $0}' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys | head -n 6
/home/alice/.ssh/authorized_keys:1:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... alice@laptop
/home/alice/.ssh/authorized_keys:2:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... old-admin
/home/deploy/.ssh/authorized_keys:1:command="/usr/local/bin/deploy-wrap" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... ci@runner
/root/.ssh/authorized_keys:1:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... breakglass@vault

Signification : Vous avez des algorithmes mixtes et au moins une clé « old-admin ». Vous avez aussi une clé avec commande forcée pour deploy.
Décision : Traitez toute ligne sans commentaire utile comme suspecte et exigez une réémission. Pour les clés deploy, vérifiez que la commande forcée fait bien ce que vous pensez.

Tâche 7 — Empreinter une clé publique connue compromise (pour la rechercher fiablement)

cr0x@server:~$ ssh-keygen -lf /tmp/contractor_id_ed25519.pub
256 SHA256:Wm3xNq7nq0M9m+eOQmR0f0sY0p+9QH8Zq4xkYw1o9X8 contractor@mbp (ED25519)

Signification : C’est l’empreinte stable que vous pouvez grepper quand les commentaires mentent.
Décision : Utilisez les empreintes comme identifiant canonique dans les tickets et audits. Les commentaires sont des indices, pas une identité.

Tâche 8 — Rechercher l’empreinte dans tous les authorized_keys (trouver la prolifération)

cr0x@server:~$ sudo grep -R --line-number --fixed-strings 'AAAAC3NzaC1lZDI1NTE5AAAAI' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys
/home/alice/.ssh/authorized_keys:7:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... contractor@mbp
/root/.ssh/authorized_keys:4:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... contractor@mbp

Signification : La clé existe à plusieurs endroits (y compris root).
Décision : Révoquez dans tous les emplacements, et ouvrez un incident de suivi : « Pourquoi une clé prestataire s’est-elle retrouvée dans le authorized_keys de root ? »

Tâche 9 — Supprimer la clé en toute sécurité (édition chirurgicale, garder la trace)

cr0x@server:~$ sudo cp -a /root/.ssh/authorized_keys /root/.ssh/authorized_keys.bak.$(date +%F)
cr0x@server:~$ sudo sed -i '\#contractor@mbp#d' /root/.ssh/authorized_keys
cr0x@server:~$ sudo ssh-keygen -lf /root/.ssh/authorized_keys | head -n 3
256 SHA256:... breakglass@vault (ED25519)

Signification : Vous avez pris une sauvegarde, supprimé la ligne du prestataire en faisant correspondre le commentaire, et vérifié que les entrées restantes se parsèrent.
Décision : Si les commentaires ne sont pas fiables, supprimez en faisant correspondre le blob de clé. Conservez toujours une sauvegarde datée pour la forensique et le rollback.

Tâche 10 — Recharger sshd (ne redémarrez pas si vous pouvez l’éviter)

cr0x@server:~$ sudo systemctl reload ssh
cr0x@server:~$ systemctl is-active ssh
active

Signification : La config et les fichiers de clés sont effectifs ; sshd est resté en ligne.
Décision : Préférez reload plutôt que restart pour éviter de couper des connexions sur des bastions chargés — sauf si vous avez changé quelque chose qui nécessite un redémarrage (rare).

Tâche 11 — Prouver que l’ancienne clé est rejetée (preuve côté serveur dans les logs)

cr0x@server:~$ sudo journalctl -u ssh -S "10 minutes ago" | tail -n 6
Dec 31 09:12:41 server sshd[22418]: Connection from 203.0.113.44 port 51221 on 10.0.0.10 port 22 rdomain ""
Dec 31 09:12:41 server sshd[22418]: Failed publickey for alice from 203.0.113.44 port 51221 ssh2: ED25519 SHA256:Wm3xNq7nq0M9m+eOQmR0f0sY0p+9QH8Zq4xkYw1o9X8
Dec 31 09:12:43 server sshd[22418]: Connection closed by authenticating user alice 203.0.113.44 port 51221 [preauth]

Signification : L’empreinte exacte a échoué. C’est votre preuve.
Décision : Marquez la clé comme révoquée pour cet hôte. Répétez sur d’autres hôtes, ou — mieux — automatisez les recherches sur le parc pour ne pas « faire confiance à un échantillonnage ».

Tâche 12 — Confirmer quelle clé le client propose (arrêter de tester la mauvaise chose)

cr0x@server:~$ ssh -vvv -i ~/.ssh/id_ed25519_new alice@server 2>&1 | egrep 'Offering public key|Server accepts key|Authentications that can continue'
debug1: Offering public key: /home/alice/.ssh/id_ed25519_new ED25519 SHA256:9aZkNf...
debug1: Authentications that can continue: publickey
debug1: Server accepts key: /home/alice/.ssh/id_ed25519_new ED25519 SHA256:9aZkNf...
debug1: Authentication succeeded (publickey).

Signification : La nouvelle clé est utilisée et acceptée.
Décision : Si cela échoue encore, le problème est probablement côté serveur (restrictions command=, from=, principals, permissions) ou vous touchez un hôte/chemin différent.

Tâche 13 — Lister les sessions SSH actives (la révocation n’annule pas les shells existants)

cr0x@server:~$ who
alice    pts/1        2025-12-31 09:03 (203.0.113.44)
deploy   pts/2        2025-12-31 08:50 (10.0.2.15)

Signification : Des utilisateurs ont déjà des sessions actives authentifiées.
Décision : Si la clé a été compromise, vous devrez probablement terminer les sessions. Si c’est une rotation de routine, vous pouvez laisser les sessions se terminer naturellement pour éviter la disruption.

Tâche 14 — Terminer une session compromise (en toute sécurité, avec intention)

cr0x@server:~$ ps -ft pts/1
UID        PID  PPID  C STIME TTY          TIME CMD
alice    22391 22388  0 09:03 pts/1    00:00:00 -bash
cr0x@server:~$ sudo kill -HUP 22391
cr0x@server:~$ ps -p 22391
  PID TTY          TIME CMD

Signification : Le shell est sorti et la session a disparu.
Décision : Utilisez des kills ciblés, pas « redémarrer ssh ». Redémarrer le démon ne tue pas nécessairement les sessions et crée des dommages collatéraux.

Tâche 15 — Valider les permissions des fichiers (éviter le « ça marche sur un hôte » pour rien)

cr0x@server:~$ sudo namei -l /home/alice/.ssh/authorized_keys
f: /home/alice/.ssh/authorized_keys
drwxr-xr-x root  root  /
drwxr-xr-x root  root  home
drwxr-x--- alice alice alice
drwx------ alice alice .ssh
-rw------- alice alice authorized_keys

Signification : Les permissions sont suffisamment strictes ; sshd devrait accepter le fichier.
Décision : Si vous voyez des répertoires ou fichiers écrits pour le groupe/le monde, corrigez-les au lieu de désactiver StrictModes.

Tâche 16 — Détecter la réutilisation de clés entre comptes (une clé, plusieurs portes)

cr0x@server:~$ sudo awk 'NF && $1 !~ /^#/ {print $2}' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys | sort | uniq -c | sort -nr | head
      2 AAAAC3NzaC1lZDI1NTE5AAAAI... 
      1 AAAAB3NzaC1yc2EAAAADAQABAAABAQ...

Signification : Un même blob de clé apparaît plusieurs fois sur le système.
Décision : Interdisez la réutilisation de clés entre comptes. Cela détruit l’attribution et rend la révocation plus difficile qu’il ne le faut.

Tâche 17 — Vérifier l’usage d’agent forwarding (cela change le modèle de menace)

cr0x@server:~$ sudo grep -R --line-number 'ForwardAgent' /etc/ssh/ssh_config /etc/ssh/ssh_config.d 2>/dev/null
/etc/ssh/ssh_config.d/20-bastion.conf:3:    ForwardAgent yes

Signification : L’agent forwarding est activé pour quelque chose (probablement des sauts via bastion).
Décision : Si vous révoquez pour cause de compromission, considérez les chemins d’agent forwarding comme suspects. Envisagez de le désactiver et d’utiliser des certificats ou des patterns ProxyJump.

Tâche 18 — Valider la config sshd avant déploiement (prévenir les auto-exclusions)

cr0x@server:~$ sudo sshd -t
cr0x@server:~$ echo $?
0

Signification : La syntaxe de la config est valide.
Décision : Ne jamais recharger sshd sans sshd -t dans l’automatisation. La seule chose pire que la prolifération de clés est de verrouiller l’astreinte hors du système.

Stratégies de révocation qui fonctionnent réellement

Stratégie A : Clés publiques brutes dans authorized_keys (la réalité par défaut)

C’est le monde dans lequel la plupart des équipes vivent : des fichiers authorized_keys par utilisateur disséminés sur les hôtes.
La révocation ici est tranchante : supprimez la clé partout où elle apparaît, y compris les comptes partagés et root (si vous l’autorisez).
Le travail n’est pas « supprimer une ligne ». Le travail est « supprimer toutes les portes que cette ligne ouvre ».

Si vous utilisez des clés brutes, appliquez ces politiques :

  • Une personne → un couple de clés par appareil (ordinateur portable, poste de travail, runner CI). Pas de clés partagées. Pas de « clé d’équipe ».
  • Chaque ligne de clé doit être traçable : le commentaire inclut le propriétaire et l’usage, et vous suivez l’empreinte dans votre IAM ou système de ticketing.
  • Chaque clé a un propriétaire et une date de revue. Si vous ne pouvez pas nommer le propriétaire, vous ne pouvez pas justifier le risque.
  • Pas d’éditions manuelles sur les machines importantes : si un hôte est critique, les clés sont gérées par la gestion de configuration (ou une commande de clés centralisée).

La partie délicate est la dérive : clés copiées là où vous ne prévoyez pas, clés laissées après départs, et clés
intégrées dans des images/AMIs/conteneurs. C’est pourquoi l’inventaire doit être répétable.

Stratégie B : Centraliser les clés avec AuthorizedKeysCommand (bon pour les grands parcs)

Avec AuthorizedKeysCommand, sshd exécute une commande pour récupérer les clés au moment de la connexion. Cette commande peut interroger LDAP, un cache local,
un gestionnaire de secrets, ou un simple fichier généré depuis votre source de vérité.

Avantage opérationnel : La révocation est immédiate et centralisée. Fini le « avons‑nous mis à jour cette machine ? ».

Inconvénient opérationnel : Vous avez introduit une dépendance dans le chemin d’authentification. Si elle est lente, indisponible ou mal configurée, personne ne se connecte.

Si vous choisissez cette voie, traitez-la comme un service de production :

  • Mettez en cache les résultats localement avec TTL ; protégez les permissions du cache.
  • Ayez un chemin de secours statique d’urgence (clé break-glass dans root, avec contrôles stricts).
  • Instrumentez et alertez sur les échecs de commande et la latence.
  • Limitez le débit et renforcez le parsing d’entrée. sshd exécutera votre commande fréquemment.

Stratégie C : Passer aux certificats utilisateur OpenSSH (l’option anti‑prolifération)

Les certificats sont la façon d’arrêter la prolifération des clés au lieu de la tondre constamment.
Les utilisateurs conservent une clé privée, mais ils s’authentifient avec un certificat à courte durée signé par votre CA SSH.
Les serveurs font confiance à la CA, pas à chaque clé publique individuelle.

Ce qui change :

  • Sur les serveurs : vous déployez la clé publique de la CA une fois (ou rarement). C’est l’ancre de confiance.
  • Sur les clients : les utilisateurs obtiennent un certificat (idéalement de courte durée) depuis un service de signature après SSO/MFA.
  • Révocation : vous pouvez révoquer en arrêtant l’émission, en rendant les certificats courts, et (si besoin) en utilisant des listes de révocation pour des certificats spécifiques.

Opinion : Si vous avez plus que quelques serveurs, et que vous faites des rotations de clés plus d’une fois par an, les certificats rentabilisent rapidement.
Ils transforment la révocation de « chasser des lignes » en « arrêter d’émettre ; attendre le TTL ».

Renforcement sshd sur Debian 13 après rotation

Les projets de rotation sont une opportunité : vous touchez sshd de toute façon, donc corrigez les problèmes structurels qui ont rendu la prolifération possible.
L’objectif n’est pas la « paranoïa maximale ». L’objectif est un contrôle d’accès prévisible.

Rendre les chemins d’authentification explicites

Si vous avez effectué une rotation à cause d’une compromission ou d’une politique, envisagez d’appliquer cette politique dans sshd pour éviter une régression silencieuse.
Par exemple, désactivez l’authentification par mot de passe et keyboard-interactive si vous ne les utilisez vraiment pas ; autrement, les attaquants emprunteront simplement l’autre porte.
Vous avez déjà vu dans la Tâche 3 comment vérifier.

Arrêter de laisser des comptes aléatoires devenir des points d’entrée

Le moyen le plus rapide de finir en enfer de prolifération de clés est d’autoriser beaucoup de comptes à accepter des clés arbitraires.
Préférez moins de comptes de connexion, et utilisez sudo avec une politique stricte pour les privilèges. Encore mieux, utilisez des comptes par personne et évitez complètement les comptes partagés.
Quand vous ne pouvez pas éviter un compte partagé (runners CI, utilisateurs deploy), isolez‑le :

  • Forcer une commande pour les clés CI (comme dans la Tâche 6).
  • Restreindre les IP sources avec from="10.0.2.15" dans authorized_keys.
  • Désactiver PTY, le port forwarding et le forwarding X11 pour les accès non humains.

Utiliser des blocs Match pour les bastions et utilisateurs spéciaux

Ne « configurez pas globalement » en espérant que ça marche. Les bastions sont différents. Les utilisateurs CI sont différents. Root est différent.
OpenSSH de Debian prend en charge des règles Match granulaires. Elles restent lisibles lorsque vous les gardez courtes.

Le break-glass n’est pas optionnel ; il est contrôlé

Vous avez besoin d’un moyen d’accès lorsque votre service de clés ou votre déploiement de config casse. Mais le break-glass doit être :
rarement utilisé, fortement journalisé, et rapidement tourné.
Une clé d’urgence soigneusement stockée vaut mieux que cinq clés « au cas où » dispersées partout.

Blague #2 : Une « clé SSH temporaire » est la chose la plus permanente en informatique — jusqu’à ce que les auditeurs arrivent et que ça devienne soudainement « un malentendu ».

Trois micro-histoires d’entreprise (toutes assez réelles pour faire mal)

Incident causé par une fausse hypothèse : « Nous avons supprimé la clé, donc elle ne peut plus se connecter »

Une entreprise SaaS de taille moyenne a tourné les clés SSH après le vol d’un ordinateur portable. L’équipe a fait le travail évident : supprimer la clé publique compromise de
authorized_keys de l’ingénieur sur la production. Ils ont utilisé la gestion de configuration, les changements ont été déployés et le ticket d’incident a été clos.

Deux jours plus tard, une connexion suspecte a touché un hôte de base de données. Les logs montraient clairement une authentification par clé publique avec l’ancienne empreinte.
La panique a suivi, comme toujours, et la première vague de réponses a été prévisible : redémarrer sshd, tourner à nouveau les clés, et bloquer l’IP.
La connexion continuait depuis de nouvelles IPs.

Le vrai problème était petit et humiliant : l’hôte de base de données n’utilisait pas du tout des clés par utilisateur. On y accédait via un compte partagé hérité appelé dbmaint
qui vivait hors de la gestion de config parce qu’il avait été créé « pour un prestataire, il y a des années ».
Ce compte possédait son propre authorized_keys, et la clé compromise s’y trouvait aussi.

L’hypothèse erronée était que « supprimer la clé de l’utilisateur » équivalait à « supprimer la clé du système ».
Les clés se moquent des organigrammes. Elles regardent les fichiers et les chemins de confiance.

La correction n’a rien d’héroïque : inventorier chaque authorized_keys sur chaque hôte, supprimer l’empreinte à l’échelle du parc, puis supprimer le
compte partagé totalement. Le meilleur ? Après le nettoyage, les futures révocations sont devenues ennuyeuses, parce qu’ils disposaient d’une liste complète des endroits où les clés peuvent exister.

Optimisation qui s’est retournée contre eux : « On accélère l’onboarding en copiant les clés partout »

Une grande équipe plateforme avait un problème d’onboarding : les nouveaux ingénieurs avaient besoin d’accès à des dizaines d’hôtes, et les validations prenaient du temps.
Quelqu’un a proposé une « optimisation simple » : un script qui ajoute la clé publique d’un nouvel arrivant au modèle /etc/skel de chaque serveur
et à quelques comptes de service communs, pour que l’accès « fonctionne tout simplement ».

À court terme, ça a marché. Le temps d’onboarding a diminué. Moins de tickets. Tout le monde a félicité le script.
Puis est venu le premier offboarding d’une ingénieure senior qui était partie en mauvais termes.
Ils ont tourné ses clés. Ils ont retiré sa clé des endroits évidents. Elle avait toujours accès.

Le script avait créé de la prolifération plus vite que n’importe quel humain. Les clés se trouvaient dans des profils utilisateurs créés depuis /etc/skel, dans des comptes partagés,
et dans quelques comptes « aide ops » créés au fil des années. Personne ne connaissait l’ensemble. Personne n’avait voulu créer un IAM parallèle.
Et pourtant c’est ce qu’ils avaient fait.

Le retour de bâton a été un coût opérationnel : la révocation a nécessité une recherche forensique à l’échelle du parc, et cela a dû être répété pour chaque départ.
Ils ont fini par remplacer le script par un vrai processus d’intégration : distribution clé centralisée, comptes de connexion limités, et migration vers des certificats courts.

La leçon : optimiser la vitesse d’onboarding en dupliquant des identifiants, c’est comme optimiser pour des incendies plus rapides en stockant de l’essence dans les couloirs.
C’est super jusqu’au moment où vous devez arrêter quelque chose rapidement.

Pratique ennuyeuse mais correcte qui a sauvé la mise : « Nous pouvons prouver qui peut se connecter »

Une équipe infra fintech gérait des hôtes Debian avec une règle stricte : aucune modification manuelle de authorized_keys en production. Les clés étaient déployées
depuis un dépôt Git via la gestion de configuration. Chaque ligne de clé contenait un propriétaire, un usage et une date de revue dans le commentaire.
Ils enregistraient aussi les empreintes dans la demande d’accès.

Un après-midi, une alerte s’est déclenchée : tentatives SSH répétées échouées suivies d’une connexion réussie sur un bastion. La connexion réussie utilisait une empreinte
qui n’était pas dans leur dépôt. Cela n’aurait pas dû arriver.

Voici où la discipline ennuyeuse paye : ils n’ont pas hésité. Ils ont lancé une recherche sur tout le parc pour cette empreinte. Elle n’apparaissait que sur le bastion,
ajoutée manuellement dans l’heure qui venait de s’écouler. L’horodatage du fichier et les logs d’audit correspondaient à une erreur humaine : quelqu’un avait collé une clé de prestataire pendant un appel de support.

Ils ont retiré la clé, rechargé sshd, tué la session, puis comparé le authorized_keys du bastion avec la version gérée par le dépôt.
Le delta était exactement une ligne. Ils ont restauré le fichier depuis la gestion de config, ouvert un incident de processus et renforcé le workflow de support.

Pas de forensique dramatique. Pas de projet d’audit de clés d’une semaine. Juste une containment rapide parce que le système avait une source de vérité et une règle contre les changements ad hoc.

Erreurs courantes (symptôme → cause racine → correction)

1) « L’ancienne clé fonctionne encore » après la rotation

Symptôme : Une clé révoquée continue d’authentifier sur certains hôtes.

Cause racine : La clé existe dans plusieurs comptes ou sources de clés (comptes partagés, root, chemins alternatifs AuthorizedKeysFile, bastions).

Correction : Empreintez la clé et recherchez-la à l’échelle du parc dans tous les emplacements authorized_keys (et toute source centralisée). Supprimez partout. Vérifiez dans les logs.

2) « La nouvelle clé échoue, mais elle marche sur un autre serveur »

Symptôme : Même utilisateur, même clé, résultat différent selon l’hôte.

Cause racine : Problèmes de permissions (StrictModes), config sshd différente, chemin du home utilisateur différent, ou ligne de clé avec des restrictions (from=, command=) qui ne correspondent pas.

Correction : Lancez sshd -T sur l’hôte qui échoue, vérifiez les permissions avec namei -l, et contrôlez les restrictions dans la ligne authorized_keys.

3) « Nous avons supprimé la clé mais la session est restée active »

Symptôme : L’utilisateur reste connecté et peut continuer à agir.

Cause racine : Les vérifications de clé SSH ont lieu au moment de l’authentification ; supprimer des clés n’annule pas rétroactivement les sessions existantes.

Correction : Identifiez les sessions avec who / ss / ps et terminez-les sélectivement si nécessaire.

4) « Nous nous sommes verrouillés dehors »

Symptôme : Après reload/restart, personne ne peut se connecter.

Cause racine : Mauvaise config sshd, chemin AuthorizedKeysFile erroné, permissions cassées, ou désactivation trop zélée de méthodes d’auth sans clé testée.

Correction : Lancez toujours sshd -t avant reload, gardez un accès console d’urgence, et déployez les changements progressivement avec vérification.

5) « Le prestataire est offboardé, mais le CI échoue »

Symptôme : Après nettoyage des clés, les jobs automatisés ne peuvent plus déployer.

Cause racine : Le CI utilisait la clé personnelle du prestataire (oui, ça arrive) ou une clé de compte partagé a été supprimée involontairement.

Correction : Le CI doit utiliser sa propre clé/cert dédié avec commande forcée et restrictions. Rétablissez l’accès du compte de service, puis ré-architectez.

6) « Nous avons révoqué la clé sur les hôtes, mais l’accès passe encore par le bastion »

Symptôme : La connexion directe échoue mais le saut via bastion réussit.

Cause racine : La clé est toujours valide sur le bastion, ou l’agent forwarding permet d’utiliser une clé différente sur la destination finale.

Correction : Révoquez d’abord sur le bastion, revoyez les réglages d’agent forwarding, et forcez l’usage explicite de IdentityFile lors des réponses à incident.

7) « L’audit indique 400 clés ; nous n’avons que 60 employés »

Symptôme : Les authorized_keys sont gonflés d’entrées inconnues.

Cause racine : Accumulation historique : anciens employés, accès prestataires, dépannages ponctuels, images copiées, et réutilisation de clés.

Correction : Établissez une baseline : supprimez les clés sans propriétaire, exigez des nouvelles demandes, et migrez vers un modèle centralisé ou les certificats.

Listes de contrôle / plan étape par étape

Phase 0 — Décider la politique (une page, appliquée)

  • Algorithmes autorisés (préférez Ed25519 ; autorisez RSA seulement si nécessaire pour des clients identifiables).
  • Règles de propriété des clés (pas de clés humaines partagées ; les comptes de service ont des clés dédiées).
  • Format requis des commentaires de clé (propriétaire + usage + éventuelle date d’expiration/revue).
  • Où les clés sont stockées et gérées (repo de gestion de config ou source AuthorizedKeysCommand).
  • Méthode d’accès d’urgence (break-glass) et cadence de rotation.

Phase 1 — Inventaire (la partie que tout le monde veut sauter)

  • Enumérer tous les comptes capables de se connecter (humains et services).
  • Enumérer toutes les sources de clés : chemins AuthorizedKeysFile, clés root, comptes partagés, toute commande centralisée de clés.
  • Extraire les empreintes dans un tableau d’inventaire (empreinte → utilisateur → hôte → fichier → commentaire de ligne).
  • Marquer les clés inconnues et les doublons (même blob de clé dans plusieurs comptes).

Phase 2 — Rotation (introduire de nouvelles clés sans casser l’accès)

  • Émettre de nouvelles clés/certs aux utilisateurs et services.
  • Déployer les nouvelles clés publiques aux côtés des anciennes temporairement (si non compromises).
  • Valider avec des tests contrôlés : un utilisateur, un hôte, -i explicite, confirmation dans les logs.
  • Déployer progressivement : bastion d’abord, puis cibles à haute valeur, puis le reste.

Phase 3 — Révocation (rendre les anciennes clés inutilisables et le prouver)

  • Retirer les anciennes clés à l’échelle du parc, y compris bastions et comptes partagés.
  • Recharger sshd après validation.
  • En cas de compromission : terminer les sessions actives authentifiées avec ces identifiants lorsqu’il est possible.
  • Collecter des preuves : lignes de log montrant des tentatives publickey échouées avec l’empreinte révoquée après le changement.

Phase 4 — Empêcher la repousse (stopper la prolifération à la source)

  • Interdire les modifications manuelles en production ; appliquer via gestion de config et surveillance d’intégrité des fichiers.
  • Réduire le nombre de comptes autorisés à accepter des connexions SSH.
  • Appliquer des restrictions aux clés de service (commandes forcées, pas de forwarding, limites d’IP source).
  • Adopter les certificats ou la recherche de clés centralisée si la taille du parc le justifie.
  • Planifier des audits réguliers (mensuels/trimestriels) et les lier aux procédures d’offboarding.

FAQ

1) Si nous supprimons une clé de authorized_keys, est-elle immédiatement révoquée ?

Pour les nouvelles connexions, oui. Pour les sessions existantes, non. SSH ne re‑vérifie pas authorized_keys en cours de session. Si la clé a été compromise, terminez volontairement les sessions.

2) Quelle est la meilleure façon d’éviter la prolifération des clés ?

Cessez de traiter authorized_keys comme un bloc‑notes. Utilisez une source de vérité (gestion de config ou lookup centralisé) et interdisez les modifications manuelles en production.
Si possible, utilisez des certificats OpenSSH à courte durée.

3) Pourquoi avons-nous besoin d’empreintes si nous avons déjà des commentaires ?

Parce que les commentaires mentent, se copient ou disparaissent. Les empreintes identifient la matière clé réelle. En cas d’incident, votre piste d’audit doit référencer des empreintes.

4) Nous avons tourné les clés, mais les utilisateurs s’authentifient toujours avec l’ancienne clé depuis leur agent. Comment ?

Leur client SSH peut proposer plusieurs clés automatiquement. Utilisez ssh -vvv -i pour forcer la clé voulue pendant les tests, et définissez des règles d’identité par hôte dans la config SSH.

5) Devrait-on désactiver la connexion root SSH pendant ou après la rotation ?

Si vous le pouvez, oui — désactivez la connexion root directe et exigez sudo depuis des comptes nommés. Si vous devez la garder, restreignez-la fortement et considérez le authorized_keys de root comme sacré.

6) Est‑il sûr d’utiliser AuthorizedKeysCommand en production ?

Ça peut l’être, si vous le traitez comme une dépendance : cachez, monitorisez, et ayez un fallback break‑glass. Si votre organisation ne sait pas opérer des petits services de façon fiable, tenez‑vous aux fichiers gérés par config.

7) Comment révoquer l’accès d’un prestataire ayant utilisé un compte partagé ?

Enlevez sa clé du authorized_keys du compte partagé partout, puis remplacez ce modèle : les prestataires doivent obtenir des accès limités dans le temps avec des restrictions strictes,
de préférence via un bastion + certificats ou des comptes par prestataire.

8) Comment prouver aux auditeurs qu’une clé est révoquée ?

Montrez : (1) l’empreinte de la clé, (2) la preuve qu’elle a été retirée des sources, et (3) des logs montrant des tentatives d’authentification publickey rejetées avec cette empreinte
après le changement, sur des hôtes représentatifs ou à l’échelle du parc si possible.

9) Qu’en est‑il des clés intégrées dans des images ou conteneurs ?

Si une image contient du contenu authorized_keys, vous continuerez de ressusciter des clés révoquées. Scannez les images, corrigez la chaîne de build, et invalidez les anciennes images.
En d’autres termes : arrêtez d’expédier des identifiants comme artefacts.

10) Faut‑il aussi faire tourner les clés d’hôte ?

C’est un problème différent. La rotation des clés utilisateurs révoque l’accès utilisateur ; la rotation des clés d’hôte change l’identité du serveur et impacte known_hosts.
Faites la rotation des clés d’hôte en cas de compromission ou de politique, mais planifiez la mise à jour de la confiance côté client.

Prochaines étapes réalisables cette semaine

Si vous voulez une rotation qui tienne, faites trois choses dans les sept prochains jours :

  1. Construire un inventaire d’empreintes à partir de tous les authorized_keys sur un échantillon représentatif d’hôtes. Vous trouverez des surprises. C’est le but.
  2. Choisir un mécanisme de révocation que vous pouvez opérer : authorized_keys gérés par config, AuthorizedKeysCommand avec cache, ou (idéal) certificats courts.
  3. Écrire la règle « pas de modifications manuelles » et l’appliquer, en commençant par les bastions et la production. La dérive est la manière dont les clés d’aujourd’hui deviennent les incidents de demain.

La rotation des clés n’est pas une cérémonie. C’est un changement de contrôle d’accès avec des résultats mesurables : les anciennes clés échouent, les nouvelles réussissent, et il existe une trace écrite que vous accepteriez de consulter à 3h du matin.
Faites‑le une fois, faites‑le proprement, puis concevez le système pour ne pas réapprendre la même leçon chaque trimestre.

← Précédent
Proxmox Ceph HEALTH_WARN : par où commencer le dépannage en toute sécurité
Suivant →
ZFS SLOG : quand un périphérique de journal aide, quand il est inutile, quand il est dangereux

Laisser un commentaire