SSH-poort wijzigen zonder uzelf buiten te sluiten: sshd, socketactivering en SELinux
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.
- Kies een poort en controleer of die vrij is.
- Eerst de firewall: open de nieuwe poort en laat de oude open.
- Laat sshd op beide poorten luisteren.
- Pas bij socketactivering ook de socket-unit aan.
- Herstart en controleer op de luisterende socket.
- Log met een derde, verse sessie in via de nieuwe poort.
- 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
| Systeem | Standaard actief | Waar 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 LTS | ssh.socket | ListenStream in de socket-unit |
| Ubuntu 22.04 LTS | ssh.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:
| Tool | Poortopgave | Voorbeeld |
| 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 |
| rsync | via -e | rsync -av -e 'ssh -p 2222' ./data/ kernel@203.0.113.10:/srv/ |
| git | in de URL | ssh://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
- Niet herstarten. Een herstart zet firewallregels en dienstconfiguratie weer terug, de server komt net zo dichtgetimmerd terug.
- 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.
- Stel de foutklasse vast.
ss -tlnpbeantwoordt dat meteen: staat de poort er, dan is het een filterprobleem. Staat hij er niet, dan is het een dienstprobleem, enjournalctl -u ssh -n 50 --no-pagerzegt waarom. - Terugdraaien in plaats van repareren.
rm -f /etc/ssh/sshd_config.d/20-port.confen, als u dat hebt aangemaakt,rm -f /etc/systemd/system/ssh.socket.d/override.conf, daarnasystemctl daemon-reloadensystemctl try-restart ssh.socket ssh.service. - 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 éénPort-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?
Welke poort kan ik het beste kiezen?
Hoe wijzig ik de poort zonder mijzelf buiten te sluiten?
Mijn Port-regel heeft geen effect, sshd luistert nog steeds alleen op 22. Hoe komt dat?
Wat is het verschil tussen Connection refused en Connection timed out?
Op AlmaLinux en Rocky Linux start sshd niet: error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.
Wat moet ik na de wijziging verder nog aanpassen?
Ik heb mijzelf buitengesloten. Wat nu?
2026 KernelHost GmbH. Alle rechten voorbehouden. Deze handleiding is auteursrechtelijk beschermd. Publicatie op andere websites, geheel, gedeeltelijk of in bewerkte vorm, is zonder onze schriftelijke toestemming niet toegestaan. Citeren met bronvermelding en link is uitdrukkelijk welkom.

