Vous venez de modifier la configuration SSH d'un serveur distant, et vous ne pouvez plus vous y connecter. La panne la plus stressante de l'administration Linux, parce que l'outil que vous utilisez pour réparer est précisément celui qui est cassé. Cette page vous apprend à qualifier le refus avant tout, puis à traiter les trois causes qui produisent trois symptômes différents, et enfin la règle qui vous aurait évité l'incident.
Toutes les commandes et sorties de cette page proviennent d'un serveur AlmaLinux
10 avec SELinux en Enforcing, la configuration par défaut du monde RHEL.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Qualifier le refus :
refused,timeoutetPermission denieddésignent trois coupables distincts - Valider
sshd_configavecsshd -tavant tout redémarrage - Diagnostiquer le piège du port non standard bloqué par SELinux, l'un des pièges classiques du RHCSA
- Corriger un rejet de clé dû aux permissions de
authorized_keys - Garder une porte de sortie pour ne jamais se verrouiller dehors
Qualifier le refus avant de toucher au serveur
Section intitulée « Qualifier le refus avant de toucher au serveur »Le message d'erreur de votre client SSH est le diagnostic. Trois refus, trois causes, trois procédures : les confondre, c'est chercher au mauvais endroit.
| Ce que dit le client | Signification | Coupable probable |
|---|---|---|
Connection refused | Le serveur a répondu, mais rien n'écoute sur ce port | sshd est arrêté ou écoute ailleurs |
Rien, puis Connection timed out | Aucune réponse : les paquets sont jetés en silence | Pare-feu, groupe de sécurité, ou serveur éteint |
Permission denied (publickey) | La connexion fonctionne, c'est l'authentification qui échoue | Clé, permissions de authorized_keys, ou compte |
Un refus n'est pas un timeout. Un refus prouve que la machine est vivante et
joignable : le réseau va bien, le problème est sur le service. Un timeout, à
l'inverse, ne dit rien du service : les paquets n'arrivent même pas jusqu'à lui.
Et un Permission denied est presque une bonne nouvelle : tout fonctionne, sauf
la preuve d'identité.
Cause 1 : une erreur de syntaxe dans sshd_config
Section intitulée « Cause 1 : une erreur de syntaxe dans sshd_config »C'est la faute la plus commune : une directive mal orthographiée, et le service refuse de redémarrer. Le point important est que cette panne est entièrement évitable, par une seule commande.
La commande qui vous sauve
Section intitulée « La commande qui vous sauve »sshd -t analyse la configuration sans toucher au service en cours. Elle
renvoie 0 si tout va bien, et un code non nul sinon :
sshd -t ; echo "exit=$?"exit=255Un code de sortie non nul, et vous ne redémarrez pas. Vous corrigez d'abord. Si vous redémarrez quand même, voici ce qui se passe :
systemctl restart sshd ; echo "exit=$?"systemctl is-active sshdss -tlnp | grep -E ':22\b' || echo "AUCUN processus n'ecoute sur le port 22"Job for sshd.service failed because the control process exited with error code.exit=1inactiveAUCUN processus n'ecoute sur le port 22Le service est arrêté, plus rien n'écoute sur le port 22, et toute nouvelle
connexion se prendra un Connection refused. Votre session actuelle, elle,
survit : c'est votre unique porte de sortie.
Restaurez la sauvegarde de votre configuration (vous en avez fait une avant de la modifier), validez, puis redémarrez :
cp -a /root/sshd_config.orig /etc/ssh/sshd_configsshd -t && echo "sshd_config valide"systemctl restart sshdss -tlnp | grep -E ':22\b'sshd_config valideLISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1865,fd=7))Cause 2 : le port non standard bloqué par SELinux
Section intitulée « Cause 2 : le port non standard bloqué par SELinux »Changer le port d'écoute de SSH est une demande courante. Sur Debian ou Ubuntu,
il suffit d'éditer sshd_config. Sur RHEL, AlmaLinux ou Rocky, cela ne suffit
pas, et l'erreur obtenue est particulièrement trompeuse.
La syntaxe est valide, et pourtant le service refuse de démarrer
Section intitulée « La syntaxe est valide, et pourtant le service refuse de démarrer »sed -ri 's/^#?Port .*/Port 2222/' /etc/ssh/sshd_configsshd -t ; echo "exit=$?"systemctl restart sshd ; echo "exit=$?"exit=0exit=1Regardez bien : sshd -t renvoie 0. La configuration est parfaitement
valide. Et pourtant le redémarrage échoue. C'est exactement le genre de
contradiction qui fait perdre une demi-heure, parce que la commande de validation
que vous venez d'apprendre vous dit ici que tout va bien.
Le journal donne la cause, mais elle induit en erreur
Section intitulée « Le journal donne la cause, mais elle induit en erreur »journalctl -u sshd --since '1 min ago' --no-pager | tail -3sshd[1816]: error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.sshd[1816]: error: Bind to port 2222 on :: failed: Permission denied.« Permission denied » alors que vous êtes root. C'est le signal. Root n'a jamais de problème de permission Unix pour ouvrir un port. Quand root se voit refuser quelque chose sans raison apparente, le suspect numéro un est le contrôle d'accès obligatoire, c'est-à-dire SELinux.
La trace AVC nomme le coupable
Section intitulée « La trace AVC nomme le coupable »SELinux journalise chaque refus sous forme d'AVC (Access Vector Cache) :
ausearch -m avc -ts recent | tail -2type=AVC msg=audit(1784022633.371:656): avc: denied { name_bind } for pid=1816comm="sshd" src=2222 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0Cette ligne se lit comme une phrase. Le démon sshd (dans le contexte sshd_t) a
tenté un name_bind sur le port 2222, dont l'étiquette est
unreserved_port_t. SELinux n'autorise sshd_t à se lier qu'aux ports étiquetés
ssh_port_t. Le port 2222 n'en fait pas partie, donc le bind est refusé.
Vérifiez quels ports la politique connaît réellement :
semanage port -l | grep -E '^ssh_port_t'ssh_port_t tcp 22Corriger
Section intitulée « Corriger »On étiquette le port pour la politique SELinux, puis on redémarre :
semanage port -a -t ssh_port_t -p tcp 2222semanage port -l | grep -E '^ssh_port_t'systemctl restart sshd ; echo "exit=$?"ss -tlnp | grep -E ':2222\b'ssh_port_t tcp 2222, 22exit=0LISTEN 0 128 0.0.0.0:2222 0.0.0.0:* users:(("sshd",pid=1847,fd=7))Le port 2222 est maintenant connu de la politique, sshd s'y lie, et le service
démarre. Deux étapes restent à faire avant de fermer votre session témoin :
ouvrir le port dans le pare-feu (firewall-cmd --add-port=2222/tcp --permanent)
et vérifier qu'une nouvelle connexion aboutit bien sur le nouveau port. Un
port SSH changé sans règle de pare-feu correspondante produit un timeout, et
vous revoilà dans la première colonne du tableau de qualification.
Cause 3 : les permissions de authorized_keys
Section intitulée « Cause 3 : les permissions de authorized_keys »Votre clé est la bonne, elle est bien dans authorized_keys, et pourtant le
serveur la refuse. La cause est presque toujours StrictModes, actif par
défaut : sshd refuse d'utiliser un fichier de clés que d'autres utilisateurs
pourraient modifier. La logique est saine, un attaquant qui peut écrire dans
votre authorized_keys peut y ajouter sa propre clé.
Le symptôme côté client
Section intitulée « Le symptôme côté client »ssh -i /root/.ssh/lab_probe root@127.0.0.1 'echo connexion OK' ; echo "exit=$?"root@127.0.0.1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).exit=255Rien, dans ce message, ne parle de permissions de fichier. Le client SSH ne sait pas pourquoi le serveur a refusé sa clé : le serveur ne le lui dit pas, et c'est volontaire (un serveur bavard aiderait un attaquant).
La cause est côté serveur, dans le journal
Section intitulée « La cause est côté serveur, dans le journal »journalctl -u sshd --since '1 min ago' | grep -i 'authentication refused'stat -c '%a %U:%G %n' /root/.ssh/authorized_keyssshd-session[1910]: Authentication refused: bad ownership or modes for file /root/.ssh/authorized_keys777 root:root /root/.ssh/authorized_keys« bad ownership or modes », le journal du serveur est explicite là où le
client était muet. Le fichier est en 777 : tout le monde peut le réécrire, donc
sshd l'ignore. Retenez ce réflexe : quand une clé est refusée, le vrai message
est côté serveur, dans journalctl -u sshd.
Corriger
Section intitulée « Corriger »chmod 700 /root/.sshchmod 600 /root/.ssh/authorized_keyschown -R root:root /root/.sshrestorecon -Rv /root/.sshLes permissions attendues sont 600 pour authorized_keys (lecture et écriture
pour le propriétaire seulement) et 700 pour le répertoire .ssh. Le
restorecon remet au passage les étiquettes SELinux correctes, souvent perdues
quand le fichier a été copié depuis un autre emplacement.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Vérification | Correction |
|---|---|---|---|
Connection refused | sshd arrêté (config invalide) | systemctl is-active sshd, sshd -t | Corriger la config, systemctl restart sshd |
Connection refused après un changement de port | Le service écoute ailleurs | ss -tlnp | grep sshd | Se connecter avec ssh -p <port> |
Connection timed out | Pare-feu ou groupe de sécurité | firewall-cmd --list-all | Ouvrir le port, vérifier aussi le pare-feu du fournisseur |
Le service refuse de démarrer sur un port non standard, sshd -t dit 0 | SELinux : port non étiqueté | ausearch -m avc -ts recent | semanage port -a -t ssh_port_t -p tcp <port> |
Permission denied (publickey) avec la bonne clé | StrictModes : permissions trop larges | journalctl -u sshd, stat sur authorized_keys | chmod 600 sur le fichier, 700 sur .ssh |
| Tout semble correct mais rien n'aboutit | Le serveur ne boote plus | Console du fournisseur ou virsh console | Voir Arrêter, redémarrer, récupérer |
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »- Le message du client est le diagnostic :
refused(rien n'écoute),timeout(pare-feu),Permission denied(authentification). Trois causes, trois procédures. sshd -tavant chaquerestart. Cette commande seule évite la majorité des verrouillages.- Gardez toujours une session ouverte et testez avec une seconde
connexion. Une session établie survit au redémarrage de
sshd. - Sur RHEL, changer le port SSH ne suffit pas : SELinux n'autorise
sshdà se lier qu'aux portsssh_port_t. Le symptôme est unPermission deniedalors que vous êtes root, etsshd -tne le voit pas. semanagen'est pas installé par défaut sur les images cloud RHEL, alors que SELinux, lui, est bien enEnforcing.- Une clé refusée se diagnostique côté serveur : le client ne dit jamais
pourquoi.
journalctl -u sshdrévèle le « bad ownership or modes ». authorized_keysen 600,.sshen 700. Plus permissif, et StrictModes ignore le fichier.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Configurer le serveur OpenSSH : durcir sshd sans se verrouiller dehors.
- Créer et gérer des clés SSH : générer, déployer et protéger ses clés.
- SELinux : comprendre les AVC et corriger une politique sans la désactiver.
- Pare-feu firewalld : ouvrir un port proprement, et de façon persistante.