Introduction & The Threat Landscape
The moment a Linux instance (VPS, dedicated server, or Cloud VM) is provisioned and assigned a public IP address, it immediately becomes a target for automated botnets. These scripts continuously scan IP ranges looking for default open ports (SSH on port 22, Docker Daemon on 2375, Redis on 6379, PostgreSQL on 5432) and attempt brute-force or known CVE exploitation.
Linux Hardening is the process of applying a systematic set of strict configurations designed to minimize the attack surface, isolate processes, and eliminate intrusion vectors.
1. SSH Configuration: Vulnerable Default vs. Hardened
❌ Insecure Default SSH Configuration (/etc/ssh/sshd_config)
Port 22 # Standard port targeted by 100% of automated scanners
PermitRootLogin yes # Direct root login allowed!
PasswordAuthentication yes # Password-based auth enabled (vulnerable to dictionary attacks)
MaxAuthTries 6 # Too many attempts — enables brute-force
X11Forwarding yes # Unnecessary X11 forwarding opens attack surface
AllowTcpForwarding yes # Open TCP tunneling
✅ Hardened SSH Configuration (/etc/ssh/sshd_config.d/hardening.conf)
# CIS Benchmarks & ANSSI-compliant hardening
Port 49222 # Non-standard port eliminates automated scan noise
PermitRootLogin no # Direct root login strictly forbidden
PasswordAuthentication no # Password-based authentication DISABLED
KbdInteractiveAuthentication no
PubkeyAuthentication yes # Ed25519 or RSA 4096-bit keys only
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3 # Immediate lockout after 3 failed attempts
ClientAliveInterval 300 # Auto-disconnect idle sessions after 5 minutes
ClientAliveCountMax 2
X11Forwarding no
AllowAgentForwarding no
# Syntax check before restarting (prevents accidental lockout!)
sudo sshd -t
sudo systemctl restart sshd
2. Firewall Setup with UFW & Brute-Force Protection with Fail2ban
✅ UFW Firewall Configuration
# Deny all inbound traffic by default, allow all outbound
sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Only allow web traffic and your custom SSH port
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw allow 49222/tcp comment 'Custom SSH'
sudo ufw enable
sudo ufw status verbose
✅ Fail2ban Configuration (/etc/fail2ban/jail.local)
[DEFAULT]
bantime = 86400 # 24-hour ban
findtime = 600 # 10-minute analysis window
maxretry = 3 # Ban after 3 failed attempts
[sshd]
enabled = true
port = 49222
logpath = %(sshd_log)s
backend = %(sshd_backend)s
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
3. Rootless Docker — Preventing Container Escape Privilege Escalation
By default, the Docker daemon runs as root on the host. If a container escape vulnerability is exploited, the attacker gains root access to the entire physical server.
# Disable the privileged Docker root service
sudo systemctl disable --now docker.service docker.socket
# Install rootless Docker for the current non-root user
dockerd-rootless-setuptool.sh install
# Set environment variable
export DOCKER_HOST=unix:///run/user/$UID/docker.sock
echo "export DOCKER_HOST=unix:///run/user/$UID/docker.sock" >> ~/.bashrc
# Enable auto-start without requiring an active user session
sudo loginctl enable-linger $USER
Complete Linux Hardening Checklist (10 Golden Rules)
- [ ] Disable SSH password authentication (
PasswordAuthentication no). - [ ] Forbid direct root login (
PermitRootLogin no). - [ ] Change SSH default port (move from 22 to a port > 1024).
- [ ] Set UFW to
default deny incoming. - [ ] Deploy Fail2ban or CrowdSec for automated IP banning.
- [ ] Enable automatic security updates (
unattended-upgrades). - [ ] Run Docker in Rootless mode.
- [ ] Audit system file permissions (
/etc/shadowset to 600). - [ ] Enable AppArmor or SELinux in Enforcing mode.
- [ ] Disable all unused services (
bluetooth,cups,avahi-daemon).