Skip to main content

Linux Hardening - Best Practices

This guide presents best practices for securing a Linux server.

1. User Management

Create a Non-root User

# Create a user
adduser admin

# Give sudo privileges
usermod -aG sudo admin

Disable Root Login

Once the admin user is configured:

sudo nano /etc/ssh/sshd_config
PermitRootLogin no
sudo systemctl restart sshd

Password Policy

Install and configure libpam-pwquality:

sudo apt install libpam-pwquality
sudo nano /etc/security/pwquality.conf
# Minimum length
minlen = 12
# At least 1 uppercase
ucredit = -1
# At least 1 lowercase
lcredit = -1
# At least 1 digit
dcredit = -1
# At least 1 special character
ocredit = -1
# No character repetition
maxrepeat = 3

Password Expiration

# Force change every 90 days
sudo chage -M 90 admin

# View user policy
sudo chage -l admin

2. Secure SSH Configuration

Recommended /etc/ssh/sshd_config file:

# Non-standard port
Port 2222

# Protocol 2 only (default on modern systems)
Protocol 2

# Disable root login
PermitRootLogin no

# Key-only authentication
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no

# Disable unused methods
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no

# Limit allowed users
AllowUsers admin deployer

# Timeout and limits
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
MaxSessions 3
LoginGraceTime 60

# Disable unnecessary features
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no

# Logging
LogLevel VERBOSE

# Connection banner
Banner /etc/ssh/banner

Create a warning banner:

sudo nano /etc/ssh/banner
*******************************************************************
* ACCESS RESTRICTED TO AUTHORIZED PERSONNEL ONLY *
* All activity is logged and monitored. *
*******************************************************************

3. UFW Firewall

Basic Configuration

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

# SSH (your port)
sudo ufw allow 2222/tcp

# HTTP/HTTPS (if web server)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable
sudo ufw enable

Limit Connections (rate limiting)

# Limit SSH: 6 connections in 30 seconds
sudo ufw limit 2222/tcp

Allow Only Certain IPs

# SSH from a specific IP
sudo ufw allow from 203.0.113.50 to any port 2222

# Block an IP
sudo ufw deny from 192.168.1.100

4. Automatic Updates

Enable Automatic Security Updates

sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Advanced Configuration

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};

// Automatically reboot if necessary
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

// Email notification
Unattended-Upgrade::Mail "admin@yourdomain.com";
Unattended-Upgrade::MailReport "on-change";

5. Kernel Security (sysctl)

sudo nano /etc/sysctl.d/99-security.conf
# SYN flood protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2

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

# Ignore broadcast pings
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Ignore bogus ICMP responses
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Enable spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Disable IP routing (unless router)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

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

# Buffer overflow protection
kernel.randomize_va_space = 2

# Restrict kernel log access
kernel.dmesg_restrict = 1

# Restrict ptrace (debugging)
kernel.yama.ptrace_scope = 1

Apply:

sudo sysctl -p /etc/sysctl.d/99-security.conf

6. File Permissions

Sensitive Files

# Restrictive permissions on /etc/shadow
sudo chmod 640 /etc/shadow

# SSH key permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/id_*.pub

# Sudoers file
sudo chmod 440 /etc/sudoers

Find Risky Files

# SUID files (run with owner privileges)
sudo find / -perm -4000 -type f 2>/dev/null

# SGID files
sudo find / -perm -2000 -type f 2>/dev/null

# World-writable files
sudo find / -perm -0002 -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null

# Files without owner
sudo find / -nouser -o -nogroup 2>/dev/null

Remove Unnecessary SUID

# Example: remove SUID from /usr/bin/chsh if not used
sudo chmod u-s /usr/bin/chsh

7. Services and Ports

Disable Unnecessary Services

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

# Disable a service
sudo systemctl disable cups
sudo systemctl stop cups

# Services often unnecessary on a server
sudo systemctl disable bluetooth
sudo systemctl disable avahi-daemon

Check Listening Ports

sudo ss -tlnp

Only necessary ports should be open.

8. Logs and Auditing

Configure Log Rotation

sudo nano /etc/logrotate.d/custom
/var/log/auth.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
}

Centralize Logs (rsyslog)

sudo nano /etc/rsyslog.d/50-auth.conf
auth,authpriv.*    /var/log/auth.log

Install auditd

sudo apt install auditd

# Audit rules for sensitive files
sudo auditctl -w /etc/passwd -p wa -k passwd_changes
sudo auditctl -w /etc/shadow -p wa -k shadow_changes
sudo auditctl -w /etc/sudoers -p wa -k sudoers_changes

# View audit logs
sudo ausearch -k passwd_changes

9. Additional Security Tools

Fail2ban

sudo apt install fail2ban
sudo systemctl enable fail2ban

See the Advanced Fail2ban Configuration guide.

RKHunter (rootkit detection)

sudo apt install rkhunter

# Update database
sudo rkhunter --update

# Scan system
sudo rkhunter --check

Lynis (security audit)

sudo apt install lynis

# Full audit
sudo lynis audit system

ClamAV (antivirus)

sudo apt install clamav clamav-daemon

# Update signatures
sudo freshclam

# Scan
sudo clamscan -r /home

10. Final Checklist

System

  • Automatic updates enabled
  • Unnecessary services disabled
  • Sysctl secured

Access

  • Non-root user created
  • Root SSH login disabled
  • SSH key authentication
  • Fail2ban configured

Network

  • UFW firewall active
  • Only necessary ports open
  • Rate limiting on SSH

Monitoring

  • Logs configured and rotating
  • Auditd installed (optional)
  • Alerts configured
Important

Always test your changes on a test environment before applying them in production. Keep an SSH session open when modifying SSH configuration.

Tip

After securing your server, use Lynis to verify you haven't missed anything.