Hey folks,
Saugat here - aka ProSaugat 👋. It's been a while since my last post, and honestly, that gap has been eating at me a bit. Between work firefighting and life doing what life does, the blog took a back seat. But I'm back at it, and I wanted to come back with something that actually earns its place in your bookmarks - not just another "what is X" post.
So today we're talking about Linux server hardening - the checklist I personally run (or automate) every single time a new box goes into production. If you've ever spun up a fresh Ubuntu or RHEL server, left it on defaults, and quietly hoped for the best - this one's for you. Let's fix that habit together.
Why Bother Hardening a Server At All?
Here's the uncomfortable truth: most servers don't get breached because of some genius zero-day exploit. They get breached because of the boring stuff — root login left open, password auth on SSH, no firewall, six-month-old unpatched packages. Attackers don't need to be clever when the front door is unlocked and the lights are off.
Run through this checklist on a fresh box, and you'll close off roughly 90% of what opportunistic scanners and bots are actively probing for — before you even get to fancy DevSecOps tooling or SIEM dashboards. Let's get into it.
1. Initial Setup & Updates
First things first - update everything.
# Debian/Ubuntu
sudo apt update && sudo apt full-upgrade -y
# RHEL/Rocky/AlmaLinux
sudo dnf upgrade --refresh -y
Then set your timezone and hostname properly:
sudo timedatectl set-timezone UTC
sudo hostnamectl set-hostname your-server-name
Pro tip from experience: always run production servers on UTC. Trying to correlate logs across five servers in five timezones during an actual incident is a special kind of pain - I've been there at 2 AM, and I don't recommend it.
2. User & Account Hardening
Stop operating as root day-to-day. Create a proper sudo user:
sudo adduser deploy
sudo usermod -aG sudo deploy # Debian/Ubuntu
sudo usermod -aG wheel deploy # RHEL-based
Enforce a real password policy:
sudo apt install libpam-pwquality -y
Edit /etc/security/pwquality.conf:
minlen = 14
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
And lock any account you're not actively using:
sudo passwd -l <username>
3. SSH Hardening (The Big One)
SSH is the number one entry point attackers scan for, worldwide, every second of every day. This one section alone will stop the vast majority of automated attacks hitting your box.
Edit /etc/ssh/sshd_config:
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers deploy
X11Forwarding no
Restart SSH:
sudo systemctl restart sshd
Important - don't skip this: copy your public key over and test login in a second terminal window before you disable password auth. Locking yourself out of a remote box is basically a rite of passage in this field, but you don't have to learn it the hard way.
ssh-copy-id -p 2222 deploy@your-server-ip
If you're managing more than a handful of servers, look into SSH certificate authentication - it beats rotating individual public keys across a whole fleet.
4. Firewall Configuration
UFW (Ubuntu/Debian):
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp
sudo ufw allow 80,443/tcp
sudo ufw enable
firewalld (RHEL/Rocky/AlmaLinux):
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Rule I live by: deny by default, allow explicitly. Every open port on your server should have a reason you can actually explain out loud.
5. Brute-Force Protection with Fail2Ban
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
Create /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 3600
findtime = 600
For anything web-facing, add jails for Nginx/Apache auth failures too - Fail2Ban isn't just an SSH-only tool.
6. Kernel & Network Hardening
Create /etc/sysctl.d/99-hardening.conf:
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.log_martians = 1
kernel.randomize_va_space = 2
Apply it:
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
If you're not using IPv6, disable it explicitly instead of leaving it half-configured and unmonitored. An unmanaged protocol is an unmanaged attack surface.
7. File System & Permissions
- Mount
/tmpwithnoexec,nosuid,nodev- it blocks a very common privilege-escalation trick. - Lock down sensitive files:
sudo chmod 700 /root
sudo chmod 600 /etc/shadow
sudo chmod 644 /etc/passwd
And periodically hunt for world-writable files:
sudo find / -xdev -type f -perm -0002 -exec ls -l {} \;
8. Logging, Auditing & Monitoring
You can't respond to what you can't see.
sudo apt install auditd -y
sudo systemctl enable --now auditd
Ship your logs off-box. If someone does manage to get root, wiping local logs is step one for them — don't let it be step one that actually works.
Watch for: repeated failed logins from the same subnet, successful logins at odd hours, and sudo grants you don't remember making.
9. Automatic Updates
# Debian/Ubuntu
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
# RHEL-based
sudo dnf install dnf-automatic -y
sudo systemctl enable --now dnf-automatic.timer
Auto-apply security patches, but hold major/feature upgrades for a proper maintenance window — nobody wants a breaking change waking them up at 3 AM.
10. Continuous Hardening in 2026
Hardening isn't a one-and-done checklist anymore - it's continuous. A few things worth building into your workflow this year:
- CIS Benchmark scoring with tools like Lynis or OpenSCAP:
sudo apt install lynis -y
sudo lynis audit system
- Infrastructure as Code - bake these settings into your Ansible/Terraform provisioning so every new server ships hardened by default, not by memory.
- DevSecOps integration - scan base images in CI before they ever touch production.
The Quick-Reference Checklist
☐ System fully updated☐ Hostname & UTC timezone set
☐ Non-root sudo user created
☐ Root SSH login disabled
☐ Password auth disabled, key-based only
☐ SSH port changed from default
☐ MaxAuthTries limited
☐ Strong password policy enforced
☐ Unused accounts locked
☐ Firewall enabled, default-deny
☐ Only required ports open
☐ Fail2Ban installed and jailed
☐ Kernel sysctl hardening applied
☐ IPv6 disabled if unused
☐ /tmp mounted noexec/nosuid
☐ Sensitive file permissions locked down
☐ World-writable files audited
☐ auditd installed and running
☐ Logs shipped off-box
☐ Automatic security updates enabled
☐ Lynis/OpenSCAP scan run and tracked
☐ Hardening codified in IaC
☐ Backup strategy tested, not just configured
☐ 2FA on any exposed admin panel
☐ Unused services/daemons disabled
☐ SUID/SGID binaries audited
☐ Cron jobs reviewed for stray scripts
☐ Network segmentation in place
☐ Incident response runbook exists
☐ This whole list re-run quarterly
FAQ
How often should I re-harden a server?
Treat it as ongoing, not one-time. Run a Lynis or OpenSCAP scan monthly, and do a full re-audit after any major OS upgrade.
Is UFW enough, or do I need something more advanced?
UFW is solid for single servers and small fleets. For larger or cloud-native setups, pair it with security groups/NACLs at the cloud layer and consider a proper NIDS on top.
Does changing the SSH port actually help?
It won't stop a targeted attacker, but it massively cuts the noise from automated bots scanning port 22 - meaning cleaner logs and fewer false alarms for your real monitoring to catch.
What's the single highest-impact step here?
Disabling SSH password authentication. One config change, and you've killed off the most common successful attack vector - credential stuffing and brute force - entirely.
Wrapping Up
That's the checklist I run on every box, every time - no exceptions. None of this is exotic, and that's kind of the point. Most breaches happen because the basics got skipped, not because attackers are unusually brilliant. Run through this list on your next server, and you'll already be ahead of most of the internet.
If this helped you out, share it with your team - and if you catch me missing something, drop it in the comments, I genuinely read every one of them.
That's it for today, folks. Stay patched, stay paranoid (just a little), and I'll see you in the next one.
.jpg)
