Hardening a Linux VPS: Beyond ufw and fail2ban
Installing ufw and fail2ban is not "hardening"; it is basic hygiene. If an attacker bypasses your firewall (e.g., via a PHP vulnerability in WordPress), those tools do nothing to stop privilege escalation or lateral movement.
This guide covers true server hardening: Kernel-level restrictions, shared memory lockdown, and network stack tuning to prevent spoofing and Man-in-the-Middle (MITM) attacks.
1. SSH Hardening: Key Exchange & Algorithm lockdown
Disabling PermitRootLogin is elementary. You need to restrict the cryptographic primitives your SSH server accepts to prevent "Downgrade Attacks" from legacy clients.
Edit /etc/ssh/sshd_config and append these strict KEX (Key Exchange) algorithms:
KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected],[email protected]
2. Kernel Hardening via Sysctl
The Linux networking stack defaults to "compatible," not "secure." We need to modify /etc/sysctl.conf to prevent IP spoofing and harden the TCP stack.
Prevent IP Spoofing & MITM
# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP Echo requests (Ping) - optional but recommended
net.ipv4.icmp_echo_ignore_all = 1
# Disable IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Disable ICMP Redirects (MITM protection)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
Protect Memory Space (ASLR & Ptrace)
# Randomize the address space of running processes (ASLR)
kernel.randomize_va_space = 2
# Restrict dmesg access to root only (hides kernel addresses)
kernel.dmesg_restrict = 1
# Hide kernel pointers from unprivileged users
kernel.kptr_restrict = 2
Apply changes with: sysctl -p
3. Securing Shared Memory (/dev/shm)
By default, /dev/shm is a world-writable memory space. Exploits often use this directory to run malicious scripts because most firewalls don't scan memory-mapped filesystems.
Edit your /etc/fstab to mount shared memory with noexec and nosuid:
tmpfs /dev/shm tmpfs defaults,noexec,nosuid,nodev 0 0
Effect: Even if a hacker uploads a binary exploit to your server, they cannot execute it from shared memory. Remount immediately with mount -o remount /dev/shm.
4. AppArmor / SELinux (Mandatory Access Control)
Discretionary Access Control (DAC)—standard chmod/chown permissions—is insufficient. If the www-data user is compromised, DAC allows it to access anything readable by "others."
For Ubuntu/Debian (AppArmor)
Ensure your critical services (Nginx, MySQL, PHP-FPM) have enforcing profiles loaded.
# Check status
sudo aa-status
# Install profiles for common services
sudo apt install apparmor-profiles apparmor-utils
# Set Nginx to strict enforcement mode
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
5. File Integrity Monitoring (AIDE)
How do you know if a binary like /bin/ls has been replaced with a rootkit? You need a checksum database.
sudo apt install aide
sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Run a daily cron job to check for changes: aide --check. This will alert you if any system file changes size, hash, or modification date, indicating a breach.