SSH-poort wijzigen zonder uzelf buiten te sluiten: sshd, socketactivering en SELinux

Gepubliceerd op 15 min leestijd

Het wijzigen van de SSH-poort loopt bijna altijd mis op de volgorde. Deze handleiding laat de server ondertussen op beide poorten luisteren, zodat de oude pas verdwijnt als de nieuwe aantoonbaar werkt.

Het wijzigen van de SSH-poort is een van de meest gegeven en slechtst onderbouwde adviezen in het serverbeheer. Het levert werkelijk iets op, alleen iets anders dan er meestal aan wordt toegeschreven, en er hoort een bijwerking bij: tussen het moment waarop de dienst de oude poort loslaat en het moment waarop de nieuwe door alle pakketfilters heen bereikbaar is, gaapt een gat. Wie daar niet op rekent, loopt er vanzelf in.

Deze handleiding voert de wijziging zo uit dat dat gat helemaal niet ontstaat: tijdens de ombouw luistert de server tegelijk op de oude en de nieuwe poort, en de oude verdwijnt pas als de nieuwe aantoonbaar werkt.

Alle gegevens gelden voor Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS en Ubuntu 22.04 LTS. Een apart hoofdstuk behandelt SELinux op RHEL-systemen zoals AlmaLinux en Rocky Linux. De commando's zijn geschreven voor gebruik als root. Werkt u als gewone gebruiker, zet dan sudo voor elk commando. Als voorbeeldpoort gebruiken wij 2222, als voorbeeldadres 203.0.113.10.

Wat een andere poort oplevert, en wat niet

Geen winst voor de beveiliging. Een volledige portscan over alle 65.535 poorten vindt de dienst toch wel, en de versiebanner die OpenSSH bij de verbindingsopbouw stuurt, verraadt ook op poort 51022 meteen waar het om gaat. Een andere poort vervangt geen enkele van de maatregelen die wel werken: inloggen met een sleutel in plaats van een wachtwoord, een uitgeschakelde wachtwoordlogin en een strak pakketfilter.

Minder ruis in de logs, en dat is geen kleinigheid. Verreweg het meeste van wat op poort 22 binnenkomt, is ongericht massascannen. Die tools proberen poort 22 en verder niets, omdat een volledige scan over het hele internet niet loont. Verplaatst u de dienst, dan verdwijnt die verkeersklasse uit het journal, en pas daardoor valt die ene gerichte inlogpoging op.

Kosten waar u rekening mee moet houden. Voortaan heeft elke tool de poort nodig: back-upscripts, uitrolprocessen, monitoring. En een punt dat vrijwel alle handleidingen weglaten: bedrijfsnetwerken, hotelwifi en sommige mobiele abonnementen laten uitgaand maar een handvol poorten toe, meestal 22, 80 en 443. Vanuit zo'n netwerk komt u daarna mogelijk helemaal niet meer bij uw server.

Kort samengevat: doe het als u rustige logs wilt. Doe het niet in de veronderstelling dat u daarmee een beveiligingsprobleem hebt opgelost.

De weg terug, voordat u iets wijzigt

1. Open de console in het klantenpaneel één keer

Elke KVM-rootserver en elke dedicated server bij KernelHost heeft een VNC-console in het klantenpaneel. Die kijkt rechtstreeks naar de schermuitvoer van het systeem en staat los van de netwerkstack van de server, een verkeerde firewallregel kan hem daarom niet blokkeren. Log daar vooraf één keer in en controleer of u het rootwachtwoord kent. Een noodtoegang die u pas tijdens het incident voor het eerst uitprobeert, is geen noodtoegang.

2. Twee sessies, en de eerste blijft open

Log een tweede keer in voordat u begint. Bestaande SSH-verbindingen overleven zowel een herstart van de dienst als het sluiten van de oude poort in de firewall, omdat de verbindingsstatus al tot stand gebracht is. U houdt dus een root-shell, zelfs wanneer u zichzelf voor nieuwe verbindingen allang hebt buitengesloten. Precies daar zit de valkuil: alles ziet er goed uit, totdat u dat venster sluit.

3. Een tijdschakelaar die de wijziging zelf terugdraait

Vallen beide sessies weg, bijvoorbeeld doordat uw eigen internetverbinding uitvalt, dan draait deze taak de poortwijziging na vijftien minuten terug:

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'

Controle: systemctl list-timers ssh-portrollback.timer toont wanneer de taak afgaat. Heeft alles gewerkt, breek de taak dan af, anders draait uw wijziging later midden in de productie terug:

systemctl stop ssh-portrollback.timer

De volgorde die niemand buitensluit

Deze reeks is zo opgebouwd dat de oude weg op geen enkel moment al dicht is terwijl de nieuwe nog niet open staat.

  1. Kies een poort en controleer of die vrij is.
  2. Eerst de firewall: open de nieuwe poort en laat de oude open.
  3. Laat sshd op beide poorten luisteren.
  4. Pas bij socketactivering ook de socket-unit aan.
  5. Herstart en controleer op de luisterende socket.
  6. Log met een derde, verse sessie in via de nieuwe poort.
  7. Verwijder pas nu poort 22 en werk de tools bij.

Stap 1: De poort kiezen

Niet 2222. Deze poort is de meestgekozen uitwijkoptie en wordt door massascanners allang meegenomen. Wij gebruiken hem hier alleen omdat hij prettig leesbaar is als voorbeeld.

Blijf onder 32768. Het bereik waaruit de kernel bronpoorten voor uitgaande verbindingen toekent, staat hier:

cat /proc/sys/net/ipv4/ip_local_port_range

Gebruikelijk is de uitvoer 32768 60999. Een poort uit dat bereik kan tijdelijk door een uitgaande verbinding bezet worden. Meestal gaat dat goed, maar na een herstart, wanneer andere diensten vóór sshd starten, mislukt de bindpoging met Address already in use en komt de server zonder SSH op. Dat gebeurt sporadisch en is lastig te achterhalen.

Onder 1024 heeft een echt voordeel. Poorten onder 1024 mag alleen root bezetten. Valt sshd uit, dan kan daar dus geen gebruiker zonder rootrechten inhaken en een nagemaakte SSH-dienst draaien die inloggegevens meeschrijft. Bij meerdere gebruikersaccounts is dat een argument, bij één enkele beheerder blijft het vooral theoretisch.

Controle: de poort mag niet bezet zijn en ook niet gereserveerd voor een dienst die u later wilt draaien. Beide commando's horen geen uitvoer te geven:

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

Stap 2: Eerst de firewall

Deze stap komt vóór de sshd-configuratie, niet erna. Een open poort zonder dienst erachter is ongevaarlijk, een dienst zonder open poort sluit u buiten.

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

Controle: in de uitvoer moeten nu beide poorten staan, elk twee keer, één keer voor IPv4 en één keer met de toevoeging (v6). Ontbreekt de IPv6-regel, dan is de nieuwe poort via IPv6 niet bereikbaar, en moderne clients proberen IPv6 als eerste. Details staan in onze handleiding over de UFW-firewall.

Beheert u nftables met de hand, vul de poort dan aan in uw regelbestand, laad dat opnieuw en controleer de geladen regelset met nft list ruleset | grep 2222. Op RHEL-systemen met firewalld:

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

Twee plekken worden over het hoofd gezien. Ten eerste fail2ban: geldt daar een blokkade, dan blokkeert die na de wijziging nog steeds alleen poort 22, terwijl de pogingen op de nieuwe poort gewoon doorkomen. Vul de poort aan in /etc/fail2ban/jail.local:

[sshd]
enabled = true
port    = 2222

De detectie blijft werken, omdat fail2ban de inlogpogingen uit het journal leest en zich niet op de poort baseert. Alleen de blokkade hangt aan deze regel, zie onze handleiding over fail2ban. Ten tweede een voorgeschakeld pakketfilter buiten de server, anders zoekt u de fout op de verkeerde plek.

Stap 3: sshd_config en de valkuil sshd_config.d

Laat /etc/ssh/sshd_config ongemoeid. Alle vier de systemen lezen aanvullende configuratie uit /etc/ssh/sshd_config.d/, en een eigen bestand daar overleeft pakketupdates zonder tussenvragen. Kijk eerst wat er al staat:

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

Bij Debian en Ubuntu staat de Include-regel standaard helemaal bovenaan, meestal op regel 12. Dat is belangrijker dan het lijkt: bij de meeste directives wint de eerst gevonden waarde, niet de laatste. Doordat de include bovenaan staat, verslaan de bestanden in die map alles wat verderop in sshd_config volgt. Is hij naar het einde van het bestand verplaatst, dan draait dat om en blijft uw bestand zonder effect.

Voor Port geldt een uitzondering, en precies die maakt de risicoloze wijziging mogelijk: meerdere Port-regels vervangen elkaar niet, ze tellen op. sshd luistert dan op alle genoemde poorten. De keerzijde is even belangrijk: de standaardwaarde 22 geldt alleen zolang er helemaal geen Port-regel bestaat. Zodra u er een schrijft, is 22 verdwenen, tenzij u die uitdrukkelijk mee opneemt.

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

Controle: eerst de syntaxis, daarna de werkzame totaalconfiguratie met opgeloste include-bestanden:

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

Verwacht worden twee regels, port 22 en port 2222. Verschijnt daarnaast een listenaddress-regel, dan is dat de tweede plek waar poorten kunnen staan: ListenAddress mag een adres samen met een poort noemen en beperkt daarmee waarop geluisterd wordt. Een over het hoofd geziene regel als ListenAddress 127.0.0.1 verklaart de meeste gevallen waarin de poort keurig geconfigureerd is, maar niemand van buitenaf binnenkomt.

Meldt sshd -t in plaats daarvan Missing privilege separation directory: /run/sshd, dan heeft de dienst sinds het opstarten van het systeem nooit gedraaid, en mkdir -p /run/sshd verhelpt dat.

Stap 4: Socketactivering, waar de poort niet in sshd_config staat

Hier lopen de distributies uiteen, en hier gaat het het vaakst mis. Ubuntu zet sinds 22.10 in op socketactivering: niet sshd houdt de poort vast, maar systemd. Dat luistert namens sshd en start pas bij een binnenkomende verbinding een sshd-proces. De poort staat dan in de unit ssh.socket onder ListenStream, en een Port-regel in de sshd-configuratie kan zonder effect blijven.

Gok niet, maar vraag het aan het systeem:

systemctl is-enabled ssh.socket ssh.service
SysteemStandaard actiefWaar de poort vandaan komt
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 in de socket-unit
Ubuntu 22.04 LTSssh.service/etc/ssh/sshd_config.d/

De tabel beschrijft de fabrieksinstelling, niet per se uw server: images uit verschillende bronnen wijken af, en een bijgewerkt systeem behoudt zijn eerdere instelling. Is ssh.socket actief, dan toont systemctl cat de unit met alle aanvullende bestanden en hun paden, ook de automatisch gegenereerde:

systemctl cat ssh.socket

De nieuwe poort legt u vast als een eigen aanvullend bestand. De eerste, lege ListenStream=-regel wist de bestaande waarden, daarna tellen uitsluitend die van u. Zonder deze terugzetregel zouden de standaardwaarden er nog bij komen:

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

Ook hier staan beide poorten naast elkaar, om dezelfde reden als in stap 3. Een bestand onder /etc/systemd/system/ heeft voorrang op alles wat het systeem zelf aanmaakt.

Controle: systemctl cat ssh.socket toont uw bestand nu als een eigen blok.

Zijn ssh.service en ssh.socket tegelijk actief, dan vechten ze om dezelfde poort. Dat uit zich in fatal: Cannot bind any address. of ssh.socket: Socket service ssh.service already active, refusing. Kies dan voor een van de twee werkwijzen, de achtergronden behandelt onze handleiding over het beveiligen van SSH.

Stap 5: Herstarten en op de socket controleren

Eén commando dat op alle vier de systemen klopt, omdat try-restart alleen herstart wat werkelijk draait en de andere unit ongemoeid laat:

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

Gebruik geen reload: op systemen met socketactivering antwoordt dat met fatal: Cannot bind any address., en heeft de dienst zijn poort daarna losgelaten. En ook geen los systemctl restart ssh.socket: op Debian mislukt dat, op Ubuntu 22.04 zet het de host ongemerkt om naar de socketmodus. Bestaande sessies doorstaan de herstart in elk geval.

De controle, en wel de enige die werkelijk telt:

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

Verwacht worden vier regels: 0.0.0.0:22, [::]:22, 0.0.0.0:2222 en [::]:2222. Ontbreken de IPv6-regels, dan bereikt u de server niet via IPv6.

Een eigenaardigheid die tot onnodige paniek leidt: bij socketactivering staat in de laatste kolom soms systemd in plaats van sshd, omdat systemd de luisterende socket vasthoudt zolang er geen sshd-proces draait. Filter daarom op het poortnummer en niet op de procesnaam, anders houdt u een werkende dienst voor dood.

Stap 6: De derde sessie, de eigenlijke test

Nu, en geen stap eerder, opent u een nieuw terminalvenster. De twee oude sessies blijven open.

ssh -p 2222 root@203.0.113.10

Lukt dat niet, dan laat ssh -vv -p 2222 root@203.0.113.10 zien op welk punt het misgaat.

Eén tussenvraag is daarbij normaal: SSH vraagt opnieuw naar de echtheid van de hostsleutel, hoewel er op de server niets veranderd is. Vermeldingen in known_hosts zijn namelijk poortgebonden en worden voor afwijkende poorten opgeslagen in de vorm [203.0.113.10]:2222. Opzoeken en bij twijfel verwijderen:

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

Of de ombouw een herstart doorstaat, controleert u het beste nu. Dankzij de nog openstaande vrijgave voor poort 22 is dat ongevaarlijk.

Stap 7: Poort 22 sluiten en de tools bijwerken

Pas als stap 6 gewerkt heeft, verwijdert u de oude poort. In 20-port.conf blijft nog maar één regel over:

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

Bij socketactivering schrapt u daarnaast de twee regels met poort 22 uit /etc/systemd/system/ssh.socket.d/override.conf en laat u systemctl daemon-reload volgen. Daarna de firewall:

ufw delete allow 22/tcp
ufw status verbose

Controle: ss -tlnp | grep -E ':(22|2222) ' toont nu alleen nog de nieuwe poort, opnieuw in beide adresfamilies.

Blijft het deel dat het langst doorwerkt: alle tools die de server aanspreken. Het handigst regelt u dat in één keer voorgoed in ~/.ssh/config:

Host mijn-server
    HostName 203.0.113.10
    Port 2222
    User kernel

Waar u het adres rechtstreeks opgeeft, hebt u de poortopgave nodig, en de schrijfwijze verschilt per tool. Dat is het klassieke struikelblok:

ToolPoortopgaveVoorbeeld
ssh-p (kleine letter)ssh -p 2222 kernel@203.0.113.10
scp-P (hoofdletter)scp -P 2222 bestand.tar.gz kernel@203.0.113.10:/tmp/
sftp-P (hoofdletter)sftp -P 2222 kernel@203.0.113.10
ssh-copy-id-p (kleine letter)ssh-copy-id -p 2222 kernel@203.0.113.10
rsyncvia -ersync -av -e 'ssh -p 2222' ./data/ kernel@203.0.113.10:/srv/
gitin de URLssh://git@203.0.113.10:2222/srv/repo.git

rsync --port slaat overigens op de rsync-daemon en niet op SSH, hier heeft die optie geen effect. In Ansible staat de poort als ansible_port in het inventory.

SELinux op RHEL-systemen

Op AlmaLinux, Rocky Linux en RHEL staat SELinux standaard in de modus enforcing, en het regelwerk staat sshd uitsluitend poorten toe die als ssh_port_t gelabeld zijn. Standaard is dat alleen poort 22. Zonder deze extra stap start de dienst niet, en de melding lijkt misleidend genoeg op een rechtenprobleem:

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

Eerst een blik op de status en op de bestaande labels:

getenforce
semanage port -l | grep ssh_port_t

Ontbreekt semanage, dan zit het in het pakket policycoreutils-python-utils:

dnf install -y policycoreutils-python-utils

Voeg de nieuwe poort toe, en wel voordat u sshd herstart:

semanage port -a -t ssh_port_t -p tcp 2222

Is de poort al aan een ander type toegewezen, dan mislukt -a met de melding dat hij al gedefinieerd is. Wijzig de toewijzing dan met -m in plaats van er een nieuwe bij te zetten.

Controle: semanage port -l | grep ssh_port_t noemt nu beide poorten. Hapert er daarna toch iets, dan tonen de geweigerde toegangspogingen zich hier:

ausearch -m avc -ts recent

Debian en Ubuntu kennen in de standaardinstallatie geen vergelijkbare beperking, daar vervalt dit hoofdstuk.

Veelvoorkomende fouten en oplossingen

ssh: connect to host 203.0.113.10 port 2222: Connection refused: de pakketten komen aan, maar niemand luistert. De dienst is niet herstart, de configuratie is niet doorgekomen, of een ListenAddress-regel bindt hem aan een ander adres.

ssh: connect to host 203.0.113.10 port 2222: Connection timed out: de pakketten komen helemaal niet aan, vrijwel altijd een pakketfilter op de server of in uw eigen netwerk. Het verschil met de vorige melding is de belangrijkste diagnose-informatie die er is: geweigerd betekent dat de dienst ontbreekt, een time-out betekent een filter.

error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.: op RHEL-systemen is dat SELinux, zie hierboven. Op Debian en Ubuntu treedt de melding praktisch alleen op als sshd niet als root draait en een poort onder 1024 moet bezetten.

error: Bind to port 2222 on 0.0.0.0 failed: Address already in use.: een ander proces heeft de poort, ss -tlnp | grep ':2222 ' noemt het. Treedt de fout alleen sporadisch na een herstart op, dan ligt de poort in het bereik van de dynamische bronpoorten, zie stap 1.

fatal: Cannot bind any address.: geen van de gevraagde adressen kon bezet worden. Op Debian en Ubuntu betekent dat vrijwel altijd dat ssh.socket de poort al vasthoudt en u daarnaast ssh.service daarop wilt starten.

Job for ssh.service failed because the control process exited with error code.: de oorzaak staat in het journal, niet in deze regel. journalctl -u ssh -n 50 --no-pager toont hem, ongeacht de OpenSSH-versie.

/etc/ssh/sshd_config.d/20-port.conf line 1: Bad configuration option: prot: een typefout. sshd -t noemt het bestand en het regelnummer, precies daarvoor staat dat commando vóór elke herstart.

sshd: no hostkeys available -- exiting.: de hostsleutels ontbreken of zijn niet leesbaar, ssh-keygen -A maakt de ontbrekende aan. sshd -t en sshd -T hebben leesrechten daarop nodig en moeten daarom als root draaien.

ssh: connect to host 203.0.113.10 port 22: Connection refused na een geslaagde wijziging: uw client probeert nog steeds de standaardpoort. Vul ~/.ssh/config aan of geef -p mee.

Als u toch buitengesloten bent

  1. Niet herstarten. Een herstart zet firewallregels en dienstconfiguratie weer terug, de server komt net zo dichtgetimmerd terug.
  2. Open de VNC-console in het klantenpaneel en log in als root. Het inloggen op de console loopt niet via SSH en heeft geen last van uw wijziging.
  3. Stel de foutklasse vast. ss -tlnp beantwoordt dat meteen: staat de poort er, dan is het een filterprobleem. Staat hij er niet, dan is het een dienstprobleem, en journalctl -u ssh -n 50 --no-pager zegt waarom.
  4. Terugdraaien in plaats van repareren. rm -f /etc/ssh/sshd_config.d/20-port.conf en, als u dat hebt aangemaakt, rm -f /etc/systemd/system/ssh.socket.d/override.conf, daarna systemctl daemon-reload en systemctl try-restart ssh.socket ssh.service.
  5. Was de firewall de oorzaak, dan helpt ufw disable, gevolgd door een nette heropbouw met de juiste poortvrijgave.

Samenvatting

  • Eerst de firewall, daarna sshd. De oude poort blijft open totdat de nieuwe aantoonbaar werkt.
  • Meerdere Port-regels tellen op, dat maakt de overgang risicoloos. De standaardwaarde 22 vervalt zodra er ook maar één Port-regel bestaat.
  • Bij socketactivering, standaard op Ubuntu 24.04, staat de poort in ListenStream.
  • Doorslaggevend is nooit het configuratiebestand, maar ss -tlnp, gefilterd op poortnummer.
  • De noodweg is de VNC-console in het klantenpaneel, houd daarvoor het rootwachtwoord bij de hand.

Neemt u de server net pas in gebruik, dan plaatst onze checklist voor nieuwe rootservers deze stap in de rest van de basisinrichting. En nog een keer ter relativering: een andere poort maakt uw logs leesbaar. Wat de toegang werkelijk beveiligt, is inloggen met een sleutel en een uitgeschakelde wachtwoordlogin. Voert u maar één van beide door, neem dan het tweede.

Veelgestelde vragen

Levert een andere SSH-poort meer veiligheid op?
Nee. Een volledige portscan over alle 65.535 poorten vindt de dienst toch wel, en de versiebanner die OpenSSH bij de verbindingsopbouw stuurt, verraadt ook op poort 51022 meteen waar het om gaat. De echte winst zit ergens anders: verreweg het meeste van wat op poort 22 binnenkomt, is ongericht massascannen, en die tools proberen poort 22 en verder niets. Na de wijziging verdwijnt die verkeersklasse uit het journal, en pas daardoor valt die ene gerichte inlogpoging op. Wat de toegang werkelijk beveiligt, is inloggen met een sleutel, een uitgeschakelde wachtwoordlogin en een strak pakketfilter.
Welke poort kan ik het beste kiezen?
Niet 2222, want dat is de meestgekozen uitwijkoptie en massascanners nemen die allang mee. Blijf onder 32768: daar begint meestal het bereik waaruit de kernel bronpoorten voor uitgaande verbindingen toekent, na te lezen in /proc/sys/net/ipv4/ip_local_port_range. Een poort uit dat bereik kan tijdelijk bezet zijn, en na een herstart mislukt de bindpoging dan sporadisch met Address already in use, terwijl de server zonder SSH opkomt. Poorten onder 1024 mag alleen root bezetten, daar kan dus geen gebruiker zonder rootrechten met een nagemaakte SSH-dienst inhaken en inloggegevens meeschrijven. Controleer vooraf met ss -tlnp en met grep -w 2222 /etc/services of de poort vrij is en niet voor een andere dienst gereserveerd staat.
Hoe wijzig ik de poort zonder mijzelf buiten te sluiten?
Door de server tijdens de ombouw op beide poorten te laten luisteren. De volgorde luidt: open de nieuwe poort in de firewall en laat de oude open, laat sshd daarna op beide poorten luisteren, herstart, log met een derde, vers opgebouwde sessie in via de nieuwe poort en verwijder pas daarna poort 22. Dat kan dankzij een bijzonderheid van OpenSSH: meerdere Port-regels vervangen elkaar niet, ze tellen op. De keerzijde is even belangrijk: de standaardwaarde 22 geldt alleen zolang er helemaal geen Port-regel bestaat. Zodra u er een schrijft, moet u 22 uitdrukkelijk mee opnemen, anders is die verdwenen.
Mijn Port-regel heeft geen effect, sshd luistert nog steeds alleen op 22. Hoe komt dat?
Daarvoor komen twee oorzaken in aanmerking. Ten eerste socketactivering: Ubuntu zet daar sinds 22.10 op in, en standaard actief is het op Ubuntu 24.04. Dan houdt niet sshd de poort vast, maar systemd, en doorslaggevend is ListenStream in de unit ssh.socket, niet de Port-regel in de sshd-configuratie. Welke werkwijze bij u draait, zegt systemctl is-enabled ssh.socket ssh.service. Ten tweede de include-volgorde: bij de meeste directives wint de eerst gevonden waarde, en de include-regel voor /etc/ssh/sshd_config.d/ staat bij Debian en Ubuntu standaard helemaal bovenaan. Is die naar het einde van het bestand verplaatst, dan blijft uw bestand zonder effect. Wat werkelijk geldt, toont sshd -T, gefilterd op de regels port en listenaddress. Verschijnt daar een listenaddress-regel, dan beperkt die bovendien waarop geluisterd wordt.
Wat is het verschil tussen Connection refused en Connection timed out?
Dat is de belangrijkste diagnose-informatie die er is. ssh: connect to host 203.0.113.10 port 2222: Connection refused betekent dat de pakketten aankomen, maar dat niemand luistert: de dienst is niet herstart, de configuratie is niet doorgekomen, of een ListenAddress-regel bindt hem aan een ander adres. ssh: connect to host 203.0.113.10 port 2222: Connection timed out betekent daarentegen dat de pakketten helemaal niet aankomen, en dat is vrijwel altijd een pakketfilter op de server of in uw eigen netwerk. Kort gezegd: geweigerd betekent dat de dienst ontbreekt, een time-out betekent een filter.
Op AlmaLinux en Rocky Linux start sshd niet: error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.
Dat is SELinux en geen rechtenprobleem, ook al ziet de melding er zo uit. Op RHEL-systemen draait SELinux standaard in de modus enforcing, en het regelwerk staat sshd uitsluitend poorten toe die als ssh_port_t gelabeld zijn. Standaard is dat alleen poort 22. Label de nieuwe poort voordat u de dienst herstart: semanage port -a -t ssh_port_t -p tcp 2222. Ontbreekt semanage, dan zit het in het pakket policycoreutils-python-utils. Is de poort al aan een ander type toegewezen, dan mislukt -a met de melding dat hij al gedefinieerd is, wijzig de toewijzing in dat geval met -m. Geweigerde toegangspogingen toont ausearch -m avc -ts recent. Debian en Ubuntu kennen in de standaardinstallatie geen vergelijkbare beperking.
Wat moet ik na de wijziging verder nog aanpassen?
Eerst fail2ban: geldt daar een blokkade, dan blokkeert die anders nog steeds alleen poort 22, terwijl de pogingen op de nieuwe poort gewoon doorkomen. Vul de poort aan in het onderdeel sshd van /etc/fail2ban/jail.local. De detectie blijft sowieso werken, omdat fail2ban de inlogpogingen uit het journal leest, alleen de blokkade hangt aan die regel. Daarna alle tools die de server aanspreken: het handigst regelt u dat in één keer voorgoed met een host-vermelding inclusief poort in ~/.ssh/config. Waar u het adres rechtstreeks opgeeft, verschilt de schrijfwijze per tool: ssh en ssh-copy-id nemen -p met een kleine letter, scp en sftp -P met een hoofdletter, rsync krijgt de poort via de optie -e, git in de URL, Ansible als ansible_port in het inventory. rsync --port slaat daarentegen op de rsync-daemon en heeft hier geen effect. Dat SSH bij de eerste verbindingsopbouw opnieuw naar de echtheid van de hostsleutel vraagt, is normaal: vermeldingen in known_hosts zijn poortgebonden en worden opgeslagen in de vorm [203.0.113.10]:2222.
Ik heb mijzelf buitengesloten. Wat nu?
Herstart de server niet, hij zet firewallregels en dienstconfiguratie weer terug en komt net zo dichtgetimmerd terug. Open in plaats daarvan de VNC-console in uw klantenpaneel en log in als root, want het inloggen op de console loopt niet via SSH en heeft geen last van uw wijziging. De foutklasse beantwoordt ss -tlnp meteen: staat de poort er, dan is het een filterprobleem, staat hij er niet, dan een dienstprobleem, en journalctl -u ssh -n 50 --no-pager zegt waarom. Draai daarna terug in plaats van te repareren: verwijder /etc/ssh/sshd_config.d/20-port.conf en, als u dat hebt aangemaakt, /etc/systemd/system/ssh.socket.d/override.conf, daarna systemctl daemon-reload en systemctl try-restart ssh.socket ssh.service. Was de firewall de oorzaak, dan helpt ufw disable, gevolgd door een nette heropbouw met de juiste poortvrijgave.

SSH OpenSSH sshd Serverbeveiliging Debian Ubuntu systemd SELinux