The Server Security Habits We Actually Use (Not Just What the Checklists Say)

Most server breaches we've been called in to clean up weren't clever attacks. They were boring, avoidable stuff nobody got around to fixing.

Illustration of a server rack with a shield and padlock overlay, representing server security hardening steps like SSH hardening and firewall configuration

Every time we take over a server someone else set up two or three years ago and haven't touched since, we already know roughly what we're going to find before we even log in. Root login still enabled over SSH. No firewall, or one that's technically on but lets everything through. Packages that haven't been updated since the server was first provisioned. It's almost never anything exotic — it's just the basics nobody circled back to.

So instead of another generic "top 10 server security tips" list, here's what we genuinely set up on every server we manage, and why we bother with each one.

Lock down SSH first — it's the front door

If someone's going to break into your server, SSH is almost always how. So this is where we start, every time.

First thing: disable root login over SSH. Create a regular user, give it sudo access, and turn off PermitRootLogin in /etc/ssh/sshd_config. It's a five-minute change and it closes off the single most common entry point for automated brute-force bots.

Second: switch to key-based authentication and turn off password login entirely. Passwords get guessed. Keys don't, practically speaking. Yes, it's mildly annoying the first time you set it up on a new machine — you get used to it fast.

We get asked a lot whether moving SSH off port 22 actually helps. Honestly? It mostly just cuts down on log noise from automated scanners hammering the default port — it's not real security on its own. We still do it, but we don't pretend it's doing more than it is.

Turn the firewall on. Actually turn it on.

This sounds obvious, and yet — we've lost count of how many servers we've inherited where ufw was installed but never enabled, or enabled with rules that allowed basically everything.

ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

That's it. Deny everything by default, then explicitly open only what the server actually needs to serve. If you're not running a mail server, don't leave port 25 open "just in case." Every open port is one more thing an attacker can try.

fail2ban: cheap, and it works

fail2ban watches your logs and temporarily bans IPs that fail login attempts too many times in a row. It's not glamorous, but it quietly kills off the constant background noise of bots trying random usernames and passwords against your SSH port around the clock. Once it's set up, you genuinely forget it's there — which is sort of the point.

Keep the OS updated, and don't rely on remembering to do it manually

Security patches don't help if they sit unapplied for eight months. On Ubuntu servers we set up unattended-upgrades so security patches get applied automatically without someone needing to remember to SSH in and run apt update && apt upgrade every week. Manual updates are the kind of task that always seems fine to postpone — until the one time it wasn't.

Real talk: the servers we've seen actually get compromised were almost never running some cutting-edge exploit. They were running months-old software with a well-known, already-patched vulnerability that nobody had gotten around to fixing.

A few things people forget

Beyond the basics above, a handful of things that don't come up in every generic checklist but matter in practice:

  • Database ports shouldn't face the internet. MySQL or PostgreSQL should only accept connections from localhost or your app server's internal IP — never bound to 0.0.0.0 with the port open to the world.
  • Backups need to actually be tested. A backup you've never restored from isn't really a backup, it's a hope. Test the restore process before you need it for real.
  • TLS certificates auto-renew, or someone forgets. If you're using Let's Encrypt, make sure the renewal cron job or systemd timer is actually running — expired certificates have a way of going unnoticed until a client emails asking why the site's showing a security warning.
  • Log in as yourself, not as a shared "admin" account. If three people all SSH in as the same generic user, you have no idea who actually did what when something goes wrong.

None of this is exciting. That's kind of the point.

Server security isn't really about outsmarting some elite hacker. Most of the time it's about not leaving the equivalent of an unlocked door and an open window for months at a time. Once the basics above are in place, you've already ruled out the overwhelming majority of what actually gets servers compromised in practice.

CG
CodeGIF DevelopersAndroid, web & server development — Ahmedabad, India

Not sure if your server is actually locked down?

We can audit your current setup and fix what's missing — for clients in India, the USA and Europe.

Get in touch
Chat with us