Nieuwe rootserver inrichten: checklist voor de eerste 30 minuten
De eerste 30 minuten op een nieuwe rootserver zijn bepalend. Negen stappen in de juiste volgorde, met de valkuilen van Debian 13 en Ubuntu 24.04 die in de meeste handleidingen ontbreken.
Een nieuwe rootserver is vanaf de eerste seconde bereikbaar en wordt vanaf de eerste minuut gescand. De geautomatiseerde inlogpogingen op poort 22 beginnen in de praktijk al voordat u zelf voor het eerst hebt ingelogd. Deze lijst brengt een verse server in ongeveer een half uur in een toestand waarin u hem met een gerust hart kunt laten draaien.
Alle commando's gaan ervan uit dat u als root werkt, zoals direct na de uitrol. Zodra u met uw nieuwe gebruiker bent ingelogd, zet u voor elk commando een sudo. De volgorde is getest op Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS en Ubuntu 22.04 LTS. Waar de vier van elkaar verschillen, staat dat erbij.
Stap 0: de terugweg veiligstellen voordat u iets wijzigt
De enige fout in deze lijst die u niet via SSH kunt herstellen, is de fout die u SSH afneemt. Daarom geldt de komende 30 minuten één ijzeren regel: open een tweede terminalvenster met een actieve SSH-verbinding en sluit dat niet. Een bestaande SSH-sessie overleeft zowel een herstart van de SSH-service als het inschakelen van de firewall. Lukt een nieuwe verbinding na een wijziging niet meer, draai die wijziging dan terug in de sessie die nog openstaat.
Daarnaast is het verstandig om te weten waar u de consoletoegang tot uw server vindt, voordat u die nodig hebt. Bij KernelHost bereikt u die in het klantenpaneel, los van SSH en los van de firewall. Wie de weg daarheen pas zoekt terwijl hij al buitengesloten is, verliest tijd.
Twee foutmeldingen moet u uit elkaar kunnen houden, want ze wijzen op totaal verschillende oorzaken:
ssh: connect to host 203.0.113.10 port 22: Connection refusedbetekent dat het pakket is aangekomen, maar dat niemand op die poort luistert. De SSH-service draait niet of luistert op een andere poort.ssh: connect to host 203.0.113.10 port 22: Connection timed outbetekent dat het pakket is weggegooid. Dat is bijna altijd de firewall.Permission denied (publickey)betekent dat de service draait en dat de firewall u doorlaat, alleen past uw sleutel niet.
Stap 1: het systeem bijwerken
Een vers geïnstalleerd image is zelden actueel. Tussen het bouwen van het image en uw bestelling zitten vaak weken waarin er beveiligingsupdates zijn verschenen.
cat /etc/os-release
apt update
apt full-upgrade -y
full-upgrade in plaats van upgrade is hier een bewuste keuze: op een vers systeem mag apt pakketten verwijderen wanneer een afhankelijkheid dat vereist. Op een draaiend productiesysteem zou u eerst controleren wat er weg moet.
Op Ubuntu 22.04 en 24.04 is needrestart voorgeïnstalleerd. Het onderbreekt de upgrade met een kleurige schermvullende vraag welke services opnieuw moeten worden gestart. Wilt u dat niet, bijvoorbeeld in een script:
NEEDRESTART_MODE=a DEBIAN_FRONTEND=noninteractive apt full-upgrade -y
Daarna opruimen en controleren of een herstart nodig is:
apt autoremove --purge -y
apt list --upgradable
test -f /var/run/reboot-required && echo "herstart vereist" || echo "geen herstart vereist"
Verschil tussen de distributies: alleen Ubuntu maakt het bestand /var/run/reboot-required betrouwbaar aan, het komt uit het pakket update-notifier-common. Debian meldt een noodzakelijke herstart standaard helemaal niet. Op Debian installeert u daarvoor needrestart na, dat vertelt u bij elke aanroep of er een nieuwe kernel klaarligt. Debian 13 brengt bovendien een nieuwere apt-generatie mee met gekleurde, in kolommen opgemaakte uitvoer. Dat is geen fout, alleen ongewoon.
Controle: apt list --upgradable geeft behalve de kopregel Listing... niets meer terug. Verschijnt bij de update de melding Release file for ... is not valid yet, dan loopt de klok van uw server verkeerd. Ga in dat geval naar stap 5 en herhaal daarna stap 1.
Meer daarover, ook over het omgaan met vastgehouden pakketten en externe pakketbronnen: Linux-server bijwerken met apt.
Stap 2: een gebruiker aanmaken in plaats van als root werken
Als root werken doet u niet, omdat elke typefout meteen het hele systeem raakt en omdat elke aanvaller de gebruikersnaam root al kent. Op minimale Debian-images is sudo vaak niet eens aanwezig:
apt install -y sudo
adduser --disabled-password --gecos "" kernel
usermod -aG sudo kernel
De optie --disabled-password maakt de gebruiker aan zonder wachtwoord, precies goed voor een login die alleen op sleutels werkt. Wilt u er toch een wachtwoord bij zetten, bijvoorbeeld voor sudo via de console, doe dat dan met passwd kernel.
Verschil tussen de distributies: op Debian en Ubuntu heet de beheerdersgroep sudo. Alleen wie van een RHEL-achtig systeem komt, zoekt naar wheel, en dat bestaat hier niet.
Nu de publieke sleutel. Maak de map met de juiste rechten aan, want verkeerde rechten zijn de meest voorkomende oorzaak van een geweigerde sleutellogin:
mkdir -p /home/kernel/.ssh
chmod 700 /home/kernel/.ssh
touch /home/kernel/.ssh/authorized_keys
chmod 600 /home/kernel/.ssh/authorized_keys
chown -R kernel:kernel /home/kernel/.ssh
De inhoud van uw publieke sleutel zet u in authorized_keys. Handiger gaat het vanaf uw eigen werkstation met ssh-copy-id kernel@203.0.113.10.
Controle, en wel voordat u SSH omzet:
id kernel
sudo -l -U kernel
De tweede regel moet (ALL : ALL) ALL bevatten. Log daarna in een derde venster in als kernel en voer één keer sudo -v uit. Pas als dat lukt, gaat u verder. Details: Een gebruiker aanmaken en sudo inrichten en SSH-sleutels aanmaken en plaatsen.
Stap 3: SSH beveiligen
Op zeer uitgeklede Debian-images is de SSH-server niet eens geïnstalleerd. Installeer die dan eerst alsnog:
apt install -y openssh-server
Alle vier de hier behandelde systemen lezen extra configuratie uit /etc/ssh/sshd_config.d/. Bewerk dus niet de grote sshd_config, maar maak een eigen bestand aan. Dat overleeft pakketupdates zonder dat er iets wordt gevraagd.
Eén detail gaat in bijna alle handleidingen mis: in de SSH-configuratie wint de eerst gevonden waarde, niet de laatste. De regel Include /etc/ssh/sshd_config.d/*.conf staat bij Debian en Ubuntu helemaal bovenaan, en de bestanden daarin worden in alfabetische volgorde gelezen. Op Ubuntu-images ligt daar vaak al 50-cloud-init.conf met PasswordAuthentication yes. Een bestand met de naam 99-... zou dus zonder effect blijven. Kijk daarom eerst wat er al staat:
ls -l /etc/ssh/sshd_config.d/
cat > /etc/ssh/sshd_config.d/10-kernelhost.conf <<'EOF'
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
EOF
prohibit-password in plaats van no is een bewuste keuze: root mag zich nog steeds met een sleutel aanmelden, maar nooit met een wachtwoord. Dat redt u wanneer er met de sudo-gebruiker iets misgaat. Wie strenger wil beveiligen, zet no, maar moet dan wel echt de consoletoegang hebben getest.
Controleer voor elke herstart van de service de syntaxis:
ssh-keygen -A
sshd -t && echo "configuratie ok"
sshd -T | grep -E "^(permitrootlogin|passwordauthentication|pubkeyauthentication|port) "
sshd -T toont de waarden die werkelijk gelden, nadat alle Include-bestanden zijn verwerkt. Dat is het enige betrouwbare bewijs dat uw wijziging is aangekomen. Meldt het commando sshd: no hostkeys available -- exiting, dan ontbreken de hostsleutels en maakt ssh-keygen -A ze aan. Breekt de controle daarentegen af met Missing privilege separation directory: /run/sshd, dan heeft de service sinds het opstarten van het systeem nog nooit gedraaid en ontbreekt de runtimemap. Een mkdir -p /run/sshd of een systemctl restart ssh maakt die aan, daarna beoordeelt sshd -t weer uw configuratie.
Eén regel uitvoer zorgt telkens voor verwarring: sshd -T geeft voor PermitRootLogin prohibit-password de regel permitrootlogin without-password terug. Dat is dezelfde waarde onder zijn oudere naam, en geen aanwijzing dat uw instelling niet zou zijn aangekomen.
Pas daarna:
systemctl restart ssh
De socketvalkuil bij Ubuntu 24.04 en Debian 13
Sinds Ubuntu 22.10, en daarmee ook in 24.04, wordt SSH via socketactivatie gestart. Het gevolg: een Port-regel in de sshd-configuratie wordt genegeerd, de poort komt uit ssh.socket. Wie de poort wil wijzigen, heeft een systemd-overlay nodig:
systemctl edit ssh.socket
Daarin komt het volgende, waarbij de lege eerste regel de standaardinstelling wist:
[Socket]
ListenStream=
ListenStream=0.0.0.0:2222
ListenStream=[::]:2222
Daarna volgen systemctl daemon-reload en systemctl restart ssh.socket. Ubuntu 22.04 kent dat nog niet, daar volstaat de Port-regel in de configuratie.
Op Debian 13 speelt een verwante eigenaardigheid. Sommige verse images hebben ssh.socket actief, systemen die vanaf Debian 12 zijn opgewaardeerd niet. Zijn beide tegelijk actief, dan mislukt een reload met fatal: Cannot bind any address., omdat service en socket allebei poort 22 willen hebben. Controleren en bij twijfel kiezen:
systemctl is-enabled ssh.socket
systemctl disable --now ssh.socket
systemctl enable --now ssh.service
Controle: ss -tlnp | grep ssh toont de verwachte poort, en een nieuwe verbindingspoging vanuit een vers venster lukt. Uitgebreid: SSH beveiligen en de rootlogin uitschakelen en De SSH-poort wijzigen.
Stap 4: de firewall inschakelen
Op Ubuntu is ufw geïnstalleerd, maar inactief. Op minimale Debian-images ontbreekt het helemaal. De volgorde is hier van levensbelang: eerst SSH toestaan, dan pas inschakelen.
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
Het laatste commando is het belangrijkste van de hele lijst. Regels en standaardbeleid filteren op zichzelf niets, pas ufw enable activeert de firewall echt. Wie dat overslaat, houdt een volledig geconfigureerde firewall over die niets tegenhoudt.
Bij het inschakelen vraagt ufw: Command may disrupt existing ssh connections. Proceed with operation (y|n)?. Die waarschuwing is serieus bedoeld, maar staat de regel voor poort 22 (of uw gewijzigde poort) er al vóór, dan gebeurt er niets. Precies daarom staat ufw allow 22/tcp in de lijst boven ufw enable. Hebt u in stap 3 de poort gewijzigd, dan hoort hier ufw allow 2222/tcp te staan, anders sluit u zichzelf buiten. In een script of in een niet-interactieve sessie neemt u ufw --force enable, dat slaat de vraag over.
Controle:
ufw status verbose
Verwacht wordt Status: active, daaronder Default: deny (incoming), allow (outgoing) en in de regellijst een regel 22/tcp ALLOW IN voor uw SSH-poort. Staat er nog steeds Status: inactive, dan ontbreekt ufw enable en is er niets beschermd, hoe compleet de regels er ook uitzien. Open daarna een nieuw venster en maak verbinding voordat u het oude sluit.
Daar hoort aanvullend een blokkeermechanisme tegen inlogpogingen bij:
apt install -y fail2ban python3-systemd
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
backend = systemd
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
EOF
Waarom backend = systemd: Debian installeert sinds versie 12 geen rsyslog meer mee, er is dus geen /var/log/auth.log. De standaard backend = auto zoekt precies dat bestand, waarna fail2ban helemaal niet start, met de melding Failed during configuration: Have not found any log file for sshd jail. Het pakket python3-systemd is nodig om de toegang tot het journal mogelijk te maken. Onder Ubuntu 22.04 en 24.04 bestaat het bestand dankzij rsyslog nog wel, maar de systemd-variant werkt daar net zo goed en is de toekomstvaste keuze. Nakijken kunt u het zo:
test -f /var/log/auth.log && echo "auth.log aanwezig" || echo "geen auth.log, backend systemd nodig"
fail2ban-client -t
Controle: fail2ban-client status sshd toont een regel Currently banned. Komt in plaats daarvan Sorry but the jail 'sshd' does not exist, dan is de configuratie niet geladen. Meer in UFW-firewall inrichten en fail2ban instellen.
Stap 5: tijdzone en tijd
Een verkeerd lopende klok maakt logbestanden waardeloos, laat certificaatcontroles mislukken en kan apt blokkeren met Release file is not valid yet. Op een echte server:
timedatectl set-timezone Europe/Vienna
timedatectl status
In de uitvoer moeten twee regels kloppen: Time zone: Europe/Vienna en System clock synchronized: yes, plus NTP service: active. Staat daar NTP service: inactive, dan draait er geen tijdsynchronisatie. Ubuntu brengt systemd-timesyncd standaard mee, minimale Debian-images vaak niet:
DEBIAN_FRONTEND=noninteractive apt install -y systemd-timesyncd tzdata
date
Veel beheerders laten hun servers bewust op UTC lopen, zodat logbestanden van verschillende locaties vergelijkbaar blijven. Beide keuzes zijn verdedigbaar, waar het om gaat is dat u weet welke u hebt gemaakt. Is timedatectl in een containeromgeving niet beschikbaar, dan kan het ook klassiek:
ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
dpkg-reconfigure -f noninteractive tzdata
Verder lezen: Tijdzone en tijdsynchronisatie inrichten.
Stap 6: de hostnaam instellen
De hostnaam duikt op in logbestanden, in uitgaande e-mails en in monitoringmeldingen. Stel hem vroeg in, anders heten later al uw servers hetzelfde.
hostnamectl set-hostname srv01.uw-domein.nl
hostname -f
Daarna hoort er een passende regel in /etc/hosts, anders wordt u bij elke aanroep van sudo begroet door de melding sudo: unable to resolve host srv01: Name or service not known, met merkbare vertraging. De regel luidt ongeveer 127.0.1.1 srv01.uw-domein.nl srv01.
De valkuil: op images met cloud-init, wat bij Ubuntu de regel is, wordt de hostnaam bij de volgende herstart teruggezet. De instelling die dat voorkomt:
command -v cloud-init || echo "cloud-init niet geïnstalleerd"
mkdir -p /etc/cloud/cloud.cfg.d
printf 'preserve_hostname: true\n' > /etc/cloud/cloud.cfg.d/99_hostname.cfg
Controle: na een herstart geeft hostnamectl nog steeds uw naam terug. Details: De hostnaam onder Linux blijvend wijzigen.
Stap 7: automatische beveiligingsupdates
Een server die niemand meer aanraakt, is de gevaarlijkste. Automatische beveiligingsupdates zijn de effectiefste losse stap uit deze lijst.
apt install -y unattended-upgrades
cat > /etc/apt/apt.conf.d/20auto-upgrades <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
EOF
Alleen het pakket installeren is niet overal genoeg, pas dit bestand activeert de dagelijkse uitvoering. Eigen fijnafstellingen horen in een bestand met een hoger nummer dan het meegeleverde 50unattended-upgrades, zodat ze winnen en bij een pakketupdate niet worden overschreven:
cat > /etc/apt/apt.conf.d/52unattended-upgrades-local <<'EOF'
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::MinimalSteps "true";
EOF
Standaard haalt de tool op beide distributies alleen uit de beveiligingsrepository, niet de gewone updates. Dat is opzet en voor productiesystemen meestal precies goed. Zet u Automatic-Reboot "true", stel dan beslist ook een tijdstip in, anders herstart de server wanneer het de timer uitkomt.
Controle: een testrun laat zien welke pakketten in aanmerking zouden komen, zonder iets te installeren. Let op het enkelvoud in de commandonaam:
unattended-upgrade --dry-run --debug
apt-config dump | grep -iE "unattended|periodic"
In het log onder /var/log/unattended-upgrades/ moet na de eerste run iets staan. Blijft het leeg, dan grijpt de configuratie niet. Uitgebreid: Automatische beveiligingsupdates inrichten.
Stap 8: monitoring
Monitoring betekent in de eerste 30 minuten niet dat u een Grafana opbouwt. Het betekent dat u het te horen krijgt wanneer de server stilvalt of de schijf volloopt.
apt install -y htop tmux curl
df -h /
free -m
Drie dingen zijn voor het begin genoeg. Ten eerste een externe bereikbaarheidstest die van buitenaf controleert en u waarschuwt, want een server die is vastgelopen, stuurt geen waarschuwing meer over zichzelf. Ten tweede een melding bij weinig schijfruimte, want een vol bestandssysteem is de meest voorkomende oorzaak van storingen die niemand zag aankomen. Ten derde een blik in het journal wanneer er iets vreemds aan de hand is:
journalctl -p 3 -b --no-pager | tail -n 30
systemctl --failed
systemctl --failed hoort 0 loaded units listed terug te geven. Elke regel daar is een service die niet start, en die u nu wilt repareren en niet over drie maanden. Meer daarover: Servermonitoring inrichten.
Stap 9: back-uppen voordat er iets te verliezen valt
Het beste moment voor de eerste back-up is voordat er data is. Dan oefent u de procedure zonder druk. Twee dingen zijn het waard om meteen weg te schrijven, omdat het reconstrueren ervan de meeste tijd kost: de configuratie onder /etc en de lijst met geïnstalleerde pakketten.
tar -czf /root/etc-backup-$(date +%F).tar.gz /etc
dpkg --get-selections > /root/pakketten.txt
tar -tzf /root/etc-backup-$(date +%F).tar.gz | wc -l
Daarmee hebt u nog geen back-up, alleen een kopie op dezelfde gegevensdrager. Een back-up ligt op een ander systeem, het liefst op een andere locatie. Een tool met versleuteling en deduplicatie van gelijke blokken loont vanaf de eerste dag:
apt install -y borgbackup
borg --version
De ongemakkelijke waarheid: een back-up waaruit nog nooit iets is teruggehaald, is een aanname. Plan een moment in voor de eerste restore en zet één enkel bestand terug. Hoe dat gaat, staat in Back-upstrategie voor rootservers.
Als u zichzelf hebt buitengesloten
Het gebeurt, meestal in stap 3 of 4. De weg terug is altijd dezelfde: inloggen via de console in het klantenpaneel, daar met gebruikersnaam en wachtwoord in plaats van met een sleutel. Daarna, afhankelijk van de oorzaak:
- Firewall te streng:
ufw disable, regel corrigeren,ufw enable. - SSH-configuratie stuk:
rm /etc/ssh/sshd_config.d/10-kernelhost.conf, daarnasshd -tensystemctl restart ssh. - Verkeerde poort na een socketwijziging:
systemctl revert ssh.socketzet de overlay terug, daarnasystemctl daemon-reloadensystemctl restart ssh.socket. - Door fail2ban buitengesloten:
fail2ban-client set sshd unbanip 203.0.113.10. Om te voorkomen dat u dat nog eens overkomt, zet u uw vaste adres onderignoreipin dejail.local. - Sleutel wordt geweigerd: bijna altijd de rechten.
chmod 700op de map,chmod 600op het bestand, en beide moeten eigendom zijn van de gebruiker, niet van root.
De eindcontrole
Dat een commando geen fout teruggeeft, betekent niet dat het effect heeft gehad. Deze zes controles tonen de werkelijke toestand:
sshd -T | grep -E "^(permitrootlogin|passwordauthentication|port) "toont de waarden die gelden, niet de gewenste.ufw status verbosemeldtStatus: activemet een regel voor uw SSH-poort.timedatectl statusmeldtSystem clock synchronized: yes.systemctl --failedsomt niets op.unattended-upgrade --dry-run --debugloopt zonder foutmelding door.- Een nieuwe SSH-verbinding vanuit een vers geopend venster lukt, met sleutel en zonder wachtwoordvraag.
Pas als punt zes klopt, mag u het oude terminalvenster sluiten.
Wat daarna komt
Nog een woord over de keuze van de distributie, want die bepaalt de komende jaren. Debian 12 valt sinds juli 2026 buiten de reguliere ondersteuning en wordt tot medio 2028 door het LTS-team onderhouden, met een beperkte set pakketten. Wie vandaag opnieuw begint, neemt Debian 13 of Ubuntu 24.04 LTS. Ubuntu 22.04 LTS zit nog tot 2027 in de standaardondersteuning, maar voor een server die jaren moet draaien is het niet meer de eerste keuze. Debian 10 en Ubuntu 20.04 zijn sinds juni 2024 respectievelijk mei 2025 definitief uitgefaseerd en horen op geen enkele nieuwe server thuis.
Praktisch relevant zijn ook de versieverschillen in de pakketbronnen. Debian levert principieel geen mysql-server, daar is MariaDB de standaard. Wie een bepaalde PHP-, Node- of Java-versie nodig heeft, kijkt beter vooraf wat de distributie meebrengt in plaats van later externe pakketbronnen toe te voegen. En voegt u er toch een toe: apt-key is afgeschaft, sleutels horen in /etc/apt/keyrings/ en worden in de bronvermelding via signed-by aangehaald.
Daarmee staat er een server die bijgewerkt is, zichzelf actueel houdt, alleen u binnenlaat en meldt wanneer er iets niet klopt. Al het andere, webserver, database, certificaten, bouwt daarop voort en niet ernaast.
Veelgestelde vragen
In welke volgorde moet ik een nieuwe rootserver inrichten?
Waarom heeft mijn wijziging in sshd_config geen effect?
Waarom verandert mijn SSH-poort onder Ubuntu 24.04 niet?
fail2ban start niet en meldt dat het geen logbestand voor de sshd-jail heeft gevonden. Wat nu?
Waarom is mijn hostnaam na de herstart weer weg?
Volstaat apt upgrade of heb ik apt full-upgrade nodig?
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.

