Every box I have ever put on the internet started getting probed within minutes. Not days, minutes. Hardening is just the list of small decisions that make those probes useless. This is the checklist I run on a fresh Debian server, in order, and the reasons stay short because the reasons are boring.

Updates on autopilot first

Skip this and nothing else matters, since most compromises start with a fixable bug that was never applied.

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

Security updates only is fine. If the box can tolerate reboots, let it; otherwise needrestart will tell you what is waiting.

Then SSH, because it is the front door

# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers deploy
X11Forwarding no
ssh-keygen -t ed25519 -a 64
ssh-copy-id deploy@server

Reload with systemctl reload ssh and test from a second terminal before you close the first. I locked myself out once, in a data center, on a Sunday. Do not be me.

A firewall that says no by default

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw enable

Then add ports as you actually open services. An unused open port is not harmless — it is a service waiting to be fingerprinted.

CrowdSec, because the noise is not random

The logins you see are mostly bots sharing blocklists of bad IPs. CrowdSec pools those lists: when some other admin's server gets attacked, your firewall already knows the attacker.

apt install crowdsec
cscli alerts list

A day later, cscli decisions list should show names you never saw in your own logs. That is the community working.

Know what is listening

ss -tulpn

Once a month. Anything bound to 0.0.0.0 that should not be public — bind it to the mesh interface instead. Anything you do not recognize, investigate until you do.

Logs that survive the attacker

If someone does get root, the first thing they edit is the logs on that box. Send yours somewhere append-only, even a cheap VPS:

# /etc/rsyslog.d/50-remote.conf
*.* @10.0.0.5:514

Keep 90 days. An incident found three weeks late needs logs that go back further than a week.

An admin account that is not root

Daily work happens as a normal user, admin actions go through sudo, and root login over SSH stays off. It costs nothing and it means one mistake does not hand over the box.

None of this is clever. That is the point. Servers get taken because the basics were skipped, not because the attacker was brilliant.