In 2026, Linux servers power over 96% of the world's top web servers, making them the primary target for cybercriminals. Whether you're managing a single VPS or an enterprise fleet, security hardening isn't optional — it's the difference between a secure system and a data breach.
This guide walks you through 10 essential hardening steps that every Linux administrator should implement, with practical commands you can run today.
1. Secure SSH Access
SSH is the front door to your server. Lock it down properly:
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# Essential changes:
Port 2222 # Change default port
PermitRootLogin no # Never allow root login
PasswordAuthentication no # Use SSH keys only
MaxAuthTries 3 # Limit login attempts
ClientAliveInterval 300 # Timeout idle sessions
AllowUsers yourusername # Whitelist specific users
Protocol 2 # Force SSH protocol 2
# Restart SSH service
sudo systemctl restart sshd
Pro tip: Always keep a second SSH session open when modifying SSH config. If you lock yourself out, you'll still have access to fix it.
2. Configure a Firewall
A properly configured firewall is your first line of defense. Use firewalld or ufw depending on your distribution:
Using UFW (Ubuntu/Debian)
# Enable UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow only necessary services
sudo ufw allow 2222/tcp comment "SSH"
sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow 443/tcp comment "HTTPS"
# Enable the firewall
sudo ufw enable
# Check status
sudo ufw status verbose
Using firewalld (RHEL/AlmaLinux)
# Start and enable firewalld
sudo systemctl enable --now firewalld
# Add services
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=2222/tcp
# Remove SSH default port if changed
sudo firewall-cmd --permanent --remove-service=ssh
# Reload
sudo firewall-cmd --reload
For a comprehensive guide on firewall configuration across all major Linux distributions, check out our Firewall Configuration: The Complete Guide.
3. Implement Automatic Security Updates
Unpatched systems are the #1 cause of successful attacks. Set up automatic security patches:
# Ubuntu/Debian - Install unattended-upgrades
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# Verify it's running
sudo systemctl status unattended-upgrades
# RHEL/AlmaLinux - Use dnf-automatic
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic-install.timer
4. Harden Kernel Parameters
The Linux kernel has many security-related parameters that should be tuned:
# Add to /etc/sysctl.d/99-security.conf
# Prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable source routing
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
# Enable SYN flood protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
# Log suspicious packets
net.ipv4.conf.all.log_martians = 1
# Disable IPv6 if not needed
net.ipv6.conf.all.disable_ipv6 = 1
# Apply changes
sudo sysctl --system
5. Set Up Intrusion Detection with Fail2Ban
Fail2Ban monitors log files and automatically bans IPs showing malicious behavior:
# Install Fail2Ban
sudo apt install fail2ban # Debian/Ubuntu
sudo dnf install fail2ban # RHEL/AlmaLinux
# Create local configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit jail.local
sudo nano /etc/fail2ban/jail.local
# Key settings in jail.local
[DEFAULT]
bantime = 3600 # Ban for 1 hour
findtime = 600 # Within 10 minutes
maxretry = 3 # After 3 failed attempts
banaction = iptables-multiport
[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
# Start and enable
sudo systemctl enable --now fail2ban
# Check status
sudo fail2ban-client status
sudo fail2ban-client status sshd
6. Implement Mandatory Access Control
Go beyond standard Linux permissions with SELinux or AppArmor:
# Check SELinux status (RHEL/AlmaLinux)
sudo sestatus
# Ensure SELinux is enforcing
sudo setenforce 1
# Make permanent
sudo sed -i 's/SELINUX=permissive/SELINUX=enforcing/' /etc/selinux/config
# View SELinux denials
sudo ausearch -m avc -ts recent
For a thorough understanding of both SELinux and AppArmor, including how to write custom policies, see our SELinux & AppArmor Guide.
7. Audit System Activity
The Linux Audit Framework provides detailed logging of system events:
# Install auditd
sudo apt install auditd # Debian/Ubuntu
sudo dnf install audit # RHEL/AlmaLinux
# Key audit rules (/etc/audit/rules.d/security.rules)
# Monitor password file changes
-w /etc/passwd -p wa -k identity_changes
-w /etc/shadow -p wa -k identity_changes
# Monitor SSH configuration
-w /etc/ssh/sshd_config -p wa -k sshd_config
# Monitor sudo usage
-w /etc/sudoers -p wa -k sudoers_changes
-w /var/log/auth.log -p r -k auth_log
# Monitor cron changes
-w /etc/crontab -p wa -k cron_changes
-w /var/spool/cron -p wa -k cron_changes
# Load new rules
sudo augenrules --load
Our Linux Security Auditing eBook provides 25+ ready-to-use audit rule sets for different compliance requirements (PCI-DSS, HIPAA, CIS Benchmarks).
8. Secure User Account Management
# Set password policies
sudo nano /etc/security/pwquality.conf
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
# Set account lockout after failed attempts
# /etc/pam.d/common-auth (Debian) or /etc/pam.d/system-auth (RHEL)
auth required pam_faillock.so preauth deny=5 unlock_time=900
auth required pam_faillock.so authfail deny=5 unlock_time=900
# Set password expiration
sudo chage -M 90 -m 7 -W 14 username
# Find accounts with no password
sudo awk -F: '($2 == "") {print $1}' /etc/shadow
# Find users with UID 0 (root equivalent)
sudo awk -F: '($3 == 0) {print $1}' /etc/passwd
9. Encrypt Data at Rest and in Transit
# Check if LUKS encryption is active
sudo cryptsetup status /dev/mapper/root
# Set up TLS for all web services (Let's Encrypt)
sudo certbot --nginx -d yourdomain.com
# Force TLS 1.2+ in NGINX
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# Enable HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
10. Regular Security Scanning
Automate vulnerability scanning with open-source tools:
# Install and run Lynis security scanner
sudo apt install lynis
sudo lynis audit system
# Check for rootkits
sudo apt install rkhunter
sudo rkhunter --check --skip-keypress
# CIS Benchmark compliance check
sudo apt install oscap-scanner
sudo oscap xccdf eval --profile cis /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml
Security Hardening Checklist
| Step | Priority | Time |
|---|---|---|
| SSH Hardening | Critical | 15 minutes |
| Firewall Configuration | Critical | 20 minutes |
| Automatic Updates | Critical | 10 minutes |
| Kernel Hardening | High | 15 minutes |
| Fail2Ban | High | 15 minutes |
| SELinux/AppArmor | High | 30 minutes |
| Audit Framework | Medium | 20 minutes |
| User Account Security | Medium | 15 minutes |
| Encryption (TLS/LUKS) | Critical | 20 minutes |
| Security Scanning | Medium | 15 minutes |
What's Next?
Security hardening is not a one-time task — it's an ongoing process. Set up regular audits, stay updated on new vulnerabilities, and continuously improve your defenses.
Ready to master Linux security? Explore our complete Linux Security collection for in-depth guides on every topic covered in this article.
Build Your Linux Security Library
Get our top-rated security eBooks and protect your infrastructure with confidence.
Browse Security Books