Linux Server Hardening: The Checklist That Works

Linux server hardening checklist showing terminal with SSH config fail2ban and UFW firewall settings on dark scree

The first time a server of mine was compromised, it was not a sophisticated attack. The auth log showed 41,000 failed login attempts in a single week, mostly from three IP ranges. Somewhere in that noise, a script got in — a simple brute force that worked because password authentication was left on and the root password was embarrassingly close to "password." The lesson was not that attacks are clever. It is that most of them do not need to be.

After rebuilding that machine and reading every hardening guide available, the honest conclusion is that most of them are overkill. A small VPS running a blog and a few services does not need a twenty-page security policy. It needs a short list of things that actually stop the attacks that actually happen.

Step 0: Decide What You Are Protecting

Hardening is a trade-off. Every lock you add is something you must manage, update, and possibly trip over at 2 AM during an outage. A server hosting nothing sensitive does not need the same treatment as one holding a database of customer emails. Decide the level, then apply it. Applying "maximum security" everywhere is exactly how you lock yourself out of your own machine.

Step 1: SSH First — It Is the Front Door

If your server is reachable on the internet, SSH is the door everyone knocks on. Fix it first because the fixes are cheapest here. Set up key-based authentication, then edit /etc/ssh/sshd_config:

PasswordAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
  • PasswordAuthentication no — kills the entire class of brute-force attacks. Bots can hammer all they want; there is nothing left to guess.
  • PermitRootLogin prohibit-password — root login only with keys, never with a password. The middle ground that keeps you from locking yourself out at 11 PM.
  • PubkeyAuthentication yes — required for the above to work.

Then reload with sudo systemctl restart sshd — but only after confirming your key works in a second terminal session. This is the exact moment people lock themselves out. Keep one session open until the new one connects cleanly.

Step 2: Fail2ban — Turn the Noise Into Nothing

Fail2ban watches the logs and bans IPs that fail to authenticate too many times. The defaults are sensible: it watches SSH, bans after repeated failures, and unbans automatically so you never permanently block a user with a typo'd password. The honest description: fail2ban will not stop a targeted attack, and anyone claiming otherwise is overselling it. What it does is eliminate background noise — after enabling it, my auth log dropped from thousands of attempts a day to a handful. Quiet logs matter more than they sound: when the noise is gone, the unusual stands out and you actually read the logs.

Step 3: UFW — The Firewall That Doesn't Fight You

iptables is powerful and completely unintuitive. UFW is a thin wrapper that makes the common cases simple — and the common cases are all most servers need:

sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

Block everything coming in except the ports you named, allow everything going out. Three allowed ports — SSH, HTTP, HTTPS — and everything else closed. If you run other services, add their ports explicitly. And enable the SSH rule before enabling the firewall; the deny-incoming default does not care that you were in the middle of something.

Step 4: Automatic Updates — The Boring Hero

Nobody gets excited about updates. They are invisible, unglamorous, and the single highest-value security action on any Linux system. Most real-world compromises in 2026 are not clever zero-days — they are known vulnerabilities on unpatched servers, exploited by scripts within days of disclosure. Enable automatic security updates and move on. The vulnerability gets patched quietly, before the exploit script reaches your door.

Step 5: The Weekly Ten-Minute Habit

Hardening is a setup task, but maintenance is a habit. Once a week, check who has logged in, review authentication failures, confirm updates are applied, and verify the firewall is still enforcing. Four commands and a quick read tell you the server is healthy. The people who get compromised are rarely the ones with elaborate defenses — they are the ones who stopped looking. The habit is the defense.

What Not to Waste Time On

  • Changing the SSH port — stops some automated noise, but fail2ban already handles the noise. It adds friction and stops exactly zero determined attackers.
  • Disabling ping — the classic "looks secure" checkbox that does nothing except break debugging.
  • A dozen monitoring tools — for a small server, a weekly log check beats a dashboard you stop opening after week two.

These things feel productive, which is precisely why they are popular. But feel is not defense.

Server hardening, done properly, is a short list: keys instead of passwords, a firewall that blocks by default, fail2ban for the noise, automatic updates for the boring stuff, and a weekly habit of looking at the logs. It takes an afternoon to set up and ten minutes a week to maintain — and it converts your server from a target with a welcome mat into a door that is actually locked. Once it is done, you stop thinking about it. That is exactly how good security should feel.

Previous Post Next Post