Aller au contenu

SSH : durcissement du serveur

Réglages recommandés pour un serveur SSH exposé à Internet. Les exemples utilisent des noms génériques (deploy).

Règle d’or : ne pas se verrouiller hors du serveur

Section intitulée « Règle d’or : ne pas se verrouiller hors du serveur »
  1. Garder une session SSH ouverte pendant toute la modification.
  2. Tester la syntaxe avant de recharger : sudo sshd -t.
  3. Tester une nouvelle connexion dans un autre terminal avant de fermer la session ouverte.
  4. Disposer d’un accès de secours (console de l’hébergeur).

Ubuntu lit /etc/ssh/sshd_config.d/*.conf avant le reste de sshd_config. Créer un fichier qui précède ceux des autres paquets (ordre alphabétique) :

Fenêtre de terminal
sudo tee /etc/ssh/sshd_config.d/00-durcissement.conf <<'CONF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowUsers deploy
ClientAliveInterval 300
ClientAliveCountMax 2
CONF
sudo sshd -t && sudo systemctl reload ssh

Avant de recharger, vérifier que la connexion par clé fonctionne (voir Clés SSH) : désactiver les mots de passe sans clé installée ferme l’accès.

Directive Effet
PermitRootLogin no Interdit la connexion directe en root (utiliser un compte et sudo)
PasswordAuthentication no Interdit les mots de passe : seules les clés sont acceptées
KbdInteractiveAuthentication no Ferme l’authentification interactive (autre voie de mot de passe)
AuthenticationMethods publickey Exige une clé publique
MaxAuthTries 3 Nombre d’essais par connexion
LoginGraceTime 30 Délai (secondes) pour s’authentifier
X11Forwarding no Désactive la redirection graphique
AllowUsers deploy Seuls ces comptes peuvent se connecter (aussi AllowGroups)
ClientAliveInterval, ClientAliveCountMax Ferme les sessions inactives (ici 300 s × 2)
Fenêtre de terminal
sudo sshd -T | grep -E "^(permitrootlogin|passwordauthentication|allowusers|maxauthtries|authenticationmethods|x11forwarding) "
sudo sshd -T -C user=deploy,host=poste,addr=203.0.113.5 # valeurs pour une connexion donnée (blocs Match)

Exemple de résultat attendu :

maxauthtries 3
permitrootlogin no
passwordauthentication no
x11forwarding no
allowusers deploy
authenticationmethods publickey

Tester depuis un autre terminal :

Fenêtre de terminal
ssh deploy@serveur.exemple.com # doit fonctionner
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password deploy@serveur.exemple.com # doit échouer : Permission denied (publickey)
ssh root@serveur.exemple.com # doit échouer
Fenêtre de terminal
sudo sshd -t # toujours avant
sudo systemctl reload ssh # recharge sshd_config, sessions conservées
sudo systemctl restart ssh # redémarre (les nouvelles connexions utilisent la nouvelle configuration)

Les sessions ouvertes ne sont pas coupées par reload ni par restart : une configuration erronée n’affecte que les connexions suivantes, d’où l’intérêt de garder la session ouverte.

Changer de port réduit le bruit des scans automatisés, mais n’est pas une protection (un scan de ports le retrouve). Sur Ubuntu, SSH démarre par activation de socket : modifier Port ne suffit pas.

Fenêtre de terminal
echo "Port 2222" | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -t
sudo ufw allow 2222/tcp # autoriser le nouveau port AVANT
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -tlnp | grep ':2222' # écoute sur le nouveau port

Testé sur Ubuntu 24.04 et 26.04 : avec seulement systemctl restart ssh.socket, le port reste 22 ; il faut daemon-reload puis restart ssh.socket. Tester ssh -p 2222 deploy@serveur.exemple.com dans un autre terminal avant de retirer l’ancien port du pare-feu (sudo ufw delete allow OpenSSH).

# Accepter les mots de passe seulement depuis le réseau interne
Match Address 192.168.1.0/24
PasswordAuthentication yes
# Un groupe limité aux transferts de fichiers (voir « Transfert de fichiers »)
Match Group sftponly
ChrootDirectory /srv/sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no

Les blocs Match s’écrivent en fin de fichier : ils s’appliquent jusqu’au prochain Match ou à la fin du fichier.

AllowTcpForwarding no # interdit les tunnels (ou « local » pour n'autoriser que -L)
AllowAgentForwarding no
PermitTunnel no
GatewayPorts no

À activer par utilisateur avec Match si certains comptes ont besoin de tunnels.

Un second facteur (code TOTP) s’ajoute à la clé avec libpam-google-authenticator :

Fenêtre de terminal
sudo apt install libpam-google-authenticator
google-authenticator # configuration par chaque utilisateur

Puis AuthenticationMethods publickey,keyboard-interactive et KbdInteractiveAuthentication yes, et auth required pam_google_authenticator.so dans /etc/pam.d/sshd. Tester sur une session de secours : une erreur ici bloque l’accès.

Banner /etc/issue.net
PrintMotd no

La bannière s’affiche avant l’authentification (message d’avertissement légal). Ne pas y indiquer d’informations techniques.

Fenêtre de terminal
sudo journalctl -u ssh -n 50 --no-pager
sudo journalctl -u ssh --since "1 hour ago" | grep -iE "failed|invalid|refused"
last -n 10 # connexions réussies
sudo lastb -n 10 # tentatives échouées

Le blocage automatique des adresses qui échouent est assuré par Fail2ban (voir Pare-feu : Fail2ban).

Symptôme Piste
sshd -t signale une erreur Ligne et fichier indiqués : directive inconnue ou faute de frappe
sshd -T montre encore passwordauthentication yes Un fichier lu avant le vôtre (ls /etc/ssh/sshd_config.d/) : nommer le vôtre 00-…
Le port ne change pas sudo systemctl daemon-reload puis sudo systemctl restart ssh.socket
Accès perdu après modification Console de l’hébergeur : corriger ou retirer le fichier /etc/ssh/sshd_config.d/00-durcissement.conf, sudo systemctl reload ssh
Un utilisateur légitime est refusé AllowUsers/AllowGroups ne l’inclut pas
Match sans effet Le bloc doit être après les réglages généraux, et la condition doit correspondre (sshd -T -C …)

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Les réglages de cette page sont identiques sur OpenSSH 9.6 (24.04) et 10.2 (26.04).