Direct naar de inhoud

Cookie-instellingen

Kies per soort welke cookies je toestaat. Je kunt je keuze altijd wijzigen via Cookie-instellingen onderaan elke pagina. Privacyverklaring

Noodzakelijk

Altijd aan

Nodig om in te loggen, je winkelwagen te bewaren en je keuzes te onthouden. Deze staan altijd aan.

Welke cookies?
  • weboke_sessie, weboke_klant, weboke_remember: je sessie en ingelogd blijven
  • weboke_basket: je winkelwagen
  • wkBtwIncl: prijzen met of zonder btw tonen
  • wok_cookies: je cookiekeuze, 12 maanden

Meet welke advertentie tot een bezoek of bestelling leidt, zodat we niet betalen voor advertenties die niets doen.

Welke cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), tot 90 dagen
  • OpenAI Ads, advertenties in ChatGPT
  • wok_aff: via welke partner je bij ons kwam (affiliateprogramma), 60 dagen

4,6

Land en taal

Elk land heeft zijn eigen site, met prijzen en btw van dat land.

Bekijken

Module 2 · 2.2

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:

  1. Twee sleutels werken (les 2.1), en je hebt in een nieuw venster gecontroleerd dat inloggen met een sleutel lukt.
  2. 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.
  3. De console van je aanbieder ken je: daar kom je binnen zonder SSH.
  4. 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/*.conf

Alle 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 yes

Omdat 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 yes

Twee 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.conf

met deze inhoud:

# Inloggen alleen met een sleutel
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password

Wat 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 PasswordAuthentication op no staat. In oudere handleidingen heet deze instelling ChallengeResponseAuthentication; sinds OpenSSH 8.7 is dat een verouderde andere naam voor hetzelfde. Debian zet hem standaard al op no, 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). Zet no pas als je zeker weet dat inloggen als die gebruiker en sudo werken.

Optioneel, voor wie meer wil:

AllowUsers anna
AuthenticationMethods publickey

AllowUsers 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 ssh

Op 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.socket

Vergeet 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 ssh

Lukt 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_config telt de eerste waarde; bestanden in sshd_config.d worden eerst gelezen. Zet je eigen instellingen in een bestand als 00-beveiliging.conf.
  • Zet PasswordAuthentication no én KbdInteractiveAuthentication no; root alleen met een sleutel (prohibit-password) of helemaal niet (no).
  • Controleer met sshd -t vóór het herladen en met sshd -T welke waarde echt geldt; let op een 50-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-reload en systemctl restart ssh.socket.

Quiz

1. Onderaan /etc/ssh/sshd_config staat PasswordAuthentication no, maar je kunt nog steeds met een wachtwoord inloggen. Wat is de meest waarschijnlijke oorzaak?



2. Waarom zet je naast PasswordAuthentication no ook KbdInteractiveAuthentication no?



3. Wat betekent PermitRootLogin prohibit-password?



4. In welke volgorde werk je het veiligst?



5. Je wijzigt op Ubuntu 24.04 de regel Port 22 in Port 2222 en doet systemctl restart ssh. Met ss -tlnp zie je dat er nog op 22 wordt geluisterd. Wat ben je vergeten?



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.

Opdracht Z2.2: Wachtwoordlogin staat uit

We loggen niet in en proberen geen wachtwoord of sleutel. Eerst laat je zien dat de server van jou is: klik op "Toon mijn code" en zet een bestand /.well-known/weboke-cursus-<code>.txt met alleen die code op de webserver van je hostnaam. We halen het rechtstreeks op bij elk IP-adres dat we controleren (IPv4 en IPv6 apart); een TXT-record telt hier niet. De controle komt van heavy.webawere.nl (185.158.167.16 en 2a07:ae80:100:0:185:158:167:16), niet van onze webserver. Alleen voor aangemelde cursisten; per server hoogstens 6 controles per uur. We vragen alleen welke inlogmethoden je server aanbiedt voor jouw gebruikersnaam, zoals elke SSH-client doet voor het inloggen. Vul je eigen gebruiker in: een onbekende naam komt als "Invalid user" in je log en telt bij fail2ban als één poging.





Wat je invult en wat we vinden, slaan we niet op. Je browser onthoudt je antwoorden en of je de opdracht hebt gehaald. Ben je aangemeld, dan bewaren we alleen dat je de opdracht (bijna) goed had in Mijn cursussen; daar kun je het ook verwijderen.

Verder lezen

De stappen in deze artikelen gelden voor het VPS-scherm van WebOké; bij andere aanbieders werkt het vergelijkbaar.

Even geduld…

Stel je domeinen in

Regel per domein de nameservers, de koppeling aan je hosting en wie de eigenaar wordt.

Je domeinen laden…