Disclosure: we may earn a commission or referral reward from CloudCone, Contabo, DigitalOcean (account credit, not cash), Hostwinds, InterServer, RackNerd, VPSDime and Vultr if you sign up through our links. It does not change the price you pay. Every other provider pays us nothing. Prices in this guide are as of the date shown and may have changed; see the comparison pages for the latest checked prices.
Guides · BLOG
How to secure a VPS in 2026: the practical checklist
Some prices quoted in this guide are out of date. It is being rebuilt on our price index; for current prices use the comparison pages, which show when each price was checked.
A fresh VPS with the default configuration is scanned by botnets within minutes and has SSH brute-force attempts within an hour. This checklist takes 30 minutes and puts a fresh VPS in an actually-defensible position for real production use.
The threat model
We're not defending against nation-state actors. We're defending against:
1. Automated SSH brute-force looking for weak or default passwords.
2. Web application vulnerability scanners looking for known bugs in WordPress, phpMyAdmin, common CMSes.
3. Compromised NPM/PyPI/Composer packages that make outbound connections from your app.
4. Someone opening your ~/.aws/credentials file because you accidentally exposed it.
Real threats. Easily countered with basic hardening.
Step 1: SSH keys only (5 minutes)
Never SSH with a password.
Generate a key on your local machine if you don't have one:
```bash
ssh-keygen -t ed25519 -C "[email protected]"
```
Add the public key to your VPS:
```bash
ssh-copy-id user@vps
```
Or manually paste ~/.ssh/id_ed25519.pub into /home/user/.ssh/authorized_keys on the VPS.
Disable password SSH:
```bash
sudo sed -i 's/^#PasswordAuthentication./PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
```
Test in a NEW terminal before closing your current session. If you lock yourself out with a bad config, use your provider's console access to recover.
Step 2: Disable root SSH (2 minutes)
Nobody should log in as root. Create a sudo user instead:
```bash
adduser deploy
usermod -aG sudo deploy
mkdir -p /home/deploy/.ssh
cp ~/.ssh/authorized_keys /home/deploy/.ssh/
chown -R deploy:deploy /home/deploy/.ssh
```
Disable root SSH:
```bash
sudo sed -i 's/^#PermitRootLogin./PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
```
Test with ssh deploy@vps and sudo -i.
Step 3: Firewall with UFW (2 minutes)
Only open the ports you actually need:
```bash
ufw allow OpenSSH
ufw allow 80
ufw allow 443
ufw --force enable
```
Check: ufw status.
Step 4: fail2ban for SSH (3 minutes)
Blocks IPs that fail SSH login attempts:
```bash
apt install fail2ban
```
Create /etc/fail2ban/jail.local:
```
[sshd]
enabled = true
findtime = 10m
maxretry = 3
bantime = 1h
```
```bash
systemctl restart fail2ban
```
Check bans: fail2ban-client status sshd.
Step 5: Automatic security updates (2 minutes)
Unattended-upgrades installs critical security patches automatically:
```bash
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
```
Verify enabled: /etc/apt/apt.conf.d/20auto-upgrades should have both settings at "1".
By default, only security-marked updates auto-install. Package updates that could break services stay manual.
Step 6: Remove services you don't use (2 minutes)
```bash
systemctl list-units --type=service --state=running
```
Anything you don't recognise, look up. If you don't need it, disable it:
```bash
systemctl disable --now unnecessary-service
```
Common candidates: sendmail (use msmtp or a relay instead), rpcbind, avahi-daemon, snapd (if you don't use snaps).
Step 7: Set up log monitoring (5 minutes)
Install logwatch for nightly emailed summaries:
```bash
apt install logwatch
```
Edit /etc/logwatch/conf/logwatch.conf:
```
Detail = Med
MailTo = [email protected]
```
Requires working mail delivery. Set up msmtp or a relay to Sendgrid/Mailgun if you don't have one.
Every morning: quick scan of last night's failed SSH attempts, sudo usage, cron output.
Step 8: Nginx / Apache hardening (5 minutes)
If you're serving HTTP:
Hide server version headers. In Nginx:
```nginx
/etc/nginx/nginx.conf, http block
server_tokens off;
```
In Apache:
```
/etc/apache2/conf-enabled/security.conf
ServerTokens Prod
ServerSignature Off
```
Rate limit — Nginx limit_req_zone for authenticated endpoints (login pages, API endpoints).
Deny access to sensitive files — .env, .git, backup files. In Nginx:
```nginx
location ~ /\.(env|git|htaccess) { deny all; }
location ~ \.(bak|old|orig|save)$ { deny all; }
```
Step 9: Application-layer security
Beyond the OS:
Use Cloudflare in front — see our Cloudflare setup guide. Blocks a lot of automated attacks at the edge.
Keep application dependencies updated. For Node: npm audit fix. For Python: pip-audit. For PHP: composer audit.
Rotate secrets regularly. API keys, database passwords, auth tokens.
Use environment variables for secrets, not hardcoded in code.
Step 10: Backup (5 minutes)
Because the best security is not needing to be secure — you can recover from a breach:
See our automated backups guide. Encrypted, off-server, tested restore.
What NOT to do
- Don't change the SSH port and call it security. Obscurity is not security. Botnets scan all ports; only SSH keys + fail2ban actually help.
- Don't install "security software" like anti-virus. Modern Linux servers don't have Windows-style malware; the tools are enterprise-oriented and mostly noise on a small VPS.
- Don't disable IPv6 unless you have a specific reason. IPv6 is fine.
- Don't remove
sudoafter locking down. You'll need it. Just don'tNOPASSWDunless you know why. - Don't ignore
unattended-upgradesfailure emails. They mean auto-updates stopped.
After 30 minutes: you have
- SSH-key-only login.
- No root SSH.
- Firewalled ports.
- Brute-force protection.
- Auto-installed security patches.
- Log monitoring.
- Nightly summary emails.
That's the practical baseline. From here, security is a discipline — updated dependencies, monitored logs, encrypted backups, secrets rotation.
Related guides
- Shared hosting to plain VPS migration — includes basic hardening.
- How to monitor a VPS — pairs with security.
- How to add Cloudflare in front of your VPS — edge-level defence.
- How to set up automated backups on any VPS — recovery plan.