Skip to content
Back to Blog
Security10 min read

Server Security Hardening Checklist: 12 Steps [2026]

Lock down your Linux or Windows server with these twelve field-tested hardening steps covering SSH, firewalls, patching, and centralized logging.

Written by Abdul AbrorTechnical Hosting Support Engineer
Server Security Hardening Checklist: 12 Steps [2026]
On this page

A fresh server installation is rarely production-ready. Default configurations prioritize convenience over defense, leaving your box exposed to brute-force attempts, privilege escalation, and lateral movement if an attacker lands a foothold.

I've cleaned up after breaches where root SSH was open to the world, firewalls were disabled, and patches hadn't run in months. Every incident shared the same pattern: basic hardening would have stopped the attack cold. This checklist walks you through twelve steps that form a solid baseline for any Linux or Windows server handling real traffic or customer data.

1. Disable Root Login Over SSH

Root login is the most hammered target for automated scans. Disable it outright and force operators to log in as a regular user, then escalate with sudo.

On Linux, edit /etc/ssh/sshd_config:

PermitRootLogin no

Restart SSH:

sudo systemctl restart sshd

For Windows Server with OpenSSH, the same directive applies in C:\ProgramData\ssh\sshd_config. Test the change with a non-root account before closing your current session.

2. Enforce Key-Based Authentication

Passwords are guessable. SSH keys are not. Require public-key auth and turn off password login.

In /etc/ssh/sshd_config:

PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no

Generate a key pair on your workstation if you haven't already:

ssh-keygen -t ed25519 -C "[email protected]"

Copy the public key to the server:

ssh-copy-id [email protected]

Confirm key-based login works, then restart sshd. I've seen support tickets where an admin locked themselves out by disabling password auth before copying their key; always test first.

3. Change the Default SSH Port

Port 22 attracts the bulk of automated scans. Moving SSH to a non-standard port (e.g., 2222 or 49152) won't stop a determined attacker, but it eliminates 99% of the noise in your auth logs.

In /etc/ssh/sshd_config:

Port 2222

Update your firewall rules to allow the new port, restart SSH, and note the port in your connection manager. Security through obscurity isn't a substitute for real hardening, but it's a practical layering tactic.

4. Configure a Host-Based Firewall

Every server needs a firewall dropping packets by default and allowing only necessary services.

Linux: UFW or firewalld

Ubuntu and Debian ship with ufw. Allow SSH (or your custom port), HTTP/HTTPS, and your application ports, then enable it:

sudo ufw allow 2222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

CentOS and RHEL use firewalld:

sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Windows: Windows Defender Firewall

Open Windows Defender Firewall with Advanced Security, create inbound rules for Remote Desktop (if needed), HTTP/HTTPS, and your app ports. Set the default action to Block for all profiles.

5. Keep the System Patched

Unpatched vulnerabilities are the fastest route to compromise. Automate updates or commit to a weekly patch window.

Linux: Unattended Upgrades

Debian/Ubuntu:

sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Configure /etc/apt/apt.conf.d/50unattended-upgrades to auto-install security updates and reboot if needed.

RHEL/CentOS:

sudo yum install yum-cron
sudo systemctl enable --now yum-cron

Edit /etc/yum/yum-cron.conf to apply updates automatically.

Windows: Automatic Updates

Open Settings → Update & Security → Windows Update → Advanced options and enable automatic installation. For Windows Server, configure the update window to avoid disrupting production traffic.

I've responded to incidents where a months-old kernel vulnerability was the entry point. Patching isn't glamorous, but it stops the easiest attacks.

6. Disable Unused Services and Ports

Every running service is a potential attack surface. Audit what's listening and turn off anything you don't need.

List open ports on Linux:

sudo ss -tulpn

On Windows, use:

netstat -ano | findstr LISTENING

Disable unused services with systemctl on Linux or the Services console (services.msc) on Windows. Common candidates: Telnet, FTP (replace with SFTP), and legacy RPC services.

7. Implement Fail2Ban or Similar Intrusion Prevention

Fail2Ban watches your logs and blocks IPs after repeated failed login attempts. It's lightweight and effective against brute-force campaigns.

Install on Debian/Ubuntu:

sudo apt install fail2ban

Create /etc/fail2ban/jail.local:

[sshd]
enabled = true
port = 2222
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Restart:

sudo systemctl restart fail2ban

For Windows, consider third-party tools like EvlWatcher or IPBan that parse Event Logs and update firewall rules.

8. Harden Kernel Parameters with sysctl

Linux kernel settings can be tuned to resist network-based attacks. Edit /etc/sysctl.conf or create a file in /etc/sysctl.d/:

# Disable IP forwarding
net.ipv4.ip_forward = 0

# Enable SYN cookies
net.ipv4.tcp_syncookies = 1

# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Ignore ICMP pings
net.ipv4.icmp_echo_ignore_all = 1

# Log suspicious packets
net.ipv4.conf.all.log_martians = 1

Apply:

sudo sysctl -p

These settings won't prevent application-layer exploits, but they reduce the kernel's exposure to low-level network tricks.

9. Enable Centralized Logging

Logs are your first line of defense for detecting anomalies. Ship them off-box so an attacker can't erase the evidence.

Rsyslog to a Remote Server

On the client, edit /etc/rsyslog.conf:

*.* @@log-server.example.com:514

Restart rsyslog:

sudo systemctl restart rsyslog

On the log server, open port 514 and configure rsyslog to accept remote messages.

Windows Event Forwarding

Configure a Windows Event Collector and set up subscriptions in Event Viewer → Subscriptions. Forward Security, System, and Application logs.

Alternatively, use a SIEM or log aggregation service (Splunk, Graylog, ELK) if your infrastructure is large enough to justify it.

10. Restrict User Privileges and Use sudo

Never run applications as root or Administrator. Create service accounts with minimal permissions and require sudo for administrative tasks.

On Linux, add users to the sudo group:

sudo usermod -aG sudo username

For finer control, edit /etc/sudoers with visudo and grant specific commands.

On Windows, use Computer Management → Local Users and Groups to create standard user accounts and assign roles through Group Policy.

In support tickets I handled, privilege escalation was often the second stage after initial compromise. Limiting user rights contains the blast radius.

11. Install and Configure a File Integrity Monitor

File integrity monitoring detects unauthorized changes to system binaries, configuration files, and web roots.

AIDE on Linux

Install:

sudo apt install aide

Initialize the database:

sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Run checks regularly via cron:

0 3 * * * /usr/bin/aide --check

Windows: Tripwire or OSSEC

Both offer file integrity modules for Windows. Configure them to monitor C:\Windows\System32, C:\Program Files, and your web root.

12. Enable Automatic Security Audits

Run periodic security audits to catch configuration drift and new vulnerabilities.

Lynis on Linux

Lynis is an open-source security auditing tool:

sudo apt install lynis
sudo lynis audit system

Review the output for warnings about weak permissions, missing patches, and insecure services.

Microsoft Baseline Security Analyzer

For Windows Server, download the Microsoft Security Compliance Toolkit and run Policy Analyzer against your system. It flags deviations from CIS benchmarks and Microsoft's own baselines.

Schedule these audits monthly and address high-severity findings immediately.

So What If You Skip a Step?

Each item on this checklist closes a specific attack vector. Skip SSH hardening and you'll see brute-force attempts in your logs within hours. Skip patching and you're vulnerable to every public exploit published since your last update. Skip logging and you won't know you've been breached until a customer reports it.

Hardening isn't a one-time checklist. Configuration drift, new CVEs, and infrastructure changes mean you need to revisit these steps regularly. I recommend auditing your baseline every quarter and after any major deployment.

FAQ

How long does full hardening take?
For a single server, plan two to four hours if you're configuring everything manually. Automation with Ansible or PowerShell DSC cuts that to minutes after the initial setup.

Should I harden development servers the same way?
Yes, especially if they're internet-facing or handle production data. Dev boxes are common pivot points in breaches.

What about containers and cloud instances?
The same principles apply. Harden the host OS, limit container privileges, use security groups or network ACLs as your firewall, and ship logs to a central store.

Can I use these steps on a VPS?
Absolutely. VPS providers give you root access, so you're responsible for hardening. Some managed hosting platforms handle parts of this for you, but verify what's covered.

How do I test that hardening worked?
Run a port scan from an external host with nmap, attempt SSH login with a weak password (it should fail), and check that your firewall drops unexpected traffic. Lynis and similar tools will confirm most settings.

What to Check First

If you inherit a server or spin up a new instance, tackle SSH and the firewall before anything else. Those two steps eliminate the easiest attacks and buy you time to work through the rest of the list. Patch immediately after, then layer on logging, Fail2Ban, and privilege restrictions.

Hardening is cumulative. No single step makes you invincible, but together they raise the cost of compromise high enough that most attackers move on to softer targets.