security2024-05-01·15 min·306/348

Linux Server Security Hardening Checklist

A comprehensive checklist for hardening Linux server security, covering SSH, firewall, updates, auditing, and best practices.

Introduction

A fresh Linux server is not a secure server. Default configurations prioritize usability over security, leaving numerous attack vectors open. This post provides a systematic checklist for hardening a Linux server, covering everything from SSH configuration to audit logging. Follow these steps when provisioning any new server.

Environment

The checklist applies to Ubuntu 22.04 LTS and Debian 12, but the principles are universal across Linux distributions. Each item includes the command or configuration needed.

lsb_release -a
# Distributor ID: Ubuntu
# Description:    Ubuntu 22.04.3 LTS
# Release:        22.04

Problem

An unhardened Linux server is vulnerable to:

  • Brute-force SSH attacks
  • Unauthorized access
  • Privilege escalation
  • Data exfiltration
  • Malware installation
  • Supply chain attacks

A checklist ensures consistent security posture across all servers.

Solution

1. System Updates

# Update all packages immediately
sudo apt-get update && sudo apt-get upgrade -y

# Enable automatic security updates
sudo apt-get install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

# Configure automatic updates
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
# Unattended-Upgrade::Allowed-Origins {
#     "${distro_id}:${distro_codename}-security";
# };

2. Create a Non-Root User

# Add a new user
sudo adduser deploy

# Add to sudo group
sudo usermod -aG sudo deploy

# Set up SSH key for the new user
sudo mkdir -p /home/deploy/.ssh
sudo cp /root/.ssh/authorized_keys /home/deploy/.ssh/
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys

3. SSH Hardening

# /etc/ssh/sshd_config
Port 2222
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers deploy
Protocol 2
sudo systemctl restart sshd

4. Firewall Configuration

# Install and configure UFW
sudo apt-get install ufw

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

# Allow SSH
sudo ufw allow 2222/tcp

# Allow HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable firewall
sudo ufw enable
sudo ufw status verbose

5. Fail2Ban

# Install fail2ban
sudo apt-get install fail2ban

# Configure
sudo nano /etc/fail2ban/jail.local
# [DEFAULT]
# bantime = 3600
# findtime = 600
# maxretry = 3
#
# [sshd]
# enabled = true
# port = 2222

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

6. File Permission Hardening

# Restrict cron access
sudo chmod 600 /etc/crontab
sudo chmod 700 /etc/cron.d
sudo chmod 700 /etc/cron.daily
sudo chmod 700 /etc/cron.hourly
sudo chmod 700 /etc/cron.monthly
sudo chmod 700 /etc/cron.weekly

# Restrict /tmp
sudo mount -o remount,noexec,nosuid /tmp

# Remove world-writable files
sudo find / -xdev -type f -perm -0002 -exec chmod o-w {} \;

# Set proper ownership
sudo chown root:root /etc/passwd
sudo chown root:root /etc/shadow
sudo chown root:root /etc/group
sudo chown root:root /etc/gshadow

7. Kernel Hardening

# /etc/sysctl.d/99-security.conf
# Disable IP forwarding (unless routing)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

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

# Enable SYN flood protection
net.ipv4.tcp_syncookies = 1

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

# Log Martian 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

8. Audit Logging

# Install auditd
sudo apt-get install auditd

# Configure rules
sudo nano /etc/audit/rules.d/hardening.rules
# Monitor login attempts
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock -p wa -k logins

# Monitor file permission changes
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod

# Monitor privilege escalation
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope

sudo systemctl enable auditd
sudo systemctl start auditd

9. Automatic Security Updates

# Configure unattended-upgrades for security only
sudo nano /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";

10. Disable Unnecessary Services

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

# Disable services you do not need
sudo systemctl disable avahi-daemon
sudo systemctl disable cups
sudo systemctl disable bluetooth

11. Set Password Policies

# Install libpam-pwquality
sudo apt-get install libpam-pwquality

# Configure password quality
sudo nano /etc/security/pwquality.conf
# minlen = 12
# dcredit = -1
# ucredit = -1
# lcredit = -1
# ocredit = -1

# Set account lockout
sudo nano /etc/pam.d/common-auth
# Add: auth required pam_tally2.so deny=5 onerr=fail unlock_time=900

12. Enable AppArmor/SELinux

# Check AppArmor status
sudo aa-status

# Enable AppArmor profiles
sudo aa-enforce /etc/apparmor.d/*

# For SELinux (RHEL/CentOS)
sudo setenforce 1

13. Set Up Log Monitoring

# Install logwatch
sudo apt-get install logwatch

# Configure
sudo nano /etc/logwatch/conf/logwatch.conf
# Output = file
# Filename = /var/log/logwatch.log
# Detail = Low
# Range = yesterday

# Add to cron
echo "0 4 * * * /usr/sbin/logwatch" | sudo tee /etc/cron.d/logwatch

14. Verify Configuration

# Run a security scan
sudo apt-get install lynis
sudo lynis audit system

# Check listening ports
ss -tlnp

# Check open files
lsof -i -P -n

# Review recent logins
last -n 20
lastb -n 20

Lessons Learned

Security hardening is not a one-time task but an ongoing process. Start with the checklist, then regularly audit your servers with tools like Lynis. Monitor logs for suspicious activity and keep systems updated. The cost of prevention is always less than the cost of recovery. And remember: security is a layer, not a product.


This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.