Points clés à retenir (TL;DR)
Synthèse exécutive- Identifier precisement la version d'OpenSSH (paquet distribution et binaire) avant toute action : la banniere reseau ne suffit pas.
- Appliquer le correctif via le gestionnaire de paquets de la distribution ; verifier la version corrigee dans l'avis officiel de l'editeur (ne jamais compiler a l'aveugle).
- Durcir
sshd_config(reduction de surface) sans couper votre propre session : toujours valider avecsshd -tet garder une session de secours ouverte. - Valider le port, la version et la connectivite avant de fermer les sessions existantes ; prevoir un rollback de paquet et de configuration.
- Cadrer l'operation comme un changement ITIL (standard ou normal selon exposition) avec fenetre de maintenance et plan de retour documente.

Le probleme qu’on resout
Une vulnerabilite critique d’OpenSSH (exploitation du service sshd exposant un acces a distance) impose une correction rapide sur un parc de serveurs. Le besoin concret : supprimer la condition exploitable sans perdre l’acces SSH, car c’est souvent le seul canal d’administration disponible.
Les methodes « evidentes » echouent pour trois raisons. D’abord, se fier a la banniere affichee a la connexion (ex. SSH-2.0-OpenSSH_9.x) est trompeur : les distributions appliquent des correctifs retroportes sans changer le numero mineur. Ensuite, redemarrer sshd trop tot ou appliquer une directive invalide peut verrouiller l’administrateur hors du serveur. Enfin, compiler OpenSSH depuis les sources contourne la gestion des paquets et casse les mises a jour futures. Ce guide privilegie le correctif distribution, la validation syntaxique et une session de secours.
Comment ca marche
La correction repose sur deux leviers complementaires, du plus efficace au plus structurel.
1. Le correctif editeur (priorite absolue)
La vulnerabilite est corrigee par une version precise d’OpenSSH. Sur les distributions maintenues, le correctif est retroporte dans le paquet openssh-server. La commande decisive n’est donc pas la version affichee, mais la version du paquet installe comparee a la version corrigee publiee dans l’avis officiel (Debian/Ubuntu DSA/USN, Red Hat RHSA, SUSE SUSE-SU, avis OpenSSH amont). Verifiez toujours le numero exact dans l’avis de votre editeur : il varie selon la distribution et la branche.
2. Le durcissement de configuration (reduction de surface, defense en profondeur)
Meme corrige, sshd gagne a limiter sa surface : desactiver l’authentification par mot de passe, l’acces root direct, restreindre les utilisateurs, limiter les tentatives. Cela reduit la portee des techniques ATT&CK T1021.004 (Remote Services: SSH) et T1110 (Brute Force). Le durcissement ne remplace pas le correctif : il le complete.
Principe cardinal : on ne touche jamais a sshd sans filet. On valide la syntaxe (sshd -t), on demarre une instance de test sur un port alternatif si doute, et on garde une session ouverte pour corriger un blocage.
Prerequis
- Acces
rootousudosur les serveurs cibles. - Deux sessions SSH ouvertes (une de travail, une de secours) ou un acces console hors-bande (iDRAC/iLO, console cloud, KVM).
- Gestionnaire de paquets fonctionnel et depots a jour (
apt,dnf/yum,zypper). - Avis de securite officiel de votre distribution pour connaitre la version corrigee.
- Fenetre de maintenance validee et ticket de changement.
- Outils :
ssh,ssounetstat,systemctl, editeur de texte.
Procedure
- Ouvrir une session de secours et ne jamais la fermer avant la fin de la validation.
- Detecter la version : binaire (
sshd -Voussh -V) et paquet (dpkg -l/rpm -q). - Comparer a la version corrigee publiee dans l’avis officiel. Si elle est inferieure, planifier le correctif.
- Sauvegarder
/etc/ssh/sshd_configet noter la version de paquet installee (pour rollback). - Mettre a jour le paquet
openssh-servervia le gestionnaire de paquets. - Durcir la configuration via un fichier
/etc/ssh/sshd_config.d/99-hardening.conf(drop-in) plutot que d’editer le fichier principal. - Valider la syntaxe avec
sshd -tavant tout rechargement. - Recharger le service (
systemctl reload sshd), puis tester une nouvelle connexion via la session de travail. - Valider version, port et connectivite, puis fermer la session de secours.
Le script
Script shell POSIX-compatible (teste sur bash) pour Debian/Ubuntu et RHEL/derives. Il detecte, sauvegarde, met a jour, applique un durcissement via drop-in, valide et recharge. Valeurs generiques uniquement.
#!/usr/bin/env bash
# fix-openssh.sh - Detection, correctif et durcissement de sshd
# Prerequis : root/sudo, session de secours ouverte, fenetre de maintenance.
# AUCUNE valeur reelle. Adaptez AllowUsers et le port a votre environnement.
set -euo pipefail
TS="$(date +%Y%m%d-%H%M%S)"
SSHD_MAIN="/etc/ssh/sshd_config"
DROPIN_DIR="/etc/ssh/sshd_config.d"
DROPIN="${DROPIN_DIR}/99-hardening.conf"
BACKUP_DIR="/root/ssh-backup-${TS}"
echo "== 1. Pre-checks =="
[ "$(id -u)" -eq 0 ] || { echo "Executez en root/sudo"; exit 1; }
mkdir -p "$BACKUP_DIR"
echo "== 2. Detection de version (binaire + paquet) =="
sshd -V 2>&1 | head -n1 || ssh -V 2>&1 | head -n1
if command -v dpkg >/dev/null 2>&1; then
PKG_MGR="apt"
dpkg -l openssh-server | tail -n1 | tee "$BACKUP_DIR/pkg-version.txt"
elif command -v rpm >/dev/null 2>&1; then
PKG_MGR="dnf"
rpm -q openssh-server | tee "$BACKUP_DIR/pkg-version.txt"
else
echo "Gestionnaire de paquets non reconnu"; exit 1
fi
echo ">> Comparez cette version a l'avis officiel de votre editeur AVANT de continuer."
echo "== 3. Sauvegarde de la configuration =="
cp -a "$SSHD_MAIN" "$BACKUP_DIR/sshd_config.bak"
[ -d "$DROPIN_DIR" ] && cp -a "$DROPIN_DIR" "$BACKUP_DIR/sshd_config.d.bak" || true
echo "Sauvegardes dans $BACKUP_DIR"
echo "== 4. Mise a jour du paquet openssh-server =="
if [ "$PKG_MGR" = "apt" ]; then
apt-get update
apt-get install --only-upgrade -y openssh-server
else
dnf -y upgrade openssh-server
fi
echo "== 5. Durcissement via drop-in (non destructif) =="
mkdir -p "$DROPIN_DIR"
cat > "$DROPIN" <<'EOF'
# 99-hardening.conf - durcissement sshd (adapter a l'environnement)
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowAgentForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
# Restreindre les comptes autorises (valeur d'exemple)
AllowUsers adminops
# Port alternatif optionnel (decommenter si souhaite)
# Port 2222
EOF
chmod 644 "$DROPIN"
echo "== 6. Verifier que le drop-in est bien inclus =="
grep -q "Include /etc/ssh/sshd_config.d/\*.conf" "$SSHD_MAIN" \
|| echo "ATTENTION: ajoutez 'Include /etc/ssh/sshd_config.d/*.conf' dans $SSHD_MAIN"
echo "== 7. Validation syntaxique (bloquant) =="
if ! sshd -t; then
echo "Syntaxe invalide -> restauration du drop-in"
rm -f "$DROPIN"
exit 1
fi
echo "== 8. Rechargement du service (reload, pas restart) =="
systemctl reload sshd || systemctl reload ssh
echo "== 9. Etat final =="
systemctl is-active sshd 2>/dev/null || systemctl is-active ssh
ss -tlnp | grep -E 'ssh|:22|:2222' || true
echo ">> Testez MAINTENANT une NOUVELLE connexion avant de fermer la session de secours."
Variante : deploiement sur plusieurs hotes via une boucle SSH simple (a lancer depuis un poste d’administration, cles deja distribuees).
#!/usr/bin/env bash
# deploy-multi.sh - diffusion du correctif sur un parc
set -euo pipefail
HOSTS="host1.exemple.test host2.exemple.test host3.exemple.test"
for H in $HOSTS; do
echo "=== $H ==="
scp ./fix-openssh.sh "adminops@${H}:/tmp/fix-openssh.sh"
ssh "adminops@${H}" 'sudo bash /tmp/fix-openssh.sh' || echo "ECHEC sur $H"
done
Validation
Valider dans cet ordre, sans fermer la session de secours :
- Version du paquet :
dpkg -l openssh-serverourpm -q openssh-serverdoit renvoyer une version egale ou superieure a celle de l’avis officiel. - Syntaxe :
sshd -tne renvoie aucune sortie (code retour 0). - Service actif :
systemctl is-active sshdrenvoieactive. - Ecoute reseau :
ss -tlnp | grep sshmontre le port attendu. - Connexion neuve : depuis un autre terminal,
ssh -v adminops@serveur.exemple.testaboutit et refuse le mot de passe siPasswordAuthentication no.
# Verifier la directive effective appliquee (config fusionnee)
sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|port|maxauthtries'
# Sortie attendue (exemple) :
# port 22
# permitrootlogin no
# passwordauthentication no
# maxauthtries 3
Si ssh -v aboutit avec une nouvelle session, l’operation est reussie. Fermez alors la session de secours.
Plan de retour (rollback)
Deux niveaux de rollback, selon le symptome.
Rollback de configuration (blocage d’acces)
# Depuis la session de secours ou la console hors-bande
rm -f /etc/ssh/sshd_config.d/99-hardening.conf
cp -a /root/ssh-backup-AAAAMMJJ-HHMMSS/sshd_config.bak /etc/ssh/sshd_config
sshd -t && systemctl reload sshd
Rollback du paquet (regression fonctionnelle)
# Debian/Ubuntu : reinstaller une version precise conservee en cache
apt-get install --allow-downgrades -y openssh-server=<VERSION_PRECEDENTE>
# RHEL/derives :
dnf downgrade openssh-server
# Verifier puis recharger
sshd -t && systemctl reload sshd
Notez la version precedente (capturee dans pkg-version.txt) avant la mise a jour. Un downgrade reintroduit la vulnerabilite : a n’utiliser qu’en cas de regression bloquante, puis replanifier le correctif.
Depannage
| Symptome | Cause probable | Solution |
|---|---|---|
| Connexion refusee apres reload | Directive invalide ou port modifie non ouvert au pare-feu | Via session de secours : sshd -t, corriger ou retirer le drop-in ; ouvrir le port (ufw allow/firewall-cmd) |
sshd -t echoue |
Erreur de syntaxe dans le drop-in | Lire le numero de ligne retourne, corriger ou supprimer 99-hardening.conf |
| Mot de passe encore accepte | Include absent du fichier principal |
Ajouter Include /etc/ssh/sshd_config.d/*.conf, verifier avec sshd -T |
| Version inchangee apres upgrade | Depot non a jour ou paquet retenu (hold) | apt-mark showhold / dnf versionlock list, lever le verrou, relancer |
| Banniere identique mais corrige | Correctif retroporte sans changement de version amont | Se fier a la version du paquet, pas a la banniere |
| Compte verrouille hors serveur | AllowUsers trop restrictif |
Console hors-bande, ajouter le compte ou retirer la directive, reload |
Securite, changement et bonnes pratiques
- Moindre privilege : executer le correctif avec
sudocible, pas en session root permanente. RestreindreAllowUsersaux comptes d’administration reels. - Secrets : privilegier l’authentification par cle ; ne stockez jamais de cle privee sur le serveur cible. Desactivez les mots de passe apres avoir confirme l’acces par cle.
- Lecture seule d’abord : la phase de detection (versions,
sshd -T) est non intrusive et peut etre deployee en masse avant tout changement. - Drop-in plutot qu’edition :
sshd_config.d/*.conffacilite le rollback et la revue de configuration. - Cadrage ITIL : sur un parc critique expose, traitez cela comme un changement normal soumis au CAB avec fenetre de maintenance, plan de retour et communication. Si vous disposez d’un modele pre-approuve de patching SSH, un changement standard est envisageable. En exploitation active averee, basculez en gestion d’incident majeur avec changement d’urgence (ECAB).
- Tracabilite : rattachez chaque hote traite au ticket, conservez
pkg-version.txtet la sauvegarde horodatee comme preuve de changement. - Apres-coup : surveillez
/var/log/auth.logoujournalctl -u sshdpour les echecs d’authentification (T1110) et confirmez l’absence de regression applicative.
A retenir
La correction d’une faille OpenSSH exploitee tient en une discipline : detecter la vraie version (paquet, pas banniere), appliquer le correctif de l’editeur, durcir sans se verrouiller, valider une connexion neuve, et garder un rollback pret. La session de secours et sshd -t sont vos deux garde-fous indispensables. Verifiez systematiquement la version corrigee dans l’avis officiel de votre distribution avant de conclure qu’un hote est sain.
Prochaine etape sobre : inventoriez vos versions OpenSSH en lecture seule, planifiez le changement dans une fenetre de maintenance, puis deployez le correctif par vagues en validant chaque hote avant de passer au suivant.