Paranoid Penguin: The Definitive Linux Server Hardening Guide
Let's be honest. If you just spun up a fresh CentOS 6 or Ubuntu 12.04 box and left it on the public internet with default settings, it's already compromised. Between the script kiddies running automated scanners and the sophisticated botnets we've seen rise this year, the "security through obscurity" mindset is dead. I've spent the last week cleaning up a client's mess after a rootkit took hold of their unpatched Apache server, and I don't want to do it again.
Security isn't a product you buy; it's a process you endure. It’s about reducing the attack surface until the effort required to hack you exceeds the value of your data. In Norway, where the Datatilsynet (Data Protection Authority) takes the Personal Data Act seriously, losing customer data due to negligence isn't just embarrassing—it's a legal nightmare waiting to happen.
This guide assumes you have root access and aren't afraid of a terminal. We are going to lock down a standard LAMP stack server. No GUI tools, no hand-holding.
1. The First Line of Defense: SSH Hardening
The moment your IP is announced via BGP, the brute-force attacks begin. Default SSH runs on port 22 and allows root login. This is suicide. We need to move the port (to reduce log noise, not for real security) and strictly enforce key-based authentication.
Open your config:
vi /etc/ssh/sshd_config
Find and modify these lines. If they don't exist, add them:
# Change standard port to avoid lazy scanners
Port 2222
# Never allow root to log in directly
PermitRootLogin no
# Disable password auth. Keys or go home.
PasswordAuthentication no
UsePAM no
# Limit who can actually log in
AllowUsers yourusername
Restart the service immediately. On CentOS 6:
service sshd restart
Pro Tip: Before you close your current session, open a new terminal window and try to connect. If you messed up the config, you don't want to lock yourself out of a remote server. At CoolVDS, we offer a VNC console for emergencies, but you shouldn't rely on it for bad config management.
2. IPTables: Because "Allow All" is Not a Policy
Many VPS providers give you a server with an empty firewall. While tools like UFW (Uncomplicated Firewall) on Ubuntu are cute, a real sysadmin should understand the underlying iptables chains. We want a default DROP policy. If we didn't ask for it, we don't want it.
Here is a battle-tested rule set for a web server. Note that we are allowing our new SSH port defined above.
# Flush existing rules
iptables -F
# Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Accept on localhost
iptables -A INPUT -i lo -j ACCEPT
# Accept established related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH on our custom port
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Log dropped packets (optional, careful with disk space)
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
Save these rules so they persist after a reboot:
service iptables save
3. Automated Defense: Fail2Ban
Even with keys, your logs will fill up with failed attempts. Fail2Ban is mandatory software in 2012. It scans log files (like /var/log/secure or /var/log/auth.log) and bans IPs that show malicious signs by updating your iptables rules dynamically.
Install it (requires EPEL repo on CentOS):
yum install fail2ban
Configure a local jail at /etc/fail2ban/jail.local:
[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=2222, protocol=tcp]
logpath = /var/log/secure
maxretry = 3
bantime = 3600
This creates a temporary ban for one hour if someone fails to authenticate 3 times. It keeps the script kiddies off your back so the CPU can focus on serving PHP requests rather than rejecting handshakes.
4. The Hardware Factor: Isolation Matters
Software hardening is useless if the hypervisor underneath you is leaky. In the budget hosting market, OpenVZ is popular because it allows providers to oversell RAM. But OpenVZ shares the kernel. If there is a kernel panic on the host node, or a vulnerability in the shared kernel, your "secure" container is at risk.
This is why at CoolVDS, we strictly use KVM (Kernel-based Virtual Machine). KVM provides full hardware virtualization. You get your own kernel. Even if a neighbor on the same physical rack gets hit with a fork bomb or a kernel exploit, your instance remains isolated. When you are handling data that falls under Norwegian privacy laws, that isolation isn't a luxury; it's a requirement.
5. Filesystem Triage
If an attacker manages to upload a malicious script to a world-writable directory like /tmp, you want to prevent them from executing it. You can do this by mounting specific partitions with the noexec and nosuid flags.
Edit your /etc/fstab. This requires you to have partitioned your drive correctly during install (or when setting up your CoolVDS volume):
/dev/sda3 /tmp ext4 defaults,noexec,nosuid 0 0
Remount it:
mount -o remount /tmp
Now, even if they upload a rootkit compiler to /tmp, they can't run it.
6. Disable Unused Network Protocols
IPv6 is the future, but in 2012, most internal networks aren't fully ready for it, and it often acts as a silent bypass for your IPv4 firewall rules if not configured identically. If you aren't using it, kill it.
Add this to /etc/sysctl.conf:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
Apply with sysctl -p. While you are there, prevent IP spoofing:
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
Summary
Security is a constant battle against entropy. By disabling root logins, configuring a strict firewall, and isolating your environment on KVM-based virtualization like we offer at CoolVDS, you drastically reduce your profile. In a country like Norway, where internet connectivity via NIX is among the fastest in the world, you can't afford to have that bandwidth hijacked by a botnet.
Don't wait for the breach report. Audit your servers today.