Securing your Linux server: the 10 commandments
As a freelance developer since 2008, I’ve managed dozens of Linux servers in production. Security isn’t a luxury — it’s an absolute necessity. Every server exposed to the internet receives thousands of intrusion attempts daily. Here are my 10 commandments to effectively protect your Linux server.
1. Disable SSH password authentication
SSH is the primary entry point to your server. The first security measure is to ban passwords in favor of cryptographic keys.
# Generate an Ed25519 key pair (recommended in 2024+)
ssh-keygen -t ed25519 -C "your@email.com"
# Copy the public key to your server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server
Then edit /etc/ssh/sshd_config:
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
Ed25519 keys are now the de facto standard: they offer an excellent balance between security and performance, with shorter keys than RSA for equivalent security.
2. Change the default SSH port
Port 22 is constantly scanned by bots. Moving SSH to a non-standard port significantly reduces automated noise in your logs.
# /etc/ssh/sshd_config
Port 2222
This measure alone isn’t enough — it only reduces automated detection surface. But combined with other measures, it contributes to a defense-in-depth strategy.
3. Disable root login
The root account is the number one target for attackers. It should be disabled for direct SSH login:
# /etc/ssh/sshd_config
PermitRootLogin no
Use a dedicated user with sudo privileges for administration tasks:
# Create a dedicated user
adduser admin
usermod -aG sudo admin
4. Configure a firewall with UFW
A firewall is non-negotiable. UFW (Uncomplicated Firewall) provides a simple interface for iptables/nftables:
# Default policy: block all incoming
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow only necessary ports
sudo ufw allow 2222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable the firewall
sudo ufw enable
sudo ufw status verbose
The golden rule: only allow what you explicitly need. Everything else should be blocked.
5. Install and configure Fail2Ban
Fail2Ban monitors connection logs and automatically bans IP addresses that accumulate failed login attempts:
sudo apt install fail2ban -y
Create a local configuration in /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
Restart the service and check active bans:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
6. Keep the system updated
Security updates are your first line of defense against known vulnerabilities. On Debian/Ubuntu:
# Manual update
sudo apt update && sudo apt upgrade -y
# Configure automatic security updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
The unattended-upgrades service will automatically install security patches, ensuring your server stays protected without daily intervention.
7. Implement a backup strategy
No security is complete without backups. The 3-2-1 rule is a good starting point:
- 3 copies of your data
- 2 different storage media
- 1 copy off-site
For a typical web server, an automated backup script might look like:
#!/bin/bash
# backup.sh - Daily backup
BACKUP_DIR="/backup/$(date +%Y-%m-%d)"
mkdir -p "$BACKUP_DIR"
# Back up website files
tar -czf "$BACKUP_DIR/site.tar.gz" /var/www/
# Back up databases
mysqldump --all-databases | gzip > "$BACKUP_DIR/databases.sql.gz"
# Rotation: keep last 30 days
find /backup -type d -mtime +30 -exec rm -rf {} +
# Sync to remote storage
rsync -avz /backup/ user@backup-server:/backups/
Schedule with cron and regularly test restoration. An untested backup doesn’t exist.
8. Monitor your server
Monitoring allows you to detect anomalies before they become incidents. Several tools are essential:
For the system:
# Monitor resources in real-time
htop
# Analyze disk space
df -h
# Check active processes
ps aux --sort=-%mem | head -20
For security logs:
# Recent failed login attempts
sudo grep "Failed password" /var/log/auth.log | tail -20
# Currently logged-in users
who
last
For continuous monitoring, tools like Prometheus + Grafana, or SaaS solutions like UptimeRobot and Sentry, provide proactive alerting.
9. Harden file permissions
Poor file permissions are an open door for attackers. Apply the principle of least privilege:
# SSH configuration file permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Web file permissions
sudo chown -R www-data:www-data /var/www/
sudo find /var/www/ -type d -exec chmod 755 {} \;
sudo find /var/www/ -type f -exec chmod 644 {} \;
# Restrict access to sensitive files
chmod 600 /etc/shadow
chmod 644 /etc/passwd
10. Disable unnecessary services
Every active service represents a potential attack surface. Inventory and disable what you don’t use:
# List active services
systemctl list-units --type=service --state=running
# Disable an unnecessary service
sudo systemctl disable --now bluetooth
sudo systemctl disable --now avahi-daemon
Also check open ports:
sudo ss -tlnp
Conclusion
Linux server security isn’t a one-time event but a continuous process. These 10 commandments form a solid foundation that eliminates the vast majority of automated attack vectors. The key is implementing defense in depth: each security layer compensates for potential weaknesses in others.
As a freelancer, the responsibility for your server security rests entirely on your shoulders. Invest time in these best practices from the start — you’ll avoid incidents far more costly to resolve after the fact.