Date: February 11, 2013
Location: Oslo, Norway
The Perimeter is Dead. Long Live the Host.
I had a debate with a junior admin last week. He was setting up a cluster for a Magento store and argued that he didn't need iptables on the database server because "it's on the private VLAN."
I almost fired him.
The biggest lie we tell ourselves in 2013 is that the "Internal Network" is a safe space. It is not. Whether you are in a massive corporate datacenter or renting VPS instances, the moment you trust a packet just because it came from a 10.0.0.x IP, you have failed. Forrester calls this concept "Zero Trust." I call it common sense.
If an attacker breaches your web frontend (and with the state of PHP plugins these days, they might), they shouldn't have a free pass to scan your entire backend network. Today, we are going to lock down a Linux infrastructure so tight that even the servers don't trust each other.
Pro Tip: Network perimeters are for comfort, not security. If you aren't auditing traffic oneth1(your private interface) the same way you auditeth0(public), you are running a 'soft center' network. One crack in the shell and it's all over.
1. Host-Based Firewalls: The First Line of Defense
Forget hardware firewalls. They are great for DDoS mitigation, but they know nothing about the context of your application. You need to control traffic at the kernel level. On CoolVDS, we give you raw KVM instances, which means you have full control over netfilter. Don't waste it.
Here is a standard "Paranoid" configuration I use on CentOS 6.3 for a database node. It drops everything by default, even from the internal network, unless explicitly allowed.
# /etc/sysconfig/iptables
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# 1. Allow loopback (essential)
-A INPUT -i lo -j ACCEPT
# 2. Allow established connections (don't break your own SSH)
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# 3. Management: ONLY allow SSH from your specific VPN IP or Jump Box
# Replace 10.10.5.5 with your management IP
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -s 10.10.5.5 -j ACCEPT
# 4. Database: ONLY allow the Web Server IP (Internal) to talk to MySQL
# Replace 10.0.0.20 with your Web Server's Private IP
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -s 10.0.0.20 -j ACCEPT
# 5. Log dropped packets (Crucial for forensics)
-A INPUT -j LOG --log-prefix "IPTABLES_DROP: " --log-level 7
COMMITApply this with service iptables restart. Now, if your web server gets compromised and the attacker tries to scan for other services, they hit a wall. Silence.
2. Encrypting "East-West" Traffic
Too many sysadmins run MySQL over cleartext on the internal LAN because they worry about latency. This is laziness. With the Enterprise SSDs we use at CoolVDS, the I/O bottleneck is gone, and the CPU overhead for SSL is negligible on modern Xeons.
If you don't encrypt internal traffic, a compromised node can sniff your SQL queries. That means they get customer emails, password hashes, and order data. In Norway, under the Personal Data Act (Personopplysningsloven) of 2000, you are mandated to secure sensitive data. If Datatilsynet (The Data Inspectorate) audits you and finds cleartext credit card data traversing a shared switch, you are in for a world of pain.
Here is how to enable SSL in MySQL 5.5.
Step A: Generate Certs
You don't need a public CA for this. Self-signed is fine for internal trust.
# On your CA machine
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3600 -key ca-key.pem > ca-cert.pem
# Create server req/key
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem > server-req.pem
openssl x509 -req -in server-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pemStep B: Configure my.cnf
Add this to /etc/my.cnf on your database server:
[mysqld]
ssl-ca=/etc/mysql/certs/ca-cert.pem
ssl-cert=/etc/mysql/certs/server-cert.pem
ssl-key=/etc/mysql/certs/server-key.pemRestart MySQL. Now, enforce it for your replication user:
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.20' IDENTIFIED BY 'StrongPassword123' REQUIRE SSL;3. Kill the Password
If you are still typing passwords to log into SSH in 2013, stop. Brute force bots are scanning port 22 every millisecond. The only acceptable authentication is an RSA key pair.
Edit /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers deploy_userFor the truly paranoid (like me), use Google Authenticator for 2FA. The libpam-google-authenticator package is available in the EPEL repos for CentOS. It adds a Time-Based One-Time Password (TOTP) requirement. Even if someone steals your laptop and your private SSH key, they still can't get in without your phone.
Why Infrastructure Matters
You can configure all the security software in the world, but it means nothing if your host is noisy or unstable. One reason I deploy these setups on CoolVDS is the isolation. We aren't messing around with oversold OpenVZ containers where a kernel panic on one neighbor takes down the whole node.
You get a KVM slice. You get your own kernel. You get dedicated resources. And crucially for us in the Nordics, your data stays in Oslo, protected by Norwegian law, not subject to the whims of the US Patriot Act.
Security isn't a product you buy. It's a mindset. It's the refusal to trust. Start by distrusting your network, and build up from there.
Need a test environment to practice your iptables fu? Spin up a CoolVDS instance in 55 seconds. The latency to NIX is practically zero.