Durcissement SSH#

Pourquoi, et pourquoi si tôt#

SSH est le tout premier service exposé sur ce serveur : c’est par lui que s’est établie la connexion à la fin du chapitre précédent. C’est aussi, de très loin, la cible la plus scannée d’Internet : un serveur fraîchement mis en ligne reçoit des tentatives de connexion SSH automatisées en quelques minutes, bien avant que chrony, nginx ou le pare-feu ne soient configurés.

Ce chapitre est placé volontairement tout de suite après le premier boot, et non à la fin de l’installation. Dans beaucoup de tutoriels, le durcissement arrive en dernier, une fois “que tout marche” : c’est l’ordre inverse du bon sens sécurité : la fenêtre entre le premier boot (SSH en configuration par défaut) et la fin d’une installation complète peut se compter en heures, voire en jours pour un projet mené sur plusieurs sessions. Chaque minute passée avec un SSH non durci sur une IP publique est une minute d’exposition inutile. Durcir SSH est donc la toute première chose à faire après le premier boot, avant même d’installer le moindre paquet applicatif.

Ce guide n’a pas la prétention d’être exhaustif en matière de sécurité. Il couvre les mesures jugées pertinentes pour ce projet précis, pas un référentiel complet. Un durcissement réellement complet dépend du contexte (exposition réseau, contraintes réglementaires, criticité) et mérite une démarche dédiée, voir le chapitre Lynis, plus loin, pour une méthode d’audit qui va au-delà de ce qui est montré ici.

Comment#

Bannière légale pré-authentification#

cat > /etc/issue.net <<'EOF'
*** WARNING, AUTHORIZED ACCESS ONLY ***
This system is restricted to authorized administrators.
All connections are logged and audited.
Disconnect IMMEDIATELY if you are not an authorized user.
EOF
cp /etc/issue.net /etc/issue

Configuration sshd#

cat > /etc/ssh/sshd_config.d/99-hardening.conf <<'EOF'
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM yes

# Bannière légale pré-authentification et journalisation détaillée
Banner /etc/issue.net
LogLevel VERBOSE

# Algorithmes modernes uniquement, hybride post-quantique en tête
KexAlgorithms        mlkem768x25519-sha256,curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
HostKeyAlgorithms    ssh-ed25519,rsa-sha2-512,rsa-sha2-256
Ciphers              chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs                 hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# Restrictions de session
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 4
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers utilisateur

# Désactivations
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
GSSAPIAuthentication no
HostbasedAuthentication no
UseDNS no
EOF

sshd -t                      # validation AVANT reload
systemctl reload ssh         # préserve les sessions actives

Les quatre listes d’algorithmes (KexAlgorithms, HostKeyAlgorithms, Ciphers, MACs) ne contiennent que des choix modernes : aucune suite en CBC ni de MAC en SHA-1, historiquement vulnérables à des attaques connues sur SSH. Le suffixe -etm (encrypt-then-MAC) est préféré à l’ordre inverse historique, une construction reconnue plus robuste contre les attaques par oracle de remplissage. L’ordre de chaque liste est aussi un ordre de préférence : le premier algorithme mutuellement supporté par le client est celui effectivement négocié.

Le premier algorithme de cette liste, mlkem768x25519-sha256, est un échange de clé hybride post-quantique (natif depuis OpenSSH 9.9, utilisé par défaut depuis OpenSSH 10.0) : le mécanisme de combinaison et sa justification sont détaillés au chapitre Post-quantique, qui couvre la même hybridation côté TLS et SSH. L’ANSSI recommande cette approche par hybridation et confirme sa disponibilité native dans OpenSSH dans sa fiche technique Transition post-quantique de SSHv2 (ANSSI-FT-116, février 2026).

Côté restrictions de session, les valeurs sont volontairement plus strictes que les défauts OpenSSH : LoginGraceTime 30 (au lieu de 120 s par défaut) réduit la fenêtre pendant laquelle une connexion non encore authentifiée reste ouverte, limitant l’impact d’un grand nombre de connexions lentes maintenues délibérément ouvertes. MaxAuthTries 3 (au lieu de 6) limite le nombre de tentatives d’authentification par connexion avant fermeture. MaxSessions 4 plafonne le nombre de sessions multiplexées sur une même connexion réseau. ClientAliveInterval 300 avec ClientAliveCountMax 2 envoie une sonde applicative toutes les 5 minutes et ferme la connexion après 2 échecs consécutifs (10 minutes sans réponse) : de quoi récupérer les ressources d’une connexion morte ou figée sans pénaliser un usage interactif normal. UseDNS no désactive la résolution DNS inverse de l’IP cliente à la connexion : elle n’apporte aucune garantie de sécurité exploitable (une IP attaquante contrôle généralement aussi son propre reverse DNS) et ajoute une latence de connexion pour rien.

PasswordAuthentication no est le réglage par défaut recommandé ici, pour un serveur exposé sur Internet sans restriction réseau amont sur le port 22. Certaines architectures compensent différemment (SSH accessible uniquement depuis un LAN d’administration privé via le pare-feu, voir le chapitre nftables, plus loin dans ce guide) et peuvent alors se permettre de garder le mot de passe en filet de récupération. Sans cette compensation réseau équivalente, no est le choix le plus sûr par défaut, à condition de disposer d’une clé fonctionnelle et d’un canal de récupération hors-bande (console série ou HDMI) avant de couper l’authentification par mot de passe.

Erreurs à éviter#

Toujours valider sshd -t avant reload, jamais après. Une configuration SSH invalide appliquée directement peut casser irrémédiablement l’accès distant. sshd -t valide la syntaxe sans rien appliquer ; systemctl reload ssh (par opposition à restart) préserve les sessions déjà ouvertes, ce qui donne un filet de sécurité même en cas d’erreur non détectée par -t, une session SSH active doit toujours rester ouverte pendant le test d’une nouvelle configuration.

  • Attendre d’avoir “fini l’installation” pour durcir SSH. C’est précisément l’anti-pattern que ce chapitre cherche à casser (voir ci-dessus). Durcir maintenant, pas à la fin.
  • Couper l’authentification par mot de passe sans avoir vérifié la clé publique au préalable. Une connexion par clé doit être testée explicitement avant de désactiver le mot de passe, dans une session séparée, sans fermer la session actuelle.

Vérifier#

# Configuration SSH effective (pas seulement le fichier écrit)
sshd -T | grep -iE "permitrootlogin|pubkeyauth|passwordauth|allowusers"

# Depuis une AUTRE session (sans fermer celle-ci) :
ssh -o PreferredAuthentications=publickey utilisateur@serveur

Un second canal d’accès (console série, HDMI, ou accès physique) doit toujours rester disponible pendant toute modification de la configuration SSH : c’est le filet de sécurité qui transforme une erreur de configuration en simple correction plutôt qu’en incident nécessitant de récupérer et écrire sur la carte SD.

La suite du durcissement système (sysctl, audit, permissions) est couverte au chapitre suivant. Le pare-feu, fail2ban et l’audit Lynis complet arrivent plus loin dans ce guide, une fois les services qu’ils protègent effectivement installés.