How to harden a Linux server: a practical checklist
A public server is probed within minutes of going online. This hardening checklist covers users, SSH, firewalls, updates, fail2ban and monitoring — step by step.
The moment a server gets a public IP, automated bots start probing it. Hardening isn't paranoia — it's basic hygiene. Work through this checklist on any new VPS and you'll shut out the overwhelming majority of attacks.
1. Keep the system updated
Unpatched software is the number one way servers get compromised. Update now and automate it:
sudo apt update && sudo apt upgrade -y
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
2. Create a non-root user
Never operate as root day to day. Make a sudo user:
sudo adduser deploy
sudo usermod -aG sudo deploy
3. Use SSH keys, not passwords
Keys can't be brute-forced. Copy yours up from your local machine:
ssh-copy-id deploy@YOUR_SERVER_IP
Then disable password login and root SSH in /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
Reload and verify a fresh login works before closing your session:
sudo systemctl restart ssh
4. Configure a firewall
Default-deny incoming, allow only what you serve:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
5. Install fail2ban
fail2ban watches logs and bans IPs that fail login repeatedly, killing brute-force attempts:
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
The default jail already protects SSH.
6. Change or protect the SSH port (optional)
Moving SSH off port 22 cuts a lot of automated noise (though it's obscurity, not real security). If you do, allow the new port in the firewall *first*:
sudo ufw allow 2222/tcp
Then set Port 2222 in sshd_config and reload.
7. Lock down services to localhost
Databases, caches and admin interfaces should not listen on public interfaces. Bind them to 127.0.0.1 and reach them over SSH tunnels or the firewall. Check what's listening:
sudo ss -tulpn
Anything on 0.0.0.0 that doesn't need to be public should be closed or restricted.
8. Enforce strong authentication everywhere
- No shared passwords; unique credentials per person.
- Disable unused accounts.
- Consider two-factor for SSH on sensitive boxes.
9. Remove what you don't use
Every installed package is potential attack surface. Uninstall services you don't need and disable ones you don't use:
sudo systemctl disable --now some-unneeded-service
10. Set up automatic, tested backups
Security includes recovery. Schedule regular backups and confirm you can actually restore them. Nxeon offers snapshots and scheduled backups from the dashboard, so you always have a recent restore point independent of the server itself.
11. Monitor and review logs
Know what your server is doing. Watch authentication attempts and resource use:
sudo journalctl -u ssh --since "1 hour ago"
sudo lastb | head # recent failed logins
htop
12. Principle of least privilege
Give each user, service and app only the access it needs — no blanket root, no world-writable files, no unnecessary sudo. It's the single most effective habit in security.
A ten-minute baseline
Steps 1–5 alone — updates, a sudo user, key-only SSH, a firewall and fail2ban — take about ten minutes and block the vast majority of real-world attacks. Do them on every server, every time. On a fresh Nxeon VPS with full root you can run this entire checklist immediately after deploy, so your server is hardened before it ever hosts anything.