De eerste 30 minuten: VPS-hardening-checklist
Een verse VPS krijgt binnen enkele minuten na het verkrijgen van een IP zijn eerste SSH-probe. Hier is de exacte volgorde die ik op elke nieuwe box draai — copy-paste-klaar voor Debian 13, met een checklist-tabel aan het einde.
Aannames: een verse Debian 13-image van je VPSRento-implementatie, je bent ingelogd als root via SSH, en het voorbeeld-IP is 185.220.101.14 — vervang door die van jou. Totale tijd: ongeveer een half uur. Voer de stappen in volgorde uit; stap 2 kan je buitensluiten als je te haastig te werk gaat.
1. Maak je sudo-gebruiker aan
Werken als root is hoe typefouten incidenten worden. Maak een echte gebruiker, geef die sudo, en doe alles vanaf daar:
# create the user (you'll set a password — still useful for sudo)
adduser ops
# grant sudo
usermod -aG sudo ops
Alles onder dit punt draait als ops tenzij anders vermeld.
2. Alleen SSH-sleutels — geen wachtwoorden, geen root-login
Wachtwoordauthenticatie is het grootste gat op een internetgerichte box. Bots bestoken poort 22 de hele dag met referentielijsten. Sleutels maken de hele aanvalsklasse irrelevant. Op je lokale machine:
# generate a keypair if you don't have one (ed25519, no passphrase tradeoff is yours)
ssh-keygen -t ed25519 -C "ops@atlas"
# push the public key to the server
ssh-copy-id [email protected]
Controleer dat je kunt inloggen met de sleutel in een nieuwe terminal — ssh [email protected] — voordat je de configuratie aanraakt. Houd de bestaande root-sessie open als je ontsnappingsluik. Bewerk dan /etc/ssh/sshd_config:
# /etc/ssh/sshd_config — the three lines that matter
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
# validate the config, then reload (Debian 13 uses ssh.service)
sshd -t && systemctl reload ssh
prohibit-password in plaats van een platte no voor root met opzet: root kan nog steeds authenticeren met een sleutel vanaf je werkstation, wat af en toe nuttig is voor herstel via de providerconsole — maar geen wachtwoord zal ooit werken, voor wie dan ook, vanaf waar dan ook. Bevestig met sshd -T | grep -E 'passwordauthentication|permitrootlogin'.
3. Firewall: standaard weigeren, alleen toestaan wat je draait
Debian's ufw is een dunne, verstandige laag bovenop nftables. Het beleid is de beveiliging; de regels zijn slechts uitzonderingen daarop:
apt update && apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
# SSH stays open — add this BEFORE enabling
ufw allow 22/tcp comment 'SSH'
# whatever your box actually serves, e.g.:
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
ufw enable
ufw status verbose
Elke poort die je opent moet een naam en een reden hebben. Als je niet kunt benoemen waar een poort voor dient, krijgt die geen regel.
4. fail2ban: vertraag de bots tot een kruipgang
Met wachtwoordauthenticatie uitgeschakeld is brute force al dood — maar fail2ban houdt je logs leesbaar en verbant de scanners die aan alles anders peuteren:
apt install -y fail2ban
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
maxretry = 5
findtime = 10m
bantime = 1h
systemctl enable --now fail2ban
# watch it work
fail2ban-client status sshd
5. Automatische beveiligingsupdates
De ongepatchte CVE is een groter risico dan de herstart. Debian's unattended-upgrades installeert beveiligingsupdates op eigen houtje:
apt install -y unattended-upgrades
# answer Yes to auto-install updates
dpkg-reconfigure -plow unattended-upgrades
De standaardconfiguratie in /etc/apt/apt.conf.d/50unattended-upgrades haalt alleen uit de security-suite — wat je wilt op een server: beveiligingsfixes automatisch, al het andere wanneer jij kiest.
6. Zet uit wat je niet draait
Elke draaiende service is aanvalsoppervlak dat je moet patchen. Zie wat er daadwerkelijk luistert:
# who is listening, on what, as which process
ss -tulpn
# everything enabled at boot
systemctl list-unit-files --state=enabled
# example: you don't run a print server — nobody does
systemctl disable --now cups
De regel: als je niet kunt zeggen wat een luisteraar doet, kom er dan achter voordat je die laat leven. Op een minimale VPSRento-image zou er heel weinig moeten zijn naast sshd en je eigen applicatie.
7. Optioneel maar aanbevolen: een WireGuard-beheerlaag
De sterkste vorm van SSH-beveiliging is SSH die het internet helemaal niet bereikt. Draai WireGuard op de machine, sta SSH alleen toe binnen de tunnel, en poort 22 verdwijnt van elke scanner op aarde:
apt install -y wireguard
# /etc/wireguard/wg0.conf — minimal management tunnel
# [Interface] Address = 10.8.0.1/24, ListenPort = 51820
# open the tunnel, not the shell
ufw allow 51820/udp comment 'WireGuard'
ufw allow in on wg0 to any port 22 proto tcp comment 'SSH via WG'
ufw delete allow 22/tcp
systemctl enable --now wg-quick@wg0
Daarna ssh [email protected] via de tunnel, en het publieke IP antwoordt op precies één UDP-poort. De volledige WireGuard-walkthrough — sleutels, peers, clientconfiguraties, telefoon-QR-codes — staat in de begeleidende gids.
De 10-puntscontrolelijst
Doorloop deze tabel na elke nieuwe implementatie, en opnieuw na elke service die je toevoegt:
| # | Item | Waar het leeft | Controleer met |
|---|---|---|---|
| 1 | Niet-root sudo-gebruiker | /etc/passwd | id ops |
| 2 | Alleen sleutelgebaseerde SSH-authenticatie | sshd_config | sshd -T | grep passwordauth |
| 3 | Root-wachtwoordlogin uitgeschakeld | sshd_config | sshd -T | grep permitrootlogin |
| 4 | Firewall standaard-weiger inkomend | ufw | ufw status verbose |
| 5 | Alleen benoemde poorten open | ufw | ufw status numbered |
| 6 | fail2ban sshd-jail actief | jail.local | fail2ban-client status sshd |
| 7 | Beveiligingsupdates automatisch | apt | systemctl status unattended-upgrades |
| 8 | Geen onverklaarde listeners | — | ss -tulpn |
| 9 | Beheer via WireGuard (optioneel) | wg0.conf | wg show |
| 10 | Snapshot na het harden | Clientgebied-add-on, $1.99/maand | Services → jouw VPS → snapshots |
Item 10 verdient één zin: eerst harden, dan snapshot, in die volgorde — een snapshot van een schone, geharde machine is je terugval voor elke toekomstige fout. Dagelijkse offsite-snapshots zijn een $1.99/maand add-on in het clientgebied. Dertig minuten preventie, één klik verzekering.