Keep Your System Updated
The single most important security measure is keeping your system and all installed software up to date. Security vulnerabilities are discovered constantly, and patches are released quickly in the Linux ecosystem.
Manual Updates
# Debian/Ubuntu
sudo apt update && sudo apt upgrade -y
# Fedora
sudo dnf upgrade
# Arch
sudo pacman -Syu
Automatic Security Updates
# Debian/Ubuntu - install unattended-upgrades
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
# Verify configuration
cat /etc/apt/apt.conf.d/50unattended-upgrades
# Fedora - enable automatic updates
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic-install.timer
Why Updates Matter
Most successful attacks against Linux systems exploit known vulnerabilities that already have patches available. Automatic security updates ensure critical fixes are applied promptly, even if you forget to run manual updates.
SSH Hardening
SSH is the most common way to remotely manage Linux servers, making it a primary target for attackers. Hardening SSH significantly reduces your attack surface.
Use Key-Based Authentication
# Generate a strong SSH key pair on your LOCAL machine
ssh-keygen -t ed25519 -C "[email protected]"
# Copy the public key to the server
ssh-copy-id user@server
# Test key-based login works before disabling passwords
ssh user@server
Harden sshd_config
Edit /etc/ssh/sshd_config with these recommended settings:
# Disable root login via SSH
PermitRootLogin no
# Disable password authentication (use keys only)
PasswordAuthentication no
# Disable empty passwords
PermitEmptyPasswords no
# Use SSH Protocol 2 only (default on modern systems)
Protocol 2
# Limit authentication attempts
MaxAuthTries 3
# Set idle timeout (disconnect after 5 minutes of inactivity)
ClientAliveInterval 300
ClientAliveCountMax 0
# Restrict SSH to specific users
AllowUsers alice bob
# Or restrict to a group
AllowGroups sshusers
# Change default port (optional layer of obscurity)
Port 2222
# Disable X11 forwarding if not needed
X11Forwarding no
# Disable agent forwarding if not needed
AllowAgentForwarding no
# Test configuration syntax before restarting
sudo sshd -t
# Apply changes
sudo systemctl restart sshd
Do Not Lock Yourself Out
Before disabling password authentication, ensure your SSH key login works correctly. Keep an existing SSH session open while testing changes. If you are configuring a remote server, have an alternative access method (console, out-of-band management) available.
Firewall Configuration
A firewall controls incoming and outgoing network traffic. The principle is simple: deny everything by default, then explicitly allow only what is needed.
# UFW (Uncomplicated Firewall) - recommended for beginners
# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow essential services BEFORE enabling
sudo ufw allow ssh # or: sudo ufw allow 2222/tcp
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
# Enable the firewall
sudo ufw enable
# Check status
sudo ufw status verbose
# Allow access from specific IP only
sudo ufw allow from 10.0.0.5 to any port 22
# Rate limiting for SSH (blocks IPs with 6+ attempts in 30s)
sudo ufw limit ssh
# Deny a specific port
sudo ufw deny 3306/tcp # block external MySQL access
# View numbered rules (for deletion)
sudo ufw status numbered
sudo ufw delete 3
Intrusion Prevention with Fail2Ban
Fail2Ban monitors log files for suspicious activity (like repeated failed login attempts) and automatically bans offending IP addresses using firewall rules.
# Install fail2ban
sudo apt install fail2ban # Debian/Ubuntu
sudo dnf install fail2ban # Fedora
# Create local configuration (never edit jail.conf directly)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Recommended jail.local Settings
[DEFAULT]
# Ban duration: 1 hour
bantime = 3600
# Time window for counting failures
findtime = 600
# Number of failures before ban
maxretry = 5
# Email notifications (optional)
destemail = [email protected]
action = %(action_mwl)s
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 3
bantime = 86400 # 24 hours for SSH
[nginx-http-auth]
enabled = true
# Start and enable fail2ban
sudo systemctl enable --now fail2ban
# Check status
sudo fail2ban-client status
sudo fail2ban-client status sshd
# Manually unban an IP
sudo fail2ban-client set sshd unbanip 192.168.1.100
# View banned IPs
sudo fail2ban-client get sshd banned
User Account Security
Principle of Least Privilege
Every user should have only the minimum permissions necessary to perform their tasks:
# Use sudo instead of logging in as root
# Never set a root password on Ubuntu/Debian (root login disabled)
# Limit sudo access to specific commands when full access is not needed
# In visudo:
deployer ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php-fpm
# Audit who has sudo access
grep -E "^sudo:|^wheel:" /etc/group
# Lock unused accounts
sudo usermod -L olduser
sudo usermod -s /usr/sbin/nologin olduser
# Set password expiration policies
sudo chage -M 90 -m 7 -W 14 username
# Find accounts with no password
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
Strong Password Policies
# Install password quality checking
sudo apt install libpam-pwquality
# Configure /etc/security/pwquality.conf
minlen = 12
dcredit = -1 # require at least 1 digit
ucredit = -1 # require at least 1 uppercase
lcredit = -1 # require at least 1 lowercase
ocredit = -1 # require at least 1 special character
maxrepeat = 3 # no more than 3 repeated characters
File System Security
# Find files with SUID/SGID bits (potential privilege escalation)
sudo find / -type f \( -perm -4000 -o -perm -2000 \) -ls
# Find world-writable files
sudo find / -type f -perm -o+w -ls 2>/dev/null
# Find world-writable directories (excluding /tmp, /var/tmp)
sudo find / -type d -perm -o+w -not -path "/tmp*" -not -path "/var/tmp*" -ls
# Find files with no owner
sudo find / -nouser -o -nogroup 2>/dev/null
# Secure important files
sudo chmod 600 /etc/shadow
sudo chmod 644 /etc/passwd
sudo chmod 600 /etc/ssh/sshd_config
sudo chmod 700 /root
# Set immutable flag (cannot be modified even by root)
sudo chattr +i /etc/passwd
# Remove immutable flag
sudo chattr -i /etc/passwd
Security Auditing
# Check for listening services (minimize attack surface)
sudo ss -tulnp
# Review failed login attempts
sudo lastb
sudo journalctl -u sshd | grep "Failed"
# Check for recently modified system files
find /etc -mtime -7 -type f
# Use Lynis for security auditing
sudo apt install lynis
sudo lynis audit system
# Check open ports from outside (run from another machine)
nmap -sV target_ip
# Review sudo usage
sudo journalctl _COMM=sudo
# Check running services and disable unnecessary ones
systemctl list-units --type=service --state=running
sudo systemctl disable --now unnecessary-service
Security Hardening Checklist
- System is fully updated with automatic security updates enabled
- SSH uses key-based authentication with password login disabled
- SSH root login is disabled
- Firewall is enabled with default deny policy
- Only necessary ports are open
- Fail2Ban is configured and running for SSH
- Unused user accounts are locked or removed
- Strong password policies are enforced
- No unnecessary services are running
- File permissions are properly configured
- SUID/SGID files have been reviewed
- System logs are monitored regularly
- Regular backups are configured and tested
Security is a Process
Security is not a one-time setup but an ongoing practice. Regularly audit your systems, keep software updated, monitor logs for suspicious activity, and stay informed about new vulnerabilities. The techniques on this page form a strong foundation, but always continue learning and adapting your security posture.