Free resource · 2026 edition
VPS Security Checklist for Ubuntu & Debian
Forty-two practical items grouped into six layers. Print it, work through it, mark each box. Or send us the box and we'll do it for you.
Last reviewed: May 2026
1
Account & access
The most exploited surface on a fresh VPS is SSH on port 22 with password login. Fix that first.
-
Create a non-root user with
sudoprivileges. -
Generate an SSH key pair locally (
ssh-keygen -t ed25519) and put the public half in~/.ssh/authorized_keys. -
Set
PermitRootLogin noin a drop-in file under/etc/ssh/sshd_config.d/. -
Set
PasswordAuthentication noandKbdInteractiveAuthentication no. -
Set
PubkeyAuthentication yesexplicitly. -
Restrict logins to specific users with
AllowUsersor a group withAllowGroups. - Optionally move SSH off port 22 (security through reduced noise, not security through obscurity).
-
Reload sshd with
systemctl reload sshdand test from a second terminal before closing the first.
2
Firewall
Default-deny inbound, allow only what you actually serve.
-
Install
ufw(or useiptables/nftablesdirectly if you prefer). -
Set defaults:
ufw default deny incoming,ufw default allow outgoing. - Allow your SSH port (whichever you chose).
-
Allow application ports:
80/tcp,443/tcp, plus anything else you actually need. -
Enable IPv6 in
/etc/default/ufwand confirm v6 rules are present. -
Verify with
ufw status verbose; verify externally withnmap -sT <ip>from a different host. - If your provider has a network-edge firewall (Lightsail, Hetzner Cloud, OVH Anti-DDoS), configure it too.
3
Brute-force & intrusion protection
Bots will try thousands of SSH passwords per hour. Make them give up.
-
Install
fail2ban(apt install fail2ban). -
Enable the SSH jail in
/etc/fail2ban/jail.local. -
Tune
findtime,maxretryandbantimefor your tolerance. -
Add an
ignoreipentry for your office or VPN range so you cannot lock yourself out. -
Verify with
fail2ban-client status sshd. -
Optionally enable jails for
nginx-http-auth,nginx-botsearchandrecidive.
4
Patching & runtime
A box that's patched two weeks behind is a box waiting to be in the news.
-
Run
apt update && apt full-upgradethe moment the box boots. -
Install and configure
unattended-upgradesfor security updates. -
Enable
50unattended-upgradesauto-removal of unused dependencies. - Pick a maintenance window for automatic reboots, or wire reboots into your own runbook.
- Optional: subscribe to your distribution's security mailing list so you know about high-severity patches early.
5
Web stack hardening
If you serve traffic on port 80/443, the application is now part of the security perimeter.
- Enable HTTP/2 in NGINX or your reverse proxy.
- Use a modern TLS profile (Mozilla Intermediate or Modern); disable TLSv1.0/1.1.
-
Issue a Let's Encrypt certificate with
certbotand confirm auto-renewal works. -
Set
Strict-Transport-Securitywith a longmax-age(and pre-load if you're ready). -
Set
X-Frame-Options,X-Content-Type-Options,Referrer-Policy,Permissions-Policy. -
Define a
Content-Security-Policymatching your application. -
Hide server tokens (
server_tokens offin NGINX). -
Limit upload size (
client_max_body_size) to what the app actually needs. -
Configure
logrotatefor access & error logs.
6
System hygiene & ongoing care
Hardening once is a moment in time; staying hardened is a habit.
-
Disable services you don't use (
systemctl disable --now). -
Set sane
sysctldefaults: disable IP redirects, ignore broadcast pings, enable SYN-cookies. -
Configure swap sized to your RAM, with
vm.swappiness=10. -
Set the time zone (
timedatectl set-timezone …) and confirm NTP is active. - Configure log rotation and ship critical logs off-box.
- Schedule daily off-box backups of databases and config (test the restore!).
- Document everything in a server runbook your future self can read.
- Recheck the whole list once a quarter — especially after major OS upgrades.
Don't want to do this yourself?
We'll work the whole list for you, from $9.99.
Hand us a fresh VPS and we'll come back with a hardened box, new credentials, and a written audit report — usually within 24 hours.