I manage a handful of VPS boxes. Every time I spin up a new one I forget something. Disable root login? Nope. Set up fail2ban? Maybe next week. Unattended upgrades? Lol.

After one too many "wait, how did that get in" moments, I wrote myself a checklist. Here are the 5 rules I actually follow now ( and why ).

Server terminal
The only screen that matters when you are hardening a box. ( )

1. Disable Root Login and Password Auth

This is rule zero. If you can SSH in as root with a password, you are playing on easy mode ( for the attacker ).

Here is my sshd_config snippet:

# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey

Generate a key pair locally, copy the public key to the server, then restart sshd. Do not close your session until you have confirmed the new key works ( trust me ).

ssh-keygen -t ed25519 -C "myserver"
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# Test in a NEW terminal before closing this one

2. Fail2ban or Go Home

Brute force attacks are not theoretical. They are constant. Every single one of my servers gets hammered within hours of going live.

sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

The defaults are fine to start. After a week, check the logs:

sudo fail2ban-client status sshd
# Banned IPs in the last 24h: usually dozens

If you want to be more aggressive ( I do ):

# /etc/fail2ban/jail.local
[sshd]
enabled = true
maxretry = 3
bantime = 3600
findtime = 600
Security lock
Lock it down or someone else will. ( )

3. Unattended Upgrades Are Not Optional

I used to update servers manually. That lasted until I realized I had a box running a kernel from 6 months ago with 3 known CVEs. Never again.

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades

Or configure it manually if you want more control:

# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

Yes, I let it auto-reboot at 3am. My servers are not running heart surgery ( )

4. Firewall: nftables Over iptables

I know, iptables is everywhere. Documentation, Stack Overflow answers, every tutorial from 2012. But nftables is the replacement and it is better. Deal with it.

sudo apt install nftables -y
sudo systemctl enable nftables

Here is my standard ruleset:

#!/usr/sbin/nft -f
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        
        # Allow loopback
        iif lo accept
        
        # Allow established connections
        ct state established,related accept
        
        # Allow SSH
        tcp dport 22 accept
        
        # Allow HTTP/HTTPS
        tcp dport { 80, 443 } accept
        
        # Allow ICMP ( ping )
        ip protocol icmp accept
    }
    
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
    
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Default policy: drop everything, allow only what you need. If you need more ports, add them explicitly. No wildcards, no hope.

Network cables
Physical security starts with logical security. ( )

5. Audit and Log Everything

If you are not reading your logs, the hardening does not matter. You are just making the attacker work slightly harder.

Install auditd:

sudo apt install auditd -y
sudo systemctl enable auditd
sudo systemctl start auditd

Key rules to watch:

# /etc/audit/rules.d/audit.rules
-w /etc/ssh/ -p wa -k ssh_config
-w /etc/nftables.conf -p wa -k firewall_config
-w /etc/sudoers -p wa -k sudoers
-w /var/log/auth.log -p wa -k auth_log
-a always,exit -F arch=b64 -S execve -k exec

Then review:

sudo ausearch -k ssh_config -ts today
sudo ausearch -k firewall_config -ts this-week

I also ship logs to a central location ( another server, not the same one ). If someone roots your box, the first thing they do is clean the logs. You want copies elsewhere.

Technology abstract
The view from outside the firewall. ( )

Conclusion

These 5 rules take maybe 20 minutes on a fresh box. 20 minutes that save you from cleaning up at 2am because someone brute-forced your root password ( again ).

I keep these in a shell script that I run on every new server. Copy, paste, sleep better.

Thank you