Harden your VPS: a checklist you can finish in 20 minutes
The concrete steps that stop the overwhelming majority of opportunistic attacks.
You will never make a server perfectly secure. You can make it an unattractive target in about twenty minutes, which deflects essentially all automated attacks.
1. Key-only SSH
Covered fully in SSH keys and access. This is the highest-value single step. Password brute-forcing is the most common intrusion method on the public internet and this eliminates it.
PasswordAuthentication no
PermitRootLogin prohibit-password2. A default-deny firewall
Allow only what you actually serve. On Debian/Ubuntu:
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp # SSH — see the warning below
ufw allow 80,443/tcp # web
ufw enable
ufw status verboseOn RHEL-family, use firewalld:
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reloadWarning: enable the firewall while your SSH session is open and confirm SSH is allowed before you disconnect. If you change the SSH port, allow the new port first. See Firewall basics for the details, including our private mesh interface which must always be allowed.
3. Automatic security updates
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades # choose yes
# verify:
systemctl status unattended-upgrades --no-pagerOn RHEL-family, dnf-automatic does the same job. Automatic security patches close the window between a vulnerability being published and being exploited — which in practice is often hours.
4. Fail2ban
Blocks an IP after repeated failed logins, turning an endless brute-force attempt into a dead end. See Fail2ban basics.
apt install -y fail2ban
systemctl enable --now fail2ban5. Turn off what you do not use
Every listening service is a potential entry point.
ss -tulpn # what is listening, and who owns it
systemctl --type=service --state=running # what is runningStop and disable anything you did not ask for. A minimal server is a secure server.
6. Run services as unprivileged users
Databases, web apps and workers should never run as root. Most packages create their own service user automatically; use it. If you are writing your own unit file, set User= and Group= explicitly.
7. Protect secrets
Never commit secrets to git. Use environment files with
chmod 600.Never make a config file world-readable if it contains a password or key.
Prefer per-service credentials over one shared admin credential.
8. Have a way back in
Confirm the rescue console in /panel/vps works before you need it.
Take a snapshot before risky changes — see Resize, snapshot and reinstall.
Keep at least one SSH key that is stored somewhere other than your everyday laptop.
9. Monitor
A server you never look at is a server you cannot defend. Add a monitoring check and read your logs occasionally — Reading your logs shows how.
Optional: intrusion detection
For higher-value hosts, CrowdSec (crowd-sourced blocking, MIT-licensed) and Wazuh (host intrusion detection) add real depth. Both are documented in our app hosting guides.
Related reading