Sections du handbook

Durcir SSH

Revu le

SSH est la porte d'entrée d'un serveur. Durcissez le démon pour qu'un pied dans la place ne devienne pas un contrôle total, et vérifiez la config effective, pas le fichier.

La menace : la porte d'entrée, brute-forcée et backdoorée

SSH est généralement le seul chemin d'administration distante d'un serveur, et il est exposé au réseau. C'est donc une cible de choix : brute-force et credential-stuffing permanents, abus de réglages permissifs (connexion root directe, mot de passe, tunneling TCP), et même des attaques sur la chaîne d'approvisionnement du démon. La backdoor XZ Utils de 2024 (CVE-2024-3094) visait précisément l'authentification sshd, et regreSSHion (CVE-2024-6387) a montré une RCE pré-authentification dans sshd lui-même. Une configuration SSH faible transforme un seul identifiant volé en contrôle total du système.

Pourquoi le durcir

Le rayon d'impact, c'est toute la machine. Un mot de passe root brute-forcé ou une clé fuitée, et l'attaquant devient l'admin. Durcir SSH réduit la surface d'attaque et force chaque connexion par des chemins traçables et à moindre privilège, augmentant le coût d'une attaque et la probabilité de la détecter.

Ce que Pavois audite : la config effective sshd -T

Pavois lit la configuration effective via sshd -T, les réglages résolus du démon, et évalue donc les Include et drop-ins sous /etc/ssh/sshd_config.d/ tels que sshd les applique, là où un scan par fichier (OVAL/oscap) les raterait. Parmi ses règles SSH, il vérifie : connexion root désactivée, mot de passe et mot de passe vide refusés, Ciphers/MACs/KexAlgorithms forts, MaxAuthTries, LoginGraceTime, délai d'inactivité, les options de forwarding, PermitUserEnvironment, la bannière d'avertissement et LogLevel. C'est le facteur différenciant : un contrôle qui lit /etc/ssh/sshd_config seul est dupé par un drop-in qui rebascule la valeur.

Les directives essentielles

Directive Valeur durcie Pourquoi
PermitRootLogin no pas de root direct ; compte nominatif puis sudo, imputable
PasswordAuthentication no clés uniquement (à poser seulement après qu'une clé fonctionne)
KbdInteractiveAuthentication no ferme l'auth interactive clavier/PAM
PermitEmptyPasswords no refuse tout compte sans mot de passe
AllowUsers / AllowGroups liste explicite liste blanche des comptes autorisés
MaxAuthTries 3 moins d'essais par connexion (défaut 6)
LoginGraceTime 30 fenêtre d'auth courte, moins de connexions pendantes
X11Forwarding / AllowTcpForwarding / AllowAgentForwarding no retire les vecteurs de rebond/tunnel inutilisés
ClientAliveInterval / ClientAliveCountMax 300 / 2 ferme les sessions inactives
LogLevel VERBOSE journalise les empreintes de clés pour la traçabilité

Ciphers, MACs et échange de clés modernes

Ne gardez que des algorithmes modernes et retirez les anciens. À bannir : *-cbc, arcfour*, blowfish, 3des-cbc ; diffie-hellman-group1-sha1, *-group14-sha1, *-sha1 ; hmac-md5*, hmac-sha1* et tout MAC non-ETM ; ssh-dss. À privilégier (converge Mozilla, ssh-audit et ANSSI) : KexAlgorithms avec sntrup761x25519-sha512@openssh.com (post-quantique, défaut depuis OpenSSH 9.0) et curve25519-sha256 ; Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com ; MACs en -etm uniquement ; HostKeyAlgorithms ssh-ed25519,rsa-sha2-512 ; RequiredRSASize 3072. Vérifiez que votre binaire supporte un algorithme avant de le coller : ssh -Q kex ; ssh -Q cipher ; ssh -Q mac. ssh-audit note le résultat réel.

Comment l'appliquer sans se verrouiller dehors ?

C'est l'étape où l'on se coupe l'accès. Le réflexe en quatre temps, à ne jamais sauter :

  1. Valider la syntaxe : sshd -t (il ne teste pas la logique d'accès).
  2. Lire la config effective : sshd -T | grep -iE 'permitroot|passwordauth|allowusers|ciphers'.
  3. Recharger, pas redémarrer : systemctl reload ssh (sshd sur RHEL) garde votre session courante vivante.
  4. Tester dans une 2e session en gardant la première ouverte ; sur un serveur distant, gardez une console KVM/série de secours.

sshd -t ne valide que la syntaxe : on peut avoir un sshd -t vert et se verrouiller quand même (un AllowUsers mal écrit, ou PasswordAuthentication no sans clé déployée). D'où le sshd -T et la 2e session.

Le piège des drop-ins

Sur Debian 12, Ubuntu et RHEL 9, /etc/ssh/sshd_config commence par Include /etc/ssh/sshd_config.d/*.conf, et pour la plupart des directives SSH retient la première valeur rencontrée. Donc un fichier de sshd_config.d/ (lu en premier via l'Include) l'emporte sur ce que vous écrivez plus bas dans le fichier principal. Le piège classique : sur une image cloud, 50-cloud-init.conf réactive souvent PasswordAuthentication yes et annule votre durcissement. Deux règles : placez vos réglages dans /etc/ssh/sshd_config.d/00-hardening.conf (le préfixe 00- gagne l'ordre lexical), et vérifiez toujours avec sshd -T, jamais en relisant sshd_config.

Pièges

  • Les images cloud réactivent le mot de passe via 50-cloud-init.conf. Surchargez avec 00-hardening.conf et confirmez avec sshd -T.
  • Les blocs Match changent la valeur effective selon le contexte : vérifiez-les avec sshd -T -C user=...,host=...,addr=....
  • reload, pas restart : un restart à l'aveugle plus une mauvaise règle égale un serveur injoignable.
  • PasswordAuthentication no avant qu'une clé soit déployée verrouille tout le monde dehors.
  • Un KexAlgorithm post-quantique sur OpenSSH < 9.0 fait échouer sshd -t ; retirez-le sur les vieux démons.

FAQ

Pourquoi Pavois utilise-t-il sshd -T plutôt que lire sshd_config ? Parce que sshd -T est la config résolue que le démon applique, y compris chaque Include et drop-in ; un scan de fichier rate une surcharge et signale un faux succès.

J'ai durci sshd_config mais sshd -T montre encore la valeur faible. Pourquoi ? Un drop-in sous sshd_config.d/ (souvent 50-cloud-init.conf) est lu en premier et gagne. Placez vos réglages dans 00-hardening.conf.

Redémarrer ou recharger ? reload. Il applique la nouvelle config sans tuer votre session courante, donc une erreur ne vous verrouille pas immédiatement.