How to Harden a Linux VPS: UFW, Fail2Ban, and SSH Key Authentication Made Simple
How to Harden a Linux VPS: UFW, Fail2Ban, and SSH Key Authentication Made Simple
Running a virtual private server (VPS) gives you full control, but it also makes you a prime target for automated attacks. In 2024, more than 70 % of compromised web servers were breached through weak SSH configurations or open ports that could be exploited by bots. The good news is that a solid hardening routine can be implemented in under an hour, and it requires only native Linux tools. This guide walks you through the three most effective layers of protection—SSH key authentication, the Uncomplicated Firewall (UFW), and Fail2Ban—while keeping the steps reproducible on any fresh Ubuntu or Debian‑based cloud VPS.
Why Basic Hardening Matters
Even a newly provisioned VPS comes with a default sshd configuration that allows password logins and exposes port 22 to the entire internet. Attackers scan these ports relentlessly, trying common usernames and passwords. Each successful guess gives them a foothold for privilege escalation, data theft, or crypto‑mining. By eliminating password logins, restricting inbound traffic, and automatically banning repeated offenders, you shrink the attack surface dramatically and force adversaries to waste time on manual exploitation.
Step 1 – Secure SSH Access with Key‑Based Authentication
Generate a Key Pair
On your local workstation, open a terminal and run:
ssh-keygen -t ed25519 -C "your_email@example.com"
Accept the default file location (~/.ssh/id_ed25519) and, if you wish, protect the private key with a passphrase. The command creates two files: id_ed25519 (private) and id_ed25519.pub (public).
Copy the Public Key to the VPS
Assuming you still have password access for the first login, copy the key with:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-vps-ip
The authorized_keys file on the server now contains your public key, enabling key‑based authentication.
Disable Password Authentication
Edit the SSH daemon configuration:
sudo nano /etc/ssh/sshd_config
Set the following directives:
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
Save the file and restart the service:
sudo systemctl restart sshd
From now on, only clients presenting a matching private key can log in.
Step 2 – Lock Down Network Traffic Using UFW
Install and Enable UFW
UFW is available in the default repositories. Install and activate it with a single command:
sudo apt-get update && sudo apt-get install ufw -y
sudo ufw enable
UFW will start blocking all inbound connections except those you explicitly allow.
Create a Minimal Rule Set
First, allow SSH from your trusted IP (replace YOUR.IP.ADDRESS):
sudo ufw allow from YOUR.IP.ADDRESS to any port 22 proto tcp
If you need HTTP/HTTPS, add:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Finally, verify the active rules:
sudo ufw status verbose
Rate‑Limit SSH Connections
To mitigate credential‑stuffing attacks, enable UFW’s built‑in rate limiting:
sudo ufw limit 22/tcp
This permits up to six connection attempts within 30 seconds from a single IP, after which further attempts are dropped for a short period.
When you need a scalable environment, you can rely on Cloud VPS to streamline your deployment and maintain a consistent security baseline across multiple instances.
Step 3 – Deploy Fail2Ban to Thwart Brute‑Force Attacks
Install Fail2Ban and Default Jails
Fail2Ban monitors log files and bans IPs that show malicious behavior. Install it with:
sudo apt-get install fail2ban -y
The package ships with a default /etc/fail2ban/jail.conf. Never edit this file directly; instead, create a local override:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Customizing the SSH Jail
Open jail.local and locate the [sshd] section. Adjust the parameters to suit your risk tolerance:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400 ; 24 hours
findtime = 600 ; 10 minutes
These settings ban an IP for a full day after three failed attempts within ten minutes.
Testing the Ban Mechanism
Trigger a fake failure from another machine:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@your-vps-ip
After three incorrect passwords, fail2ban-client status sshd should list the offending IP under “Banned IPs”.
Step 4 – Ongoing Monitoring and Automated Updates
Logwatch or Fail2Ban Email Alerts
Fail2Ban can send you an email each time it bans an address. Add the following to /etc/fail2ban/jail.local:
destemail = security@example.com
sender = fail2ban@example.com
action = %(action_mwl)s
Ensure mailutils or an equivalent MTA is installed so the server can dispatch mail.
Unattended‑Upgrade for Security Patches
Keeping the OS patched is the final line of defense. Install the unattended‑upgrade package and enable it:
sudo apt-get install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
The tool automatically applies security updates daily, reducing the window of exposure for known CVEs.
Conclusion
Hardening a Linux VPS does not require exotic tools—just a disciplined combination of SSH key authentication, a tightly scoped UFW firewall, and Fail2Ban’s automated banning. By following the steps above, you create three independent barriers that force attackers to expend significant effort for a single foothold. Pair these measures with regular log reviews and automated OS updates, and you’ll maintain a resilient server posture without constant manual intervention.