🎁 New User? Get 20% off your first purchase with code NEWUSER20 Register Now →
Menu

Categories

Linux Security Hardening 2026: The Complete Server Protection Guide

Linux Security Hardening 2026: The Complete Server Protection Guide

Every 39 seconds, a cyberattack occurs. In 2025, the average cost of a data breach reached $4.88 million (IBM). Linux servers power 96% of the world's top web servers, making them the primary target for attackers worldwide.

The good news? A properly hardened Linux server is one of the most secure computing platforms available. The bad news? Most Linux servers are deployed with default configurations that leave them vulnerable.

Reality Check: If your server still allows root SSH login, runs with SELinux disabled, has no firewall rules beyond defaults, and hasn't been audited in months — this article is for you. We'll walk through every layer of Linux security, from kernel hardening to intrusion detection, with copy-paste commands for RHEL, Ubuntu, and Debian.


The 7 Layers of Linux Server Security

Layer Area Key Components Priority
1Physical & BootBIOS/UEFI password, GRUB password, boot partition encryptionCritical
2Network & Firewallfirewalld, nftables, TCP wrappers, port managementCritical
3AuthenticationSSH keys, MFA, PAM, password policies, sudo configurationCritical
4Access ControlSELinux/AppArmor, file permissions, ACLs, capabilitiesHigh
5Kernel & Systemsysctl hardening, kernel modules, ASLR, core dumpsHigh
6Monitoring & Auditauditd, rsyslog, fail2ban, AIDE, log managementHigh
7MaintenancePatching, vulnerability scanning, backup verification, incident responseOngoing

Layer 1: SSH Hardening — The First Line of Defense

SSH is the primary attack surface for most Linux servers. Bots constantly scan the internet for SSH servers with weak configurations. Here's how to lock it down properly:

Essential SSH Configuration

# /etc/ssh/sshd_config — Production-grade SSH hardening

# === Authentication ===
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
MaxSessions 3
LoginGraceTime 30

# === Protocol & Encryption ===
Protocol 2
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512

# === Access Control ===
AllowUsers deployer admin
AllowGroups sshusers
DenyUsers root
PermitEmptyPasswords no

# === Session Security ===
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no

# === Logging ===
LogLevel VERBOSE
SyslogFacility AUTH

# === Port (optional: change from default) ===
Port 2222

SSH Key Setup (Ed25519)

# Generate modern Ed25519 key (strongest, smallest)
ssh-keygen -t ed25519 -C "admin@company.com" -f ~/.ssh/id_ed25519

# Copy to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 deployer@your-server.com

# Set correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys

# Restart SSH service
sudo systemctl restart sshd

# Verify key-only authentication works BEFORE disconnecting!
ssh -p 2222 deployer@your-server.com

Warning: ALWAYS verify you can login with your SSH key in a separate terminal session BEFORE disabling password authentication. Locking yourself out of a remote server is one of the most common and costly mistakes in system administration.


Layer 2: Firewall Configuration

firewalld (RHEL/CentOS/Fedora/AlmaLinux)

# Check status
sudo systemctl enable --now firewalld
sudo firewall-cmd --state

# Set default zone to drop (deny all incoming)
sudo firewall-cmd --set-default-zone=drop

# Allow only essential services
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# If SSH is on custom port
sudo firewall-cmd --permanent --add-port=2222/tcp

# Remove unnecessary services
sudo firewall-cmd --permanent --remove-service=cockpit
sudo firewall-cmd --permanent --remove-service=dhcpv6-client

# Rate limit SSH connections (max 10 per minute)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="ssh" accept limit value="10/m"'

# Block specific countries (optional, requires ipset)
sudo firewall-cmd --permanent --new-ipset=blocked_countries --type=hash:net
# Add IP ranges...

# Apply changes
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-all

nftables (Modern Replacement for iptables)

#!/usr/sbin/nft -f
# /etc/nftables.conf — Production web server ruleset

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        
        # Accept established connections
        ct state established,related accept
        
        # Accept loopback
        iif lo accept
        
        # Drop invalid
        ct state invalid drop
        
        # ICMP (allow ping, limit rate)
        ip protocol icmp icmp type echo-request limit rate 5/second accept
        
        # SSH (rate limited)
        tcp dport 2222 ct state new limit rate 10/minute accept
        
        # HTTP/HTTPS
        tcp dport { 80, 443 } accept
        
        # Log dropped packets
        log prefix "[nftables-drop] " flags all counter drop
    }
    
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
    
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Firewall Comparison

Feature firewalld nftables iptables (legacy) ufw
Best ForRHEL/CentOSAdvanced usersLegacy systemsUbuntu/Debian
Zones/ProfilesYesTablesNoProfiles
Runtime ChangesYes (no restart)Atomic updatesManual reloadReload needed
Rich RulesYesNativeComplex syntaxLimited
RHCSA ExamRequiredNot testedNot testedNot tested
Learning CurveModerateSteepSteepEasy

Layer 3: SELinux — Mandatory Access Control

SELinux is the single most important security feature in RHEL-based distributions — and the most frequently disabled one. Disabling SELinux is the #1 security mistake Linux administrators make.

# Check SELinux status
getenforce           # Current mode
sestatus             # Detailed status

# Set to enforcing (permanent)
sudo sed -i 's/SELINUX=permissive/SELINUX=enforcing/' /etc/selinux/config
sudo sed -i 's/SELINUX=disabled/SELINUX=enforcing/' /etc/selinux/config

# Common: Allow Apache to serve from non-standard directory
sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
sudo restorecon -Rv /data/www

# Common: Allow Apache to connect to database
sudo setsebool -P httpd_can_network_connect_db on

# Common: Allow nginx to connect to upstream
sudo setsebool -P httpd_can_network_connect on

# Troubleshoot AVC denials
sudo ausearch -m AVC -ts recent
sudo audit2why < /var/log/audit/audit.log
sudo sealert -a /var/log/audit/audit.log    # Detailed analysis

# Create custom policy from denials
sudo ausearch -m AVC -ts recent | audit2allow -M mypolicy
sudo semodule -i mypolicy.pp

SELinux Quick Reference

Task Command
Check modegetenforce
Temporary permissivesudo setenforce 0 (reverts on reboot)
View file contextls -Z /var/www/html/
Change file contextsudo chcon -t httpd_sys_content_t file.html
Restore default contextsudo restorecon -Rv /path
List booleansgetsebool -a | grep httpd
Set boolean permanentlysudo setsebool -P httpd_can_sendmail on
View denialssudo ausearch -m AVC -ts today
Port labelingsudo semanage port -a -t http_port_t -p tcp 8080

Layer 4: Kernel Hardening with sysctl

# /etc/sysctl.d/99-security.conf — Kernel security parameters

# === Network Security ===
# Disable IP forwarding (unless router/VPN)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# Prevent source routing attacks
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

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

# Enable SYN flood protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2

# Ignore ICMP broadcasts (smurf attack prevention)
net.ipv4.icmp_echo_ignore_broadcasts = 1

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

# Enable reverse path filtering (anti-spoofing)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# === Memory Security ===
# Restrict dmesg access
kernel.dmesg_restrict = 1

# Restrict kernel pointers
kernel.kptr_restrict = 2

# Enable ASLR (Address Space Layout Randomization)
kernel.randomize_va_space = 2

# Disable core dumps for SUID programs
fs.suid_dumpable = 0

# === Process Security ===
# Restrict ptrace scope (prevent process snooping)
kernel.yama.ptrace_scope = 1

# Disable SysRq key (prevent kernel-level commands from keyboard)
kernel.sysrq = 0
# Apply without reboot
sudo sysctl --system

# Verify specific setting
sysctl net.ipv4.ip_forward
sysctl kernel.randomize_va_space

Layer 5: User & Authentication Security

Password Policy Configuration

# /etc/login.defs — Global password settings
PASS_MAX_DAYS   90       # Force password change every 90 days
PASS_MIN_DAYS   7        # Minimum 7 days between changes
PASS_MIN_LEN    14       # Minimum 14 characters
PASS_WARN_AGE   14       # Warn 14 days before expiry

# /etc/security/pwquality.conf — Password complexity
minlen = 14
dcredit = -1             # At least 1 digit
ucredit = -1             # At least 1 uppercase
lcredit = -1             # At least 1 lowercase
ocredit = -1             # At least 1 special character
maxrepeat = 3            # Max 3 consecutive identical characters
maxclassrepeat = 4       # Max 4 consecutive chars from same class
reject_username          # Cannot contain username
enforce_for_root         # Apply even to root

Sudo Hardening

# Use visudo for safe editing
sudo visudo

# Best practices
Defaults    timestamp_timeout=5        # Re-auth after 5 min idle
Defaults    passwd_tries=3             # Max 3 password attempts
Defaults    logfile="/var/log/sudo.log" # Log all sudo commands
Defaults    log_input,log_output       # Log stdin/stdout
Defaults    requiretty                 # Require terminal
Defaults    use_pty                    # Use pseudo-terminal

# Principle of least privilege — specific commands only
deployer ALL=(ALL) /usr/bin/systemctl restart nginx, \
                   /usr/bin/systemctl restart php-fpm, \
                   /usr/bin/journalctl -u nginx, \
                   /usr/bin/journalctl -u php-fpm

Account Auditing

# Find accounts with empty passwords (CRITICAL)
sudo awk -F: '($2 == "") {print $1}' /etc/shadow

# Find accounts with UID 0 (root-equivalent)
awk -F: '($3 == "0") {print}' /etc/passwd

# List users with login shells
grep -v 'nologin\|false' /etc/passwd | cut -d: -f1

# Lock unused accounts
sudo usermod -L unused_account
sudo usermod -s /sbin/nologin unused_account

# Set account expiration
sudo chage -E 2026-12-31 contractor_user

# Check password aging for all users
sudo chage -l username

Layer 6: Intrusion Detection & Monitoring

fail2ban — Automated Attack Prevention

# Install
sudo dnf install fail2ban     # RHEL/CentOS
sudo apt install fail2ban     # Debian/Ubuntu

# /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 3600       # 1 hour ban
findtime = 600        # Within 10 minutes
maxretry = 3          # After 3 failures
action = %(action_mwl)s    # Ban + send email with whois + logs

[sshd]
enabled  = true
port     = 2222
logpath  = /var/log/auth.log
maxretry = 3
bantime  = 86400      # 24 hours for SSH

[nginx-http-auth]
enabled  = true
logpath  = /var/log/nginx/error.log
maxretry = 5

[nginx-botsearch]
enabled  = true
logpath  = /var/log/nginx/access.log
maxretry = 2

# Enable and start
sudo systemctl enable --now fail2ban

# Check status
sudo fail2ban-client status
sudo fail2ban-client status sshd

# Unban an IP
sudo fail2ban-client set sshd unbanip 192.168.1.100

auditd — Linux Audit Framework

# /etc/audit/rules.d/security.rules

# Monitor password file changes
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity

# Monitor SSH configuration changes
-w /etc/ssh/sshd_config -p wa -k sshd_config

# Monitor sudo configuration
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers

# Monitor cron changes
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron

# Monitor login/logout
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock/ -p wa -k logins

# Monitor kernel module loading
-w /sbin/insmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-w /sbin/rmmod -p x -k modules

# Monitor time changes
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change

# Search audit logs
sudo ausearch -k identity -ts today
sudo aureport --auth --summary

AIDE — File Integrity Monitoring

# Install AIDE
sudo dnf install aide           # RHEL
sudo apt install aide aide-common  # Debian/Ubuntu

# Initialize database
sudo aide --init
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

# Check for changes
sudo aide --check

# Update database after legitimate changes
sudo aide --update

# Automate daily checks via cron
echo "0 5 * * * root /usr/sbin/aide --check | mail -s 'AIDE Report' admin@company.com" | sudo tee /etc/cron.d/aide-check

Layer 7: Automated Security Maintenance

Automatic Security Updates

# RHEL/CentOS — dnf-automatic
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic-install.timer

# /etc/dnf/automatic.conf
[commands]
apply_updates = yes
upgrade_type = security    # Only security updates

[emitters]
emit_via = email
email_from = server@company.com
email_to = admin@company.com

# Ubuntu/Debian — unattended-upgrades
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Rootkit Detection

# Install rootkit scanners
sudo dnf install rkhunter chkrootkit    # RHEL
sudo apt install rkhunter chkrootkit    # Debian/Ubuntu

# Run rkhunter
sudo rkhunter --update
sudo rkhunter --check --skip-keypress

# Run chkrootkit
sudo chkrootkit

# Schedule weekly scan
echo "0 3 * * 0 root /usr/bin/rkhunter --check --skip-keypress --report-warnings-only | mail -s 'rkhunter Weekly' admin@company.com" | sudo tee /etc/cron.d/rkhunter-weekly

Post-Install Hardening Checklist

Use this checklist after every new server deployment:

Task Command / Action Priority
Update all packagessudo dnf update -yP0
Create admin useruseradd -m -G wheel deployerP0
Setup SSH keysssh-copy-id deployer@serverP0
Harden SSH configDisable root login, passwordsP0
Configure firewallDrop default, allow SSH/HTTP/HTTPSP0
Enable SELinuxsetenforce 1 + configP0
Apply sysctl hardeningNetwork + kernel paramsP1
Install fail2banConfigure SSH + web jailsP1
Configure auditdMonitor critical files & loginsP1
Setup auto updatesdnf-automatic or unattended-upgradesP1
Remove unnecessary packagesdnf remove telnet rshP2
Disable unused servicessystemctl disable bluetooth cupsP2
Setup AIDEFile integrity monitoringP2
Install rootkit scannerrkhunter + weekly cronP2
Set GRUB passwordgrub2-setpasswordP2
Configure log rotation/etc/logrotate.d/P2
Backup strategyAutomated + verified + off-siteP1
Document everythingConfig changes, access, contactsP1

CIS Benchmarks: Industry Standard Hardening

The Center for Internet Security (CIS) Benchmarks are the gold standard for Linux server hardening. They provide detailed, scored configuration recommendations:

CIS Level Description Best For
Level 1Essential security settings with minimal impact on functionalityAll production servers
Level 2Defense-in-depth settings that may reduce functionalityHigh-security environments
STIGDoD Security Technical Implementation GuidesGovernment, military, defense
# Automated CIS compliance scanning with OpenSCAP
sudo dnf install openscap-scanner scap-security-guide

# List available profiles
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

# Run CIS Level 1 scan
sudo oscap xccdf eval \
    --profile xccdf_org.ssgproject.content_profile_cis \
    --results /tmp/cis-results.xml \
    --report /tmp/cis-report.html \
    /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

# View HTML report
firefox /tmp/cis-report.html

Common Linux Security Mistakes

# Mistake Why It's Dangerous Fix
1Disabling SELinuxRemoves mandatory access control entirelyLearn to fix AVC denials instead
2Root SSH login allowedDirect target for brute-force attacksPermitRootLogin no
3Password auth for SSHPasswords are brute-forceableUse SSH keys exclusively
4chmod 777World-writable = anyone can modifyUse 755 dirs, 644 files, ACLs
5No firewall activeAll ports exposed to internetDrop default + whitelist services
6Running as rootAny exploit gets full system accessDedicated service users + sudo
7No log monitoringAttacks go unnoticed for monthsauditd + centralized logging
8Delayed patchingKnown CVEs exploited within hoursAuto security updates enabled
9No backup verificationBackup may be corrupted or incompleteMonthly restore test
10Secrets in code/envLeaked via git, logs, or env dumpsVault, encrypted configs, rotate keys

Security Salary Impact

Security-skilled Linux professionals earn significantly more than their peers:

Role Without Security Skills With Security Skills Premium
Linux Sysadmin$65,000 - $85,000$85,000 - $120,000+30-40%
DevOps Engineer$90,000 - $130,000$120,000 - $170,000+25-35%
Security Engineer$110,000 - $180,000
SOC Analyst$70,000 - $120,000
EU Equivalent€45,000 - €65,000€65,000 - €110,000+35-50%


Further Reading on Dargslan


Final Thoughts

Linux security is not a one-time task — it's a continuous process. The hardening measures in this guide will dramatically reduce your attack surface, but security is never "done." New vulnerabilities are discovered daily, and attackers constantly evolve their techniques.

The three pillars of Linux server security are:
1. Prevention — Hardening, firewalls, SELinux, SSH keys, minimal packages
2. Detection — auditd, fail2ban, AIDE, rootkit scanners, log analysis
3. Response — Incident response plan, backups, documentation, communication

Start with the P0 items in the checklist above, then work through P1 and P2 over the following weeks. A server hardened with even the basics from this guide is already more secure than 90% of servers on the internet.

Master Linux Security

From fundamentals to advanced hardening — protect your infrastructure:

Get Linux Security Hardening →
Share this article:

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.