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 servicessudo systemctl list-unit-files --state=enabled and disable anything you don’t recognize
  • Set up logwatch or a log aggregator — you can’t defend what you can’t see
  • Use sudo instead of su — granular permissions beat shared root access
  • Enable 2FA for SSHlibpam-google-authenticator adds TOTP to your login flow
  • Keep your kernel updatedsudo apt upgrade or use needrestart to 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.