Journal
Hardening Your Linux Server: A Practical Checklist
Every server you expose to the internet is a target. Bots will find your SSH port within minutes of going live. The good news is that a handful of straightforward steps will deflect the vast majority of attacks.
SSH: The Front Door
The default SSH configuration ships wide open. Start here.
Disable root login and password auth
Edit /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Generate an ed25519 key pair on your local machine if you haven’t already:
ssh-keygen -t ed25519 -C "you@workstation"
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
Restart the daemon:
sudo systemctl restart sshd
Change the default port
Moving SSH off port 22 won’t stop a determined attacker, but it cuts log noise by 99%. Pick something above 1024:
Port 2222
Update your firewall rules before restarting sshd, or you’ll lock yourself out.
Firewall with UFW
UFW wraps iptables into something you can reason about:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
Check the status:
sudo ufw status verbose
That’s it. Three open ports. Everything else is dropped.
Fail2Ban
Fail2ban watches log files and bans IPs that show malicious patterns. Install and enable:
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
Create a local jail configuration at /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 3600
findtime = 600
Three failed attempts in 10 minutes earns a one-hour ban. Adjust to taste.
Unattended Upgrades
Security patches shouldn’t wait for you to remember. On Debian/Ubuntu:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Verify the config in /etc/apt/apt.conf.d/50unattended-upgrades allows security updates. You can also enable automatic reboots when required:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
Quick Wins
A few more items for the checklist:
- Disable unused services —
sudo systemctl list-unit-files --state=enabledand disable anything you don’t recognize - Set up logwatch or a log aggregator — you can’t defend what you can’t see
- Use
sudoinstead ofsu— granular permissions beat shared root access - Enable 2FA for SSH —
libpam-google-authenticatoradds TOTP to your login flow - Keep your kernel updated —
sudo apt upgradeor useneedrestartto flag stale processes
The Ongoing Work
Hardening isn’t a one-time event. Subscribe to your distro’s security mailing list, review your access logs weekly, and automate everything you can. The goal isn’t perfection — it’s raising the cost of compromise above what an opportunistic attacker is willing to pay.