Changer le port SSH sans perdre l'accès : sshd, activation par socket et SELinux

Publié le 17 min de lecture

Le changement de port SSH échoue presque toujours à cause de l'ordre des opérations. Ce guide fait écouter le serveur sur les deux ports pendant la transition, si bien que l'ancien ne disparaît qu'une fois le nouveau vérifié.

Changer le port SSH est l'un des conseils les plus répandus et les plus mal justifiés de l'administration serveur. Il a une utilité réelle, mais pas celle qu'on lui prête d'habitude, et il a un effet secondaire : entre le moment où le service lâche l'ancien port et celui où le nouveau devient joignable à travers tous les filtres de paquets, il reste une fenêtre. Qui ne la prévoit pas finit par la trouver.

Ce guide mène le changement de telle sorte que cette fenêtre n'apparaisse jamais : pendant toute la manipulation, le serveur écoute en même temps sur l'ancien et sur le nouveau port, et l'ancien ne disparaît qu'une fois le nouveau vérifié.

Toutes les indications valent pour Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS et Ubuntu 22.04 LTS. Une section distincte traite de SELinux sur les systèmes RHEL comme AlmaLinux et Rocky Linux. Les commandes sont écrites pour une exécution en tant que root. Si vous travaillez avec un compte utilisateur normal, faites précéder chaque commande de sudo. Le port d'exemple est 2222, l'adresse d'exemple 203.0.113.10.

Ce qu'un autre port apporte, et ce qu'il n'apporte pas

Aucun gain de sécurité. Un scan complet des 65535 ports trouve le service malgré tout, et la bannière de version qu'OpenSSH envoie à l'établissement de la connexion révèle immédiatement de quoi il s'agit, y compris sur le port 51022. Le changement de port ne remplace aucune des mesures qui agissent réellement : connexion par clé au lieu du mot de passe, authentification par mot de passe désactivée, un filtre de paquets restrictif.

Moins de bruit dans les logs, et ce n'est pas rien. L'essentiel de ce qui arrive sur le port 22 relève du balayage de masse, sans cible précise. Ces outils testent le port 22 et rien d'autre, parce qu'un scan complet de l'Internet entier ne serait pas rentable. Déplacez le service et cette classe de trafic disparaît du journal, ce qui rend enfin visible la tentative de connexion isolée et ciblée.

Un coût qu'il faut intégrer. Chaque outil aura désormais besoin de l'indication du port : scripts de sauvegarde, séquences de déploiement, monitoring. Et un point que presque tous les guides passent sous silence : les réseaux d'entreprise, les WiFi d'hôtel et certains forfaits mobiles n'autorisent en sortie qu'une poignée de ports, le plus souvent 22, 80 et 443. Depuis de tels réseaux, vous risquez ensuite de ne plus atteindre votre serveur du tout.

En bref : faites-le si vous voulez des logs calmes. Ne le faites pas en croyant avoir réglé un problème de sécurité.

Le chemin de retour, avant de modifier quoi que ce soit

1. Ouvrir une fois la console dans l'espace client

Chaque serveur root KVM et chaque serveur dédié chez KernelHost dispose d'une console VNC dans l'espace client. Elle est branchée sur la sortie écran du système et reste indépendante de la pile réseau du serveur, si bien qu'une règle de pare-feu erronée ne peut pas la bloquer. Connectez-vous-y une fois avant de commencer et assurez-vous de connaître le mot de passe root. Une voie de secours que l'on essaie seulement le jour de l'urgence n'en est pas une.

2. Deux sessions, et la première reste ouverte

Connectez-vous une deuxième fois avant de commencer. Les connexions SSH existantes survivent aussi bien au redémarrage du service qu'à la fermeture de l'ancien port dans le pare-feu, parce que leur état de connexion est déjà établi. Vous gardez donc un shell root même lorsque vous vous êtes depuis longtemps coupé l'accès pour toute nouvelle connexion. C'est précisément le piège : tout paraît en ordre jusqu'au moment où vous fermez la fenêtre.

3. Une minuterie qui annule la modification d'elle-même

Si les deux sessions venaient à tomber, par exemple parce que votre propre accès Internet lâche, cette tâche annule le changement de port au bout de quinze minutes :

systemd-run --on-active=15min --unit=ssh-portrollback /bin/sh -c 'rm -f /etc/ssh/sshd_config.d/20-port.conf /etc/systemd/system/ssh.socket.d/override.conf; systemctl daemon-reload; systemctl try-restart ssh.socket ssh.service'

Vérification : systemctl list-timers ssh-portrollback.timer affiche l'heure de déclenchement. Si tout a fonctionné, annulez la tâche, sinon votre modification sera défaite plus tard, en pleine exploitation :

systemctl stop ssh-portrollback.timer

L'ordre des opérations qui ne coupe l'accès à personne

Cette séquence est conçue de manière qu'à aucun moment l'ancien chemin ne soit déjà fermé alors que le nouveau n'est pas encore ouvert.

  1. Choisir le port et vérifier qu'il est libre.
  2. Le pare-feu d'abord : ouvrir le nouveau port, laisser l'ancien ouvert.
  3. Faire écouter sshd sur les deux ports.
  4. En cas d'activation par socket, adapter en plus l'unité socket.
  5. Redémarrer et vérifier sur le socket réellement ouvert.
  6. Se connecter par le nouveau port avec une troisième session, entièrement nouvelle.
  7. Seulement maintenant, retirer le port 22 et mettre les outils à jour.

Étape 1 : choisir le port

Pas 2222. C'est le port de repli le plus courant et les scanners de masse le testent depuis longtemps. Nous ne l'employons ici que parce qu'il se lit bien dans les exemples.

Restez en dessous de 32768. La plage dans laquelle le noyau puise les ports source des connexions sortantes se lit ici :

cat /proc/sys/net/ipv4/ip_local_port_range

La sortie habituelle est 32768 60999. Un port de cette plage peut être occupé temporairement par une connexion sortante. La plupart du temps cela se passe bien, mais après un redémarrage, lorsque d'autres services démarrent avant sshd, la tentative de liaison échoue avec Address already in use et le serveur remonte sans SSH. Le phénomène est sporadique et pénible à localiser.

En dessous de 1024, il y a un vrai avantage. Seul root peut occuper les ports inférieurs à 1024. Si sshd tombe, aucun utilisateur non privilégié ne peut donc s'y installer pour faire tourner un faux service SSH qui enregistrerait les identifiants. Avec plusieurs comptes utilisateurs, c'est un argument ; avec un administrateur unique, cela reste plutôt théorique.

Vérification : le port ne doit être ni occupé ni réservé à un service que vous comptez faire tourner plus tard. Les deux commandes ne doivent rien afficher :

ss -tlnp | grep -E ':2222 '
grep -w 2222 /etc/services

Étape 2 : le pare-feu d'abord

Cette étape vient avant la configuration de sshd, pas après. Un port ouvert sans service derrière est inoffensif, alors qu'un service sans port ouvert vous coupe l'accès.

ufw allow 2222/tcp comment 'nouveau SSH'
ufw status verbose

Vérification : la sortie doit maintenant contenir les deux ports, et chacun deux fois, une fois pour IPv4 et une fois avec la mention (v6). Si la ligne IPv6 manque, le nouveau port n'est pas joignable en IPv6, or les clients récents tentent IPv6 en premier. Les détails figurent dans notre guide sur le pare-feu UFW.

Si vous entretenez nftables à la main, ajoutez le port dans votre fichier de règles, rechargez-le, puis contrôlez le jeu de règles chargé avec nft list ruleset | grep 2222. Sur les systèmes RHEL avec firewalld :

firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload
firewall-cmd --list-ports

Deux endroits passent régulièrement à la trappe. D'abord fail2ban : si un blocage s'y déclenche, il continue après le changement à ne bloquer que le port 22, pendant que les tentatives sur le nouveau port passent. Ajoutez le port dans /etc/fail2ban/jail.local :

[sshd]
enabled = true
port    = 2222

La détection continue de fonctionner, car fail2ban lit les tentatives de connexion dans le journal et ne se fixe pas sur le port. Seul l'effet de blocage dépend de cette ligne, voir notre guide sur fail2ban. Ensuite un filtre de paquets placé en amont, à l'extérieur du serveur, faute de quoi vous chercherez l'erreur au mauvais endroit.

Étape 3 : sshd_config et le piège sshd_config.d

Ne touchez pas à /etc/ssh/sshd_config. Les quatre systèmes lisent de la configuration supplémentaire dans /etc/ssh/sshd_config.d/, et un fichier qui vous appartient y survit aux mises à jour de paquets sans poser de question. Regardez d'abord ce qui s'y trouve déjà :

ls -l /etc/ssh/sshd_config.d/
grep -n '^Include' /etc/ssh/sshd_config

Chez Debian et Ubuntu, la ligne Include se trouve tout en haut en sortie d'usine, en général à la ligne 12. C'est plus important qu'il n'y paraît : pour la plupart des directives, c'est la première valeur trouvée qui l'emporte, pas la dernière. Comme l'include est en tête, les fichiers du répertoire priment sur tout ce qui suit plus bas dans sshd_config. S'il a été déplacé en fin de fichier, la logique s'inverse et votre fichier reste sans effet.

Pour Port, il existe une exception, et c'est précisément elle qui rend le changement sans risque possible : plusieurs lignes Port ne se remplacent pas, elles s'additionnent. sshd écoute alors sur tous les ports mentionnés. Le revers est tout aussi important : la valeur par défaut 22 ne s'applique que tant qu'aucune ligne Port n'existe. Dès que vous en écrivez une, le 22 disparaît si vous ne le mentionnez pas explicitement.

tee /etc/ssh/sshd_config.d/20-port.conf >/dev/null <<'EOF'
Port 22
Port 2222
EOF
chmod 644 /etc/ssh/sshd_config.d/20-port.conf

Vérification : d'abord la syntaxe, ensuite la configuration effective complète, avec les fichiers inclus résolus :

sshd -t
sshd -T | grep -E '^(port|listenaddress) '

Deux lignes sont attendues, port 22 et port 2222. Si une ligne listenaddress apparaît en plus, c'est le second endroit où des ports peuvent figurer : ListenAddress peut indiquer une adresse assortie d'un port et restreint alors ce sur quoi le service écoute. Une ligne passée inaperçue comme ListenAddress 127.0.0.1 explique la majorité des cas où le port est correctement configuré alors que personne n'arrive depuis l'extérieur.

Si sshd -t renvoie à la place Missing privilege separation directory: /run/sshd, c'est que le service n'a jamais tourné depuis le démarrage du système, et mkdir -p /run/sshd règle le problème.

Étape 4 : l'activation par socket, quand le port ne figure pas dans sshd_config

C'est ici que les distributions divergent, et c'est ici que se produisent la plupart des accidents. Depuis la 22.10, Ubuntu mise sur l'activation par socket : ce n'est pas sshd qui détient le port, mais systemd. Il écoute à sa place et ne démarre un processus sshd qu'à l'arrivée d'une connexion. Le port figure alors dans l'unité ssh.socket, sous ListenStream, et une ligne Port dans la configuration de sshd peut rester sans effet.

Ne devinez pas, interrogez le système :

systemctl is-enabled ssh.socket ssh.service
SystèmeActif en sortie d'usineD'où vient le port
Debian 13 (trixie)ssh.service/etc/ssh/sshd_config.d/
Debian 12 (bookworm)ssh.service/etc/ssh/sshd_config.d/
Ubuntu 24.04 LTSssh.socketListenStream dans l'unité socket
Ubuntu 22.04 LTSssh.service/etc/ssh/sshd_config.d/

Le tableau décrit l'état à la livraison, pas nécessairement votre serveur : les images de provenances différentes s'en écartent, et un système mis à jour conserve son réglage précédent. Si ssh.socket est actif, systemctl cat affiche l'unité avec tous ses fichiers complémentaires et leurs chemins, y compris ceux générés automatiquement :

systemctl cat ssh.socket

Vous déposez le nouveau port dans un fichier complémentaire qui vous appartient. La première ligne ListenStream=, laissée vide, efface les valeurs existantes, et seules les vôtres comptent ensuite. Sans cette ligne de remise à zéro, les valeurs d'origine s'ajouteraient aux vôtres :

mkdir -p /etc/systemd/system/ssh.socket.d
tee /etc/systemd/system/ssh.socket.d/override.conf >/dev/null <<'EOF'
[Socket]
ListenStream=
ListenStream=0.0.0.0:22
ListenStream=[::]:22
ListenStream=0.0.0.0:2222
ListenStream=[::]:2222
EOF
systemctl daemon-reload

Ici aussi, les deux ports coexistent, pour la même raison qu'à l'étape 3. Un fichier placé sous /etc/systemd/system/ prime sur tout ce que le système génère lui-même.

Vérification : systemctl cat ssh.socket liste désormais votre fichier comme un bloc distinct.

Si ssh.service et ssh.socket sont actifs en même temps, ils se disputent le même port. Cela se manifeste par fatal: Cannot bind any address. ou ssh.socket: Socket service ssh.service already active, refusing. Choisissez alors l'un des deux modes de fonctionnement, le contexte est détaillé dans notre guide sur la sécurisation de SSH.

Étape 5 : redémarrer et vérifier sur le socket

Une commande valable sur les quatre systèmes, parce que try-restart ne redémarre que ce qui tourne réellement et laisse l'autre unité intacte :

sshd -t && systemctl try-restart ssh.socket ssh.service

N'utilisez pas reload : sur les systèmes en activation par socket, il répond fatal: Cannot bind any address. et le service a ensuite lâché son port. Et pas non plus un systemctl restart ssh.socket isolé : sur Debian il échoue, sur Ubuntu 22.04 il bascule discrètement l'hôte en mode socket. Les sessions existantes survivent au redémarrage dans tous les cas.

La vérification, et c'est la seule qui compte vraiment :

ss -tlnp | grep -E ':(22|2222) '

Quatre lignes sont attendues : 0.0.0.0:22, [::]:22, 0.0.0.0:2222 et [::]:2222. Si les lignes IPv6 manquent, vous n'atteindrez pas le serveur en IPv6.

Une particularité qui déclenche des paniques inutiles : avec l'activation par socket, la dernière colonne affiche parfois systemd au lieu de sshd, parce que systemd détient le socket en écoute tant qu'aucun processus sshd ne tourne. Filtrez donc sur le numéro de port, pas sur le nom du processus, sinon vous prendrez un service en parfait état de marche pour un service mort.

Étape 6 : la troisième session, le vrai test

Maintenant, et pas une étape plus tôt, ouvrez un nouveau terminal. Les deux anciennes sessions restent ouvertes.

ssh -p 2222 root@203.0.113.10

Si cela ne fonctionne pas, ssh -vv -p 2222 root@203.0.113.10 montre à quel endroit l'échec se produit.

Une question de confirmation est normale à ce stade : SSH redemande l'authenticité de la clé d'hôte alors que rien n'a changé sur le serveur. Les entrées de known_hosts sont en effet liées au port et, pour un port différent, elles sont enregistrées sous la forme [203.0.113.10]:2222. Pour vérifier et, en cas de doute, supprimer :

ssh-keygen -F '[203.0.113.10]:2222'
ssh-keygen -R '[203.0.113.10]:2222'

C'est aussi le bon moment pour vérifier que la manipulation survit à un redémarrage. Grâce à l'autorisation encore ouverte pour le port 22, l'opération est sans danger.

Étape 7 : fermer le port 22 et mettre les outils à jour

Ce n'est qu'une fois l'étape 6 réussie que vous retirez l'ancien port. Il ne reste plus qu'une seule ligne dans 20-port.conf :

tee /etc/ssh/sshd_config.d/20-port.conf >/dev/null <<'EOF'
Port 2222
EOF
sshd -t && systemctl try-restart ssh.socket ssh.service

En activation par socket, supprimez en plus les deux lignes contenant le port 22 dans /etc/systemd/system/ssh.socket.d/override.conf, puis enchaînez avec systemctl daemon-reload. Ensuite le pare-feu :

ufw delete allow 22/tcp
ufw status verbose

Vérification : ss -tlnp | grep -E ':(22|2222) ' n'affiche plus que le nouveau port, de nouveau dans les deux familles d'adresses.

Reste la partie dont l'écho dure le plus longtemps : tous les outils qui s'adressent au serveur. Le plus commode est de régler cela une fois pour toutes dans ~/.ssh/config :

Host mon-serveur
    HostName 203.0.113.10
    Port 2222
    User kernel

Partout où vous indiquez l'adresse directement, il vous faut préciser le port, et l'écriture change d'un outil à l'autre. C'est le piège classique :

OutilIndication du portExemple
ssh-p (minuscule)ssh -p 2222 kernel@203.0.113.10
scp-P (majuscule)scp -P 2222 fichier.tar.gz kernel@203.0.113.10:/tmp/
sftp-P (majuscule)sftp -P 2222 kernel@203.0.113.10
ssh-copy-id-p (minuscule)ssh-copy-id -p 2222 kernel@203.0.113.10
rsyncvia -ersync -av -e 'ssh -p 2222' ./donnees/ kernel@203.0.113.10:/srv/
gitdans l'URLssh://git@203.0.113.10:2222/srv/repo.git

rsync --port concerne d'ailleurs le daemon rsync et non SSH, il n'a aucun effet ici. Dans Ansible, le port se note ansible_port dans l'inventaire.

SELinux sur les systèmes RHEL

Sur AlmaLinux, Rocky Linux et RHEL, SELinux tourne en sortie d'usine en mode enforcing, et la politique n'autorise sshd que sur les ports étiquetés ssh_port_t. Par défaut, il n'y a que le port 22. Sans cette étape supplémentaire, le service ne démarre pas, et le message ressemble à tort à un problème de droits :

error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.

D'abord un coup d'œil sur l'état et sur l'étiquetage existant :

getenforce
semanage port -l | grep ssh_port_t

Si semanage manque, il se trouve dans le paquet policycoreutils-python-utils :

dnf install -y policycoreutils-python-utils

Ajoutez le nouveau port, et faites-le avant de redémarrer sshd :

semanage port -a -t ssh_port_t -p tcp 2222

Si le port est déjà associé à un autre type, -a échoue en signalant qu'il est déjà défini. Modifiez alors l'association avec -m au lieu d'en ajouter une nouvelle.

Vérification : semanage port -l | grep ssh_port_t liste maintenant les deux ports. Si quelque chose coince malgré tout, les accès refusés s'affichent ainsi :

ausearch -m avc -ts recent

Debian et Ubuntu n'imposent aucune restriction comparable en installation standard, cette section ne les concerne donc pas.

Erreurs fréquentes et solutions

ssh: connect to host 203.0.113.10 port 2222: Connection refused : les paquets arrivent, mais personne n'écoute. Le service n'a pas été redémarré, la configuration n'est pas passée, ou une ligne ListenAddress le lie à une autre adresse.

ssh: connect to host 203.0.113.10 port 2222: Connection timed out : les paquets n'arrivent même pas, ce qui trahit presque toujours un filtre de paquets sur le serveur ou dans votre propre réseau. L'écart entre ce message et le précédent est l'information de diagnostic la plus précieuse qui soit : refusé signifie service absent, dépassement de délai signifie filtre.

error: Bind to port 2222 on 0.0.0.0 failed: Permission denied. : sur les systèmes RHEL, c'est SELinux, voir plus haut. Sur Debian et Ubuntu, ce message n'apparaît pratiquement que si sshd ne tourne pas en tant que root et doit occuper un port inférieur à 1024.

error: Bind to port 2222 on 0.0.0.0 failed: Address already in use. : un autre processus détient le port, ss -tlnp | grep ':2222 ' le nomme. Si l'erreur ne survient que sporadiquement après un redémarrage, le port se situe dans la plage des ports source dynamiques, voir l'étape 1.

fatal: Cannot bind any address. : aucune des adresses demandées n'a pu être occupée. Sur Debian et Ubuntu, cela signifie en règle générale que ssh.socket détient déjà le port et que vous voulez démarrer ssh.service par-dessus.

Job for ssh.service failed because the control process exited with error code. : la cause se trouve dans le journal, pas dans cette ligne. journalctl -u ssh -n 50 --no-pager l'affiche, quelle que soit la version d'OpenSSH.

/etc/ssh/sshd_config.d/20-port.conf line 1: Bad configuration option: prot : une faute de frappe. sshd -t indique le fichier et le numéro de ligne, c'est exactement pour cela que cette commande précède chaque redémarrage.

sshd: no hostkeys available -- exiting. : les clés d'hôte manquent ou ne sont pas lisibles, ssh-keygen -A génère celles qui manquent. sshd -t et sshd -T ont besoin des droits de lecture dessus et doivent donc s'exécuter en tant que root.

ssh: connect to host 203.0.113.10 port 22: Connection refused après un changement réussi : votre client tente toujours le port par défaut. Complétez ~/.ssh/config ou passez l'option -p.

Si vous vous êtes tout de même coupé l'accès

  1. Ne redémarrez pas. Un redémarrage rétablit les règles de pare-feu et la configuration du service, le serveur revient tout aussi fermé.
  2. Ouvrez la console VNC dans l'espace client et connectez-vous en tant que root. La connexion par la console ne passe pas par SSH et n'est pas affectée par votre modification.
  3. Déterminez la classe d'erreur. ss -tlnp y répond immédiatement : si le port y figure, c'est un problème de filtrage. S'il n'y figure pas, c'est un problème de service, et journalctl -u ssh -n 50 --no-pager dit pourquoi.
  4. Revenez en arrière au lieu de réparer. rm -f /etc/ssh/sshd_config.d/20-port.conf et, s'il a été créé, rm -f /etc/systemd/system/ssh.socket.d/override.conf, puis systemctl daemon-reload et systemctl try-restart ssh.socket ssh.service.
  5. Si le pare-feu était en cause, ufw disable vous dépanne, suivi d'une reconstruction propre avec la bonne autorisation de port.

En résumé

  • Le pare-feu d'abord, sshd ensuite. L'ancien port reste ouvert jusqu'à ce que le nouveau soit vérifié.
  • Plusieurs lignes Port s'additionnent, ce qui rend la transition sans risque. La valeur par défaut 22 disparaît dès qu'une ligne Port quelconque existe.
  • En activation par socket, active en sortie d'usine sur Ubuntu 24.04, le port figure dans ListenStream.
  • Ce qui fait foi n'est jamais le fichier de configuration, mais ss -tlnp, filtré sur le numéro de port.
  • La voie de secours est la console VNC dans l'espace client, gardez donc le mot de passe root sous la main.

Si vous êtes en train de mettre le serveur en service, notre checklist pour un nouveau serveur root replace cette étape dans le reste de la configuration de base. Et pour bien situer les choses une dernière fois : un autre port rend vos logs lisibles. Ce qui sécurise l'accès, c'est la connexion par clé et l'authentification par mot de passe désactivée. Si vous ne mettez en œuvre qu'une seule des deux mesures, prenez la seconde.

Questions fréquentes

Un autre port SSH apporte-t-il plus de sécurité ?
Non. Un scan complet des 65535 ports trouve le service malgré tout, et la bannière de version qu'OpenSSH envoie à l'établissement de la connexion révèle immédiatement de quoi il s'agit, y compris sur le port 51022. Le vrai bénéfice est ailleurs : l'essentiel de ce qui arrive sur le port 22 relève du balayage de masse sans cible précise, et ces outils testent le port 22 et rien d'autre. Après le changement, cette classe de trafic disparaît du journal, ce qui rend enfin visible la tentative de connexion isolée et ciblée. Ce qui sécurise l'accès, c'est la connexion par clé, l'authentification par mot de passe désactivée et un filtre de paquets restrictif.
Quel port faut-il choisir ?
Pas 2222, car c'est le port de repli le plus courant et les scanners de masse le testent depuis longtemps. Restez en dessous de 32768 : c'est là que commence habituellement la plage dans laquelle le noyau puise les ports source des connexions sortantes, à lire dans /proc/sys/net/ipv4/ip_local_port_range. Un port de cette plage peut être occupé temporairement, et après un redémarrage la tentative de liaison échoue alors sporadiquement avec Address already in use, pendant que le serveur remonte sans SSH. Seul root peut occuper les ports inférieurs à 1024, si bien qu'aucun utilisateur non privilégié ne peut s'y installer avec un faux service SSH pour enregistrer les identifiants. Vérifiez au préalable avec ss -tlnp et avec grep -w 2222 /etc/services que le port est libre et n'est réservé à aucun autre service.
Comment changer le port sans me couper l'accès ?
En faisant écouter le serveur sur les deux ports pendant la manipulation. L'ordre est le suivant : ouvrir le nouveau port dans le pare-feu et laisser l'ancien ouvert, faire écouter sshd sur les deux ports, redémarrer, se connecter par le nouveau port avec une troisième session entièrement nouvelle, et retirer le port 22 seulement après. Une particularité d'OpenSSH rend cela possible : plusieurs lignes Port ne se remplacent pas, elles s'additionnent. Le revers est tout aussi important : la valeur par défaut 22 ne s'applique que tant qu'aucune ligne Port n'existe. Dès que vous en écrivez une, vous devez mentionner le 22 explicitement, sinon il disparaît.
Ma ligne Port reste sans effet, sshd n'écoute toujours que sur le 22. D'où cela vient-il ?
Deux causes entrent en ligne de compte. D'abord l'activation par socket : Ubuntu mise dessus depuis la 22.10 et la livre active sur Ubuntu 24.04. Ce n'est alors pas sshd qui détient le port, mais systemd, et ce qui fait foi est ListenStream dans l'unité ssh.socket, pas la ligne Port de la configuration sshd. La commande systemctl is-enabled ssh.socket ssh.service vous dit quel mode tourne chez vous. Ensuite l'ordre des includes : pour la plupart des directives, c'est la première valeur trouvée qui l'emporte, et chez Debian comme chez Ubuntu la ligne Include pour /etc/ssh/sshd_config.d/ se trouve tout en haut en sortie d'usine. Si elle a été déplacée en fin de fichier, votre fichier reste sans effet. Ce qui s'applique réellement, sshd -T le montre, filtré sur les lignes port et listenaddress. Si une ligne listenaddress y apparaît, elle restreint en plus ce sur quoi le service écoute.
Quelle est la différence entre Connection refused et Connection timed out ?
C'est l'information de diagnostic la plus précieuse qui soit. ssh: connect to host 203.0.113.10 port 2222: Connection refused signifie que les paquets arrivent, mais que personne n'écoute : le service n'a pas été redémarré, la configuration n'est pas passée, ou une ligne ListenAddress le lie à une autre adresse. ssh: connect to host 203.0.113.10 port 2222: Connection timed out signifie au contraire que les paquets n'arrivent même pas, et c'est presque toujours un filtre de paquets sur le serveur ou dans votre propre réseau. En résumé : refusé signifie service absent, dépassement de délai signifie filtre.
Sur AlmaLinux et Rocky Linux, sshd ne démarre pas : error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.
C'est SELinux et non un problème de droits, même si le message y ressemble. Sur les systèmes RHEL, SELinux tourne en sortie d'usine en mode enforcing, et la politique n'autorise sshd que sur les ports étiquetés ssh_port_t. Par défaut, il n'y a que le port 22. Étiquetez le nouveau port avant de redémarrer le service : semanage port -a -t ssh_port_t -p tcp 2222. Si semanage manque, il se trouve dans le paquet policycoreutils-python-utils. Si le port est déjà associé à un autre type, -a échoue en signalant qu'il est déjà défini, et vous modifiez alors l'association avec -m. Les accès refusés s'affichent avec ausearch -m avc -ts recent. Debian et Ubuntu n'imposent aucune restriction comparable en installation standard.
Que faut-il encore adapter après le changement ?
D'abord fail2ban : si un blocage s'y déclenche, il continue sinon à ne bloquer que le port 22, pendant que les tentatives sur le nouveau port passent. Ajoutez le port dans la section sshd de /etc/fail2ban/jail.local. La détection continue de toute façon de fonctionner, car fail2ban lit les tentatives de connexion dans le journal, seul l'effet de blocage dépend de cette ligne. Ensuite tous les outils qui s'adressent au serveur : le plus commode est de régler cela une fois pour toutes avec une entrée Host assortie du port dans ~/.ssh/config. Partout où vous indiquez l'adresse directement, l'écriture change d'un outil à l'autre : ssh et ssh-copy-id prennent -p en minuscule, scp et sftp -P en majuscule, rsync reçoit le port via l'option -e, git dans l'URL, Ansible comme ansible_port dans l'inventaire. rsync --port concerne en revanche le daemon rsync et n'a aucun effet ici. Que SSH redemande l'authenticité de la clé d'hôte au premier établissement de connexion est normal : les entrées de known_hosts sont liées au port et sont enregistrées sous la forme [203.0.113.10]:2222.
Je me suis coupé l'accès. Que faire maintenant ?
Ne redémarrez pas le serveur, il rétablit les règles de pare-feu et la configuration du service et revient tout aussi fermé. Ouvrez plutôt la console VNC dans votre espace client et connectez-vous en tant que root, car la connexion par la console ne passe pas par SSH et n'est pas affectée par votre modification. La commande ss -tlnp répond immédiatement sur la classe d'erreur : si le port y figure, c'est un problème de filtrage, s'il n'y figure pas, un problème de service, et journalctl -u ssh -n 50 --no-pager dit pourquoi. Revenez ensuite en arrière au lieu de réparer : supprimez /etc/ssh/sshd_config.d/20-port.conf et, s'il a été créé, /etc/systemd/system/ssh.socket.d/override.conf, puis lancez systemctl daemon-reload et systemctl try-restart ssh.socket ssh.service. Si le pare-feu était en cause, ufw disable vous dépanne, suivi d'une reconstruction propre avec la bonne autorisation de port.

SSH OpenSSH sshd Sécurité des serveurs Debian Ubuntu systemd SELinux