Skip to main content
Back to Category

Server Security Hardening: Comprehensive Checklist

Linux server security hardening guide: SSH hardening, disabling root login, Fail2Ban, automatic updates, firewall rules, unnecessary services, and file permissions checklist.

Read time: 16 min Server Management
securityhardeningsshfail2banfirewalllinuxchecklistufw
Author
REXE Teknoloji Network & Security Team
Editor
REXE Teknoloji Technical Editorial
First published
Last updated

Server Security Hardening: Comprehensive Checklist

When you set up a new Linux server, the default configuration is not security-optimized. Server hardening involves systematic configuration changes to reduce the attack surface and close security vulnerabilities. This guide provides a comprehensive security checklist for your REXE servers.

Why Server Hardening?

Default Linux installations may have:

  • Unnecessary services running
  • SSH open to password authentication
  • Root login enabled
  • Minimal firewall rules
  • Automatic updates disabled

Don't close your existing SSH connection while hardening. After each step, test the connection from a new terminal.

✅ Checklist 1: System Updates

hljs bash
# Update the system
sudo apt update && sudo apt upgrade -y

# Install automatic security updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades

# Check configuration
cat /etc/apt/apt.conf.d/50unattended-upgrades
# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";

✅ Checklist 2: SSH Hardening

hljs bash
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# SSH Security Settings

# Disable root login
PermitRootLogin no

# Disable password authentication (after SSH key is set up)
PasswordAuthentication no

# Disallow empty passwords
PermitEmptyPasswords no

# Disable X11 forwarding
X11Forwarding no

# Maximum login attempts
MaxAuthTries 3

# Maximum concurrent sessions
MaxSessions 5

# Login timeout (seconds)
LoginGraceTime 30

# Protocol version
Protocol 2

# Allow specific users only
AllowUsers admin deploy

# Change SSH port (optional)
# Port 2222

# Strong encryption algorithms
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,diffie-hellman-group14-sha256
hljs bash
# Test SSH configuration
sudo sshd -t

# Restart SSH service
sudo systemctl restart sshd

✅ Checklist 3: Firewall Configuration

hljs bash
# Install and configure UFW
sudo apt install ufw -y

# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH first!
sudo ufw allow ssh
# Or for custom port:
# sudo ufw allow 2222/tcp

# Web services
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Allow access from specific IP
sudo ufw allow from 192.168.1.0/24 to any port 3306

# Enable UFW
sudo ufw enable

# Check status
sudo ufw status verbose

Advanced UFW Rules

hljs bash
# Rate limiting for brute force protection
sudo ufw limit ssh

# Block specific IP
sudo ufw deny from 1.2.3.4

# Delete a rule
sudo ufw delete allow 80/tcp

# Show rules numbered
sudo ufw status numbered

# Delete rule by number
sudo ufw delete 3

✅ Checklist 4: Fail2Ban Setup

Fail2Ban monitors failed login attempts and automatically blocks repeated attacks.

hljs bash
# Install Fail2Ban
sudo apt install fail2ban -y

# Create local configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
hljs ini
# /etc/fail2ban/jail.local

[DEFAULT]
# Ban duration (seconds)
bantime = 3600

# Detection window (seconds)
findtime = 600

# Maximum failed attempts
maxretry = 5

# Email notification
destemail = admin@example.com
sender = fail2ban@example.com
mta = sendmail

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400

[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log

[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
hljs bash
# Start Fail2Ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

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

# View banned IPs
sudo fail2ban-client status sshd | grep "Banned IP"

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

✅ Checklist 5: Disable Unnecessary Services

hljs bash
# List running services
sudo systemctl list-units --type=service --state=running

# Disable unnecessary services
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now cups
sudo systemctl disable --now bluetooth
sudo systemctl disable --now rpcbind

# Check open ports
sudo ss -tlnp
sudo netstat -tlnp

# Find which service uses which port
sudo lsof -i :80

✅ Checklist 6: File System Security

hljs bash
# Find SUID/SGID files
find / -perm /4000 -type f 2>/dev/null
find / -perm /2000 -type f 2>/dev/null

# Find world-writable files
find / -perm -0002 -type f 2>/dev/null

# Find files with no owner
find / -nouser -o -nogroup 2>/dev/null

# Secure /tmp mount
# Add to /etc/fstab:
# tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev 0 0

# Make critical files immutable
sudo chattr +i /etc/passwd
sudo chattr +i /etc/shadow
sudo chattr +i /etc/gshadow

# Remove immutable attribute
sudo chattr -i /etc/passwd

✅ Checklist 7: Kernel Security Parameters

hljs bash
# Edit sysctl configuration
sudo nano /etc/sysctl.d/99-security.conf
# Network security
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.tcp_syncookies = 1

# IPv6 redirects
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

# Memory protection
kernel.randomize_va_space = 2
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2

# Disable core dumps
fs.suid_dumpable = 0
hljs bash
# Apply changes
sudo sysctl -p /etc/sysctl.d/99-security.conf

✅ Checklist 8: Log Monitoring

hljs bash
# Important log files
tail -f /var/log/auth.log      # Authentication
tail -f /var/log/syslog        # System logs
tail -f /var/log/fail2ban.log  # Fail2Ban
tail -f /var/log/ufw.log       # Firewall

# Count failed SSH logins
grep "Failed password" /var/log/auth.log | wc -l

# Recent successful logins
grep "Accepted" /var/log/auth.log | tail -20

# Install Logwatch (daily summary)
sudo apt install logwatch -y
sudo logwatch --output stdout --format text --range today

✅ Checklist 9: User Account Security

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

# Configure password policy
sudo apt install libpam-pwquality -y
sudo nano /etc/security/pwquality.conf
# Password quality requirements
minlen = 12
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
minclass = 3

✅ Checklist 10: Security Scanning

hljs bash
# Security audit with Lynis
sudo apt install lynis -y
sudo lynis audit system

# Rootkit scan with rkhunter
sudo apt install rkhunter -y
sudo rkhunter --update
sudo rkhunter --check

# Virus scan with ClamAV
sudo apt install clamav -y
sudo freshclam
sudo clamscan -r /home

Lynis security score should be 70+. A lower score indicates areas needing improvement. Run it regularly (monthly).

Quick Reference Checklist

  • System updates applied
  • Automatic security updates enabled
  • SSH root login disabled
  • SSH password login disabled (key installed)
  • SSH MaxAuthTries set to 3
  • UFW firewall enabled and configured
  • Fail2Ban installed and running
  • Unnecessary services disabled
  • Kernel security parameters configured
  • Log monitoring configured
  • Strong password policy enforced
  • Lynis security audit completed

Conclusion

Server hardening is not a one-time task but an ongoing process. Apply this checklist to new server setups and conduct regular security audits. These steps will significantly improve the security of your REXE servers.

Frequently Asked Questions

Does changing the SSH port improve security?

Changing from the default port 22 reduces automated scanning attacks (security through obscurity). However, SSH key-based authentication and Fail2Ban are more effective for real security. Port change can be used as an additional layer.

Can Fail2Ban and UFW be used together?

Yes, Fail2Ban uses iptables by default but can work with UFW. Set 'banaction = ufw' in /etc/fail2ban/jail.local to have Fail2Ban create UFW rules.

What should I do before disabling root login?

First create a regular user with sudo privileges and set up their SSH key. Test the connection with the new user. Then set 'PermitRootLogin no' in /etc/ssh/sshd_config. Test from a new terminal before disconnecting.

Can automatic updates break the server?

Security updates are generally safe. However, major version upgrades can cause issues. Configure unattended-upgrades for security updates only and set 'Automatic-Reboot false'. For critical systems, test updates in a staging environment first.

How do I improve the Lynis security score?

The Lynis report contains improvement suggestions. Focus on the 'Suggestion' and 'Warning' sections. Common improvements: kernel parameters, PAM configuration, file permissions, and disabling unnecessary services. Re-run after each change to track progress.

Related Articles

Network TrafficInbound GbpsOutbound Gbps