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.