De SSH-server veilig instellen
Module 2: SSH en sleutels · Leestijd: 12 minuten
Leerdoel: Na deze les kun je inloggen met een wachtwoord en root-login met een wachtwoord uitzetten, controleren welke instelling echt geldt, en dat doen zonder jezelf buiten te sluiten.
Kernbegrippen: sshd, sshd_config, sshd_config.d, eerste waarde telt, PasswordAuthentication, KbdInteractiveAuthentication, PermitRootLogin, AuthenticationMethods, AllowUsers, sshd -t, sshd -T, tweede sessie, cloud-init, ssh.socket
Eerst het vangnet
Deze les zet iets dicht waar je zelf doorheen moet. Een tikfout kan betekenen dat je niet meer binnenkomt. Daarom altijd, voordat je begint:
- Twee sleutels werken (les 2.1), en je hebt in een nieuw venster gecontroleerd dat inloggen met een sleutel lukt.
- Een snapshot van je VPS. Bij WebOké maak je die in het VPS-scherm, bij andere aanbieders heet het ook snapshot of image. Gaat het mis, dan zet je hem terug.
- De console van je aanbieder ken je: daar kom je binnen zonder SSH.
- Je huidige SSH-sessie blijft open tot het einde. Een lopende sessie blijft werken als je de instellingen wijzigt of de dienst herlaadt. Je test elke wijziging in een tweede venster.
Waar de instellingen staan
De SSH-server heet sshd. Zijn instellingen staan in /etc/ssh/sshd_config. Op Debian en Ubuntu staat bovenaan dat bestand deze regel:
Include /etc/ssh/sshd_config.d/*.confAlle bestanden met .conf in de map sshd_config.d worden dus vóór de rest van het hoofdbestand gelezen, in alfabetische volgorde. Dat is handig: je zet je eigen instellingen in een eigen bestand en laat het hoofdbestand met rust, zodat een update van het pakket je wijzigingen niet raakt.
Maar het heeft een gevolg dat veel mensen overvalt. In sshd_config geldt: voor elke instelling telt de eerste waarde die sshd tegenkomt. Latere regels met dezelfde instelling worden genegeerd. Wie onderaan sshd_config PasswordAuthentication no zet, wint dus niet van een bestand in sshd_config.d dat yes zegt.
De valkuil van cloud-init
Veel VPS-images worden bij de eerste start ingericht door cloud-init. Afhankelijk van hoe de image en de installatie zijn ingesteld, schrijft cloud-init een bestand als /etc/ssh/sshd_config.d/50-cloud-init.conf met daarin bijvoorbeeld:
PasswordAuthentication yesOmdat dat bestand eerder gelezen wordt dan het hoofdbestand, staat wachtwoordlogin aan, wat je ook in sshd_config zet. Ga er dus niet van uit, maar kijk:
root@web1:~# grep -ri passwordauthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
/etc/ssh/sshd_config:#PasswordAuthentication yes
/etc/ssh/sshd_config.d/50-cloud-init.conf:PasswordAuthentication yesTwee nette oplossingen: pas dat bestand aan naar no, of zet je eigen instellingen in een bestand dat eerder in het alfabet komt, zoals 00-beveiliging.conf. Een bestand 99-mijn.conf werkt juist niet, want dan heeft cloud-init al gewonnen.
De instellingen die ertoe doen
Maak je eigen bestand:
root@web1:~# nano /etc/ssh/sshd_config.d/00-beveiliging.confmet deze inhoud:
# Inloggen alleen met een sleutel
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-passwordWat betekent elke regel?
- PasswordAuthentication no: de server accepteert geen wachtwoord meer. De standaardwaarde van OpenSSH is
yes. - KbdInteractiveAuthentication no: "keyboard-interactive" is een tweede manier om om een wachtwoord te vragen, via PAM. Laat je deze aan staan, dan kan iemand alsnog een wachtwoord proberen, ook als
PasswordAuthenticationopnostaat. In oudere handleidingen heet deze instellingChallengeResponseAuthentication; sinds OpenSSH 8.7 is dat een verouderde andere naam voor hetzelfde. Debian zet hem standaard al opno, maar zet hem er toch neer: dan is het duidelijk en klopt het ook op andere systemen. - PermitRootLogin prohibit-password: root mag inloggen, maar alleen met een sleutel. Dat is sinds OpenSSH 7.0 de standaard. Strenger is
PermitRootLogin no: root mag helemaal niet via SSH binnen, je logt in als gewone gebruiker en gebruikt sudo (les 3.2). Zetnopas als je zeker weet dat inloggen als die gebruiker ensudowerken.
Optioneel, voor wie meer wil:
AllowUsers anna
AuthenticationMethods publickeyAllowUsers laat alleen de genoemde gebruikers binnen; iedere andere naam wordt geweigerd, ook als die een geldige sleutel heeft. Handig, maar vergeet jezelf niet, en vergeet het niet aan te vullen als je een tweede beheerder toevoegt. AuthenticationMethods publickey zegt in één regel dat alleen sleutels gelden.
Testen, toepassen, controleren
Eerst laat je sshd het bestand controleren. Dit start niets en verandert niets:
root@web1:~# sshd -t
root@web1:~#Geen uitvoer betekent: geen fouten. Bij een tikfout zie je de regel en het bestand. Pas dan herlaad je de dienst:
root@web1:~# systemctl reload sshOp Debian en Ubuntu heet de dienst ssh, op AlmaLinux en Rocky Linux sshd.
Daarna controleer je welke waarde echt geldt. sshd -T toont de volledige, uitgerekende configuratie, met alle Include-bestanden verwerkt:
root@web1:~# sshd -T | grep -Ei 'passwordauth|kbdinteractive|permitrootlogin'
permitrootlogin without-password
passwordauthentication no
kbdinteractiveauthentication no(without-password is de oude naam van prohibit-password. Versies van OpenSSH vóór 10.1, zoals op Debian 13 en Ubuntu 24.04, tonen nog de oude naam; nieuwere tonen prohibit-password. Het betekent hetzelfde.)
En nu het belangrijkste: test in een tweede venster, terwijl het eerste open blijft.
anna@laptop:~$ ssh anna@192.0.2.10
anna@web1:~$Werkt dat, probeer dan bewust met een wachtwoord in te loggen. Dit moet mislukken:
anna@laptop:~$ ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no anna@192.0.2.10
anna@192.0.2.10: Permission denied (publickey).Achter Permission denied staat tussen haakjes welke inlogmethoden de server nog aanbiedt. Staat daar alleen publickey, dan is het goed. Staat er password of keyboard-interactive bij, dan geldt er ergens nog een andere waarde: kijk opnieuw met sshd -T.
Precies die lijst controleert de cursusopdracht ook, van buitenaf. Je SSH-client vraagt bij elke verbinding eerst welke methoden mogen, met een verzoek van de soort "none". De server antwoordt met de lijst, zonder dat er een wachtwoord of sleutel wordt geprobeerd.
Ubuntu 24.04 en later: ssh.socket
Op Ubuntu sinds 22.10 luistert niet sshd zelf op poort 22, maar systemd, via ssh.socket. Pas als er een verbinding binnenkomt, start systemd de SSH-dienst. Voor de instellingen in deze les maakt dat niets uit: systemctl reload ssh of restart ssh is genoeg.
Het maakt wel uit als je de poort of het luisteradres wijzigt (Port, ListenAddress). Sinds Ubuntu 24.04 leest systemd die waarden uit sshd_config, maar alleen na:
root@web1:~# systemctl daemon-reload
root@web1:~# systemctl restart ssh.socketVergeet je dat, dan luistert de server gewoon nog op de oude poort. Erger: zet je eerst je firewall op een nieuwe poort en blijft SSH op de oude, dan sluit je jezelf buiten. Controleer altijd met ss -tlnp | grep ssh waarop echt geluisterd wordt (les 5.1), en zet de nieuwe poort in je firewall vóór je de oude dichtdoet. Of een andere poort zinvol is, lees je in les 2.3.
Als het toch misgaat
Kom je niet meer binnen, dan open je de console van je aanbieder, logt in als root (met het wachtwoord, want de console is een "toetsenbord aan de server" en geen SSH) en draai je je bestand terug:
root@web1:~# mv /etc/ssh/sshd_config.d/00-beveiliging.conf /root/
root@web1:~# systemctl reload sshLukt ook dat niet, zet dan de snapshot terug. Bij WebOké kun je in het VPS-scherm ook een nieuw root-wachtwoord zetten; andere aanbieders hebben vaak een vergelijkbare knop of een reddingsmodus (rescue).
Op AlmaLinux en Rocky Linux
De dienst heet sshd (systemctl reload sshd). Ook daar staat een Include /etc/ssh/sshd_config.d/*.conf bovenaan en levert het systeem eigen bestanden in die map mee; dezelfde regel "eerste waarde telt" geldt. Wijzig je de poort, dan moet SELinux die poort ook toestaan (semanage port -a -t ssh_port_t -p tcp 2222) en firewalld hem openen.
Samenvatting
- In
sshd_configtelt de eerste waarde; bestanden insshd_config.dworden eerst gelezen. Zet je eigen instellingen in een bestand als00-beveiliging.conf. - Zet
PasswordAuthentication noénKbdInteractiveAuthentication no; root alleen met een sleutel (prohibit-password) of helemaal niet (no). - Controleer met
sshd -tvóór het herladen en metsshd -Twelke waarde echt geldt; let op een50-cloud-init.conf. - Test in een tweede venster en houd de eerste sessie open. Ken de console en maak vooraf een snapshot.
- Op Ubuntu 24.04+ vraagt een andere poort
systemctl daemon-reloadensystemctl restart ssh.socket.
Quiz
Opdracht
Opdracht Z2.2: Wachtwoordlogin staat uit. Zet wachtwoordlogin en keyboard-interactive uit zoals in deze les, en laat dan het programma van buitenaf kijken. Vul het IP-adres of de hostnaam van je server in, de SSH-poort (standaard 22) en de gebruikersnaam waarmee je zelf inlogt (bijvoorbeeld anna, niet root of een verzonnen naam). Het programma logt niet in: het vraagt alleen, zoals elke SSH-client vóór het inloggen, welke inlogmethoden je server voor die gebruiker aanbiedt. Goed is: alleen publickey.
Verder lezen
De stappen in deze artikelen gelden voor het VPS-scherm van WebOké; bij andere aanbieders werkt het vergelijkbaar.
- Je VPS beveiligen: de eerste vijf minuten
- Geen toegang meer tot je VPS: wat nu?
- Snapshots en backups van je VPS
- Handleiding sshd_config: https://man.openbsd.org/sshd_config
- Ubuntu: SSHd now uses socket-based activation: https://discourse.ubuntu.com/t/sshd-now-uses-socket-based-activation-ubuntu-22-10-and-later/30189
