Key Takeaways

  • Disable root SSH login and use key-based authentication.
  • Keep systems updated and minimize installed packages.
  • Use SELinux or AppArmor for mandatory access control.
  • Implement fail2ban to prevent brute-force attacks.
  • Regular auditing with tools like Lynis identifies vulnerabilities.
  • Centralized logging enables faster incident detection.

1. Introduction to Linux Security

Linux servers power the majority of the internet's infrastructure, from web servers to databases to cloud platforms. While Linux is inherently more secure than many alternatives, a poorly configured Linux server can still be compromised. Security is not a product but a process—continuous attention to hardening, monitoring, and updating is essential.

This guide covers essential security measures for Linux servers, whether you're running Ubuntu, CentOS, RHEL, Debian, or other distributions. The principles apply broadly, though specific commands may vary between distributions.

The Security Mindset

Assume breach. Configure your systems as if attackers already have network access. Implement defense in depth—multiple security layers so that if one fails, others still protect your data.

2. Initial Server Hardening

2.1 System Updates

Keeping your system updated is the single most important security measure. Many breaches exploit known vulnerabilities with available patches.

# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y

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

# CentOS/RHEL
sudo yum update -y
sudo yum install yum-cron
sudo systemctl enable yum-cron

2.2 Minimize Attack Surface

Remove unnecessary packages and disable unused services. Every running service is a potential attack vector.

# List installed packages
dpkg --list | less

# Remove unnecessary packages
sudo apt remove telnet rsh-client

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

# Disable unnecessary services
sudo systemctl disable cups
sudo systemctl stop cups

2.3 Secure Boot Settings

Protect GRUB bootloader with a password to prevent unauthorized boot modifications.

# Generate password hash
grub-mkpasswd-pbkdf2

# Add to /etc/grub.d/40_custom
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512...

# Update GRUB
sudo update-grub

3. SSH Security

SSH is the primary remote access method for Linux servers. Securing it properly is critical.

3.1 Key-Based Authentication

# Generate SSH key pair (on client)
ssh-keygen -t ed25519 -C "[email protected]"

# Copy public key to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server

# Or manually add to ~/.ssh/authorized_keys on server

3.2 SSH Hardening (/etc/ssh/sshd_config)

# Disable root login
PermitRootLogin no

# Disable password authentication
PasswordAuthentication no
PubkeyAuthentication yes

# Use SSH Protocol 2 only
Protocol 2

# Change default port (optional)
Port 2222

# Limit user access
AllowUsers deployuser adminuser

# Connection settings
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2

# Disable unused features
X11Forwarding no
PermitEmptyPasswords no
AllowTcpForwarding no
# Restart SSH service
sudo systemctl restart sshd

# Test before disconnecting!
ssh -p 2222 user@server
Warning

Always test SSH changes in a new session before closing your current connection. Misconfiguration can lock you out of the server permanently.

3.3 Fail2Ban Configuration

Fail2ban monitors log files and bans IPs showing malicious behavior.

# Install fail2ban
sudo apt install fail2ban

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

# Edit /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

# Start fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Check banned IPs
sudo fail2ban-client status sshd

4. User & Permission Management

4.1 User Management

# Create user with no direct login (for services)
sudo useradd -r -s /usr/sbin/nologin serviceuser

# Create admin user
sudo useradd -m -s /bin/bash -G sudo adminuser
sudo passwd adminuser

# Set password expiration
sudo chage -M 90 -m 7 -W 14 adminuser

# View password policies
sudo chage -l adminuser

4.2 Sudo Configuration

# Always use visudo to edit
sudo visudo

# Add user with limited sudo (example)
adminuser ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

# Require password for sudo
Defaults timestamp_timeout=5
Defaults passwd_tries=3

4.3 File Permissions

# Secure sensitive files
sudo chmod 600 /etc/shadow
sudo chmod 600 /etc/gshadow
sudo chmod 644 /etc/passwd
sudo chmod 644 /etc/group

# Set sticky bit on tmp
sudo chmod 1777 /tmp

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

# Find SUID files
find / -perm -4000 -type f 2>/dev/null

5. Firewall Configuration

5.1 UFW (Uncomplicated Firewall)

# Enable UFW
sudo ufw enable

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

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

# Allow web traffic
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Rate limiting for SSH
sudo ufw limit 2222/tcp

# Check status
sudo ufw status verbose

5.2 Iptables Rules

# Drop null packets
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# Reject SYN flood
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# Drop XMAS packets
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Allow established connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Save rules
iptables-save > /etc/iptables.rules

6. Mandatory Access Control

6.1 SELinux

SELinux provides mandatory access control on RHEL-based systems.

# Check SELinux status
sestatus

# Set to enforcing mode
sudo setenforce 1

# Edit /etc/selinux/config for persistence
SELINUX=enforcing

# View SELinux denials
sudo ausearch -m avc -ts recent

# Generate policy module for denied action
sudo audit2allow -a -M mypolicy
sudo semodule -i mypolicy.pp

6.2 AppArmor

AppArmor is the MAC system for Debian/Ubuntu.

# Check AppArmor status
sudo aa-status

# Set profile to enforcing
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

# Set profile to complain mode (logging only)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

# Reload profiles
sudo systemctl reload apparmor

7. Auditing & Monitoring

7.1 System Auditing

# Install auditd
sudo apt install auditd audispd-plugins

# Common audit rules (/etc/audit/rules.d/audit.rules)
# Monitor sudo usage
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers

# Monitor login files
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock/ -p wa -k logins

# Monitor passwd changes
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes

# Search audit logs
sudo ausearch -k sudoers -ts today

7.2 Lynis Security Audit

# Install Lynis
sudo apt install lynis

# Run security audit
sudo lynis audit system

# View report
cat /var/log/lynis.log

7.3 Log Monitoring

# Important logs to monitor
/var/log/auth.log       # Authentication
/var/log/syslog         # System events
/var/log/kern.log       # Kernel messages
/var/log/secure         # RHEL auth log

# Real-time log watching
sudo tail -f /var/log/auth.log

# Search for failed logins
grep "Failed password" /var/log/auth.log | tail -20
Centralized Logging

For production environments, forward logs to a centralized logging solution (ELK Stack, Graylog, Splunk) for better analysis, alerting, and retention. Never store logs only on the server being monitored.

8. Frequently Asked Questions

Should I change the SSH port?
Changing the SSH port from 22 to a non-standard port reduces automated attacks but isn't true security (security through obscurity). It should supplement, not replace, other measures like key-based auth and fail2ban.
SELinux keeps breaking my applications. Should I disable it?
Never disable SELinux in production. Instead, set it to permissive mode temporarily while troubleshooting, analyze audit logs, and create appropriate policies. Modern applications should work with SELinux in enforcing mode.
How often should I run security audits?
Run automated audits (Lynis) weekly, perform configuration reviews monthly, and conduct comprehensive penetration testing annually. Also audit after any significant changes to the system.

Conclusion

Linux server security requires continuous attention. Start with the basics—updates, SSH hardening, firewall configuration—then layer on additional protections like MAC frameworks and comprehensive auditing. No single measure provides complete protection; effective security comes from implementing multiple overlapping controls.

Continue Learning:
Container Security SELinux/AppArmor Guide