The Complete Linux Server Security Hardening Checklist (2025)

✅ SSH keys only
✅ Firewall rules
✅ fail2ban
✅ Auto-updates
✅ Audit logging
✅ Kernel params

Most security breaches don't exploit zero-days. They exploit known misconfigurations — default passwords, unrestricted SSH, missing patches. This checklist covers every step you should take before a Linux server goes live in production. Commands are tested on Ubuntu 22.04 LTS and work on Debian 12.

⚠️

Apply all steps before your server goes live. Re-applying security controls to a running production server is risky and much harder to do safely.

1. Access Control

✅ SSH key-only authentication

# Edit /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
PermitRootLogin no           # Use sudo from a regular user
MaxAuthTries 3
ClientAliveInterval 300      # Disconnect idle sessions after 5 min
AllowUsers your-username     # Whitelist specific users

sudo systemctl restart sshd

✅ Use ed25519 keys (not RSA 2048)

ssh-keygen -t ed25519 -C "[email protected]"

✅ Create a non-root sudo user

adduser deploy
usermod -aG sudo deploy
# Copy your public key to the new user
su - deploy
mkdir ~/.ssh && chmod 700 ~/.ssh
echo "YOUR_PUBLIC_KEY" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

✅ Change the default SSH port (optional but reduces noise)

# /etc/ssh/sshd_config
Port 2222    # Or any port above 1024

# Update your firewall rule to match the new port

2. Firewall

✅ Enable UFW with default deny

sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow only what you need
sudo ufw allow from YOUR_IP to any port 22   # SSH from your IP only
sudo ufw allow 80/tcp                        # HTTP
sudo ufw allow 443/tcp                       # HTTPS

sudo ufw enable
sudo ufw status verbose
💡

VeloxaHost's network-level firewall blocks traffic before it reaches your instance's kernel. UFW adds a second layer at the OS. Run both.

3. Brute Force Protection

✅ Install and configure fail2ban

sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Minimal jail.local configuration:

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled  = true
maxretry = 3
sudo systemctl enable --now fail2ban

See the full setup guide: fail2ban complete setup →

4. Automatic Security Updates

✅ Enable unattended-upgrades

sudo apt install unattended-upgrades apt-listchanges -y
sudo dpkg-reconfigure --priority=low unattended-upgrades

Verify it's working:

sudo systemctl status unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades

The output should include:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

5. Audit Logging

✅ Install auditd

sudo apt install auditd audispd-plugins -y
sudo systemctl enable --now auditd

✅ Add critical audit rules

# /etc/audit/rules.d/hardening.rules

# Log all authentication events
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k privileged

# Log sudo usage
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k privileged

# Log SSH logins
-w /var/log/auth.log -p wa -k auth

sudo augenrules --load

✅ View audit logs

# Recent logins
ausearch -k auth -ts recent

# All sudo commands
ausearch -k privileged -ts today

6. Kernel Security Parameters

✅ Harden /etc/sysctl.conf

cat >> /etc/sysctl.d/99-hardening.conf <<'EOF'
# Disable IP forwarding (unless this is a router)
net.ipv4.ip_forward = 0

# Prevent SYN flood attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048

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

# Disable source routing
net.ipv4.conf.all.accept_source_route = 0

# Log martian packets (packets with impossible source addresses)
net.ipv4.conf.all.log_martians = 1

# Disable IPv6 if not in use
net.ipv6.conf.all.disable_ipv6 = 1
EOF

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

7. Minimize Attack Surface

✅ Disable unused services

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

# Disable anything you don't need
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now bluetooth
sudo systemctl disable --now cups

✅ Remove unnecessary packages

sudo apt autoremove --purge -y
sudo apt clean

8. Secrets & Application Security

✅ Never hardcode credentials

  • Load all secrets from environment variables or a secrets manager
  • Use .env files with chmod 600 .env
  • Rotate secrets immediately if they're ever committed to git

✅ Check for exposed sensitive files

# Find world-readable .env files
find / -name ".env" -perm /o+r 2>/dev/null

# Find SUID binaries (potential privilege escalation)
find / -perm -4000 -type f 2>/dev/null

9. Monitoring & Alerting

✅ Set up CPU and memory alerts

In VeloxaHost console, go to Monitoring → Alert Rules and create alerts for:

  • CPU usage > 85% for 5 minutes (application malfunction or crypto mining)
  • Memory usage > 90% (OOM risk)
  • Disk usage > 80% (application or logs filling up)

✅ Watch auth.log for failed logins

# Live tail of authentication events
sudo tail -f /var/log/auth.log | grep -i "fail\|invalid\|error"

# Count failed login attempts by IP
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20

Final Checklist

  • ✅ SSH key-only, no root login, no password auth
  • ✅ Non-root sudo user created
  • ✅ UFW firewall — deny-all inbound, allowlist only needed ports
  • ✅ fail2ban — 3 attempts triggers 1-hour ban
  • ✅ unattended-upgrades — daily security patch install
  • ✅ auditd — all privileged actions logged
  • ✅ sysctl hardening — SYN flood protection, redirects disabled
  • ✅ Unnecessary services disabled
  • ✅ No hardcoded secrets anywhere
  • ✅ Monitoring alerts configured

VeloxaHost instances start with network-level firewall protection. Add your OS-level hardening and you have a defense-in-depth setup. Deploy a hardened instance →