Les formes de ce message
kex_exchange_identification: read: Connection reset by peer
Connection reset by 203.0.113.10 port 22
kex_exchange_identification: Connection closed by remote host
Connection closed by 203.0.113.10 port 22
Les clients récents n'affichent parfois que la dernière ligne, Connection closed by 203.0.113.10 port 22, sauf si vous ajoutez -v. Reset et closed ne diffèrent que par la façon dont la connexion s'est terminée. Traitez-les comme le même problème, car la même cause peut produire l'un ou l'autre selon ce qui se trouve entre vous et le serveur.
Commencez ici
ssh -v user@server true
Cette ligne dans la sortie est un indice très utile :
debug1: kex_exchange_identification: banner line 0: Not allowed at this time
Ce texte vient de sshd lui-même. Il signifie que le serveur est en marche et vous écarte volontairement : passez à la cause 1 et à la cause 2. Pour lire la raison, utilisez une console ou une autre connexion sur le serveur :
sudo journalctl -u ssh -u sshd --since "1 hour ago" | grep -iE 'maxstartups|penalty'
Si vous êtes bloqué dehors, essayez aussi depuis un autre réseau, comme le point d'accès d'un téléphone. Si cela fonctionne, le blocage est lié à votre adresse.
Cause 1 : les pénalités de sshd
Depuis OpenSSH 9.8, sshd pénalise les adresses qui échouent à se connecter, et c'est activé par défaut. Tant que la pénalité dure, les nouvelles connexions de cette adresse sont abandonnées. Le journal du serveur affiche :
drop connection #0 from [203.0.113.10]:41056 on [203.0.113.20]:22 penalty: failed authentication
Attendre suffit : le maximum par défaut est de 10 minutes. Cela vous touche plus facilement derrière une adresse de bureau partagée, ou avec un script ou une surveillance qui échoue sans cesse : corrigez d'abord ce qui échoue. Pour une adresse de confiance, ajoutez ceci à sshd_config :
PerSourcePenaltyExemptList 203.0.113.10
Un client qui propose beaucoup de clés peut échouer plusieurs fois en une seule connexion. Voyez Too many authentication failures pour le limiter à la bonne clé.
Cause 2 : MaxStartups
MaxStartups limite les connexions qui ne sont pas encore authentifiées. La valeur par défaut est 10:30:100 : à partir de 10 de ces connexions, sshd abandonne les nouvelles au hasard avec 30 % de chances, en augmentant jusqu'à tout abandonner à 100. Des robots qui scannent un serveur public peuvent remplir cette limite. Le journal affiche :
drop connection #1 from [203.0.113.10]:37954 on [203.0.113.20]:22 Maxstartups
Les versions plus anciennes journalisent exceeded MaxStartups. Vérifiez le réglage et les connexions en cours :
sudo sshd -T | grep -iE '^(maxstartups|persourcemaxstartups|logingracetime)'
ss -tn state established '( sport = :22 )'
L'échec est souvent intermittent : un nouvel essai fonctionne. Pour faire de la place, relevez la limite, et réduisez le trafic des robots avec une liste d'autorisation dans le pare-feu ou un LoginGraceTime plus court :
MaxStartups 30:30:100
Validez et appliquez. Le service s'appelle ssh sur Debian et Ubuntu, et sshd sur les systèmes de type Red Hat :
sudo sshd -t && sudo systemctl reload ssh
Cause 3 : les TCP wrappers
OpenSSH en amont a abandonné cette fonction depuis longtemps, mais certaines distributions la compilent encore. C'est le cas de Debian 13, et une ligne sshd: ALL dans /etc/hosts.deny a produit le message de reset lors de notre test. Depuis OpenSSH 9.8, la bibliothèque est liée à sshd-session et non à sshd, donc vérifiez les deux :
ldd /usr/sbin/sshd /usr/lib/openssh/sshd-session 2>/dev/null | grep libwrap
grep -v '^#' /etc/hosts.deny /etc/hosts.allow
Supprimez la règle, ou autorisez votre adresse dans /etc/hosts.allow :
sshd: 203.0.113.10
Cause 4 : un pare-feu ou fail2ban
Un pare-feu, un répartiteur de charge ou un dispositif de prévention d'intrusion qui envoie un reset TCP après l'ouverture de la connexion produit cette famille de messages. Nous l'avons reproduit avec cette règle, où SSH a affiché Connection reset by peer :
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate ESTABLISHED -j REJECT --reject-with tcp-reset
fail2ban est une cause moins probable de ce message qu'on ne le croit. Ses actions par défaut rejettent les nouvelles connexions, ce que le client signale par Connection refused et non par un reset. Cela vaut quand même un coup d'œil si vous avez échoué plusieurs connexions :
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10
Voir fail2ban pour SSH pour en savoir plus.
Cause 5 : un tunnel dans une impasse
Si vous vous connectez par un tunnel ou une redirection de port, le premier saut accepte votre connexion puis n'arrive pas à joindre la vraie cible. Le client voit le reset. Avec ssh -L, le terminal où tourne le tunnel affiche la vraie raison :
channel 3: open failed: connect failed: Connection refused
Regardez là, ou dans le journal de votre proxy. Vérifiez que l'adresse et le port de la cible sont corrects, et que sshd tourne sur la cible.
Cause 6 : sshd lui-même a un problème
Quand les cas ci-dessus ne correspondent pas, testez la configuration et lancez une copie de débogage sur un port libre. Votre service normal continue de tourner :
sudo sshd -t
sudo /usr/sbin/sshd -d -p 2200
Connectez-vous ensuite avec ssh -p 2200 user@server et lisez ce qu'affiche la copie de débogage. Autorisez d'abord ce port dans votre pare-feu, et fermez-le ensuite.
Questions
Que signifie kex_exchange_identification: Connection reset by peer ?
La connexion TCP s'est ouverte mais a été coupée avant le message d'accueil SSH. Le serveur, ou un équipement entre les deux, vous a refusé avant toute vérification de clé ou de mot de passe.
Combien de temps dure une pénalité de sshd ?
Depuis OpenSSH 9.8, les pénalités augmentent avec les échecs répétés, jusqu'à 10 minutes par défaut. Il suffit d'attendre, et PerSourcePenaltyExemptList exempte les adresses de confiance.
Pourquoi la coupure n'arrive-t-elle que parfois ?
Une coupure intermittente désigne souvent MaxStartups : quand trop de connexions sont encore en cours d'authentification, sshd rejette les nouvelles au hasard.
Sources
- sshd_config(5), MaxStartups et PerSourcePenalties
- Notes de version d'OpenSSH 9.8
- sshd(8), manuel OpenBSD
- hosts_access(5), manuel Debian