Console Login

Kill the Perimeter: Implementing Zero-Trust on Linux in Post-Safe Harbor Europe

Your Internal Network is Compromised. Accept It.

I have a simple rule for every junior sysadmin that joins my team: Trust nothing. verify everything. For the last decade, we built infrastructure like medieval castles. We dug deep moats (firewalls) and assumed anyone inside the castle walls (the LAN) was a friend. That era is over. The Target breach proved it. The Sony hack proved it. And if you are running a standard VPS setup where database ports are open to the local network because you 'trust' your web server, you are next.

We are seeing a shift towards what Forrester calls the Zero Trust model. Google has been doing this internally with their 'BeyondCorp' initiative, but you don't need Google's budget to implement the basics. In fact, with the recent invalidation of the US-EU Safe Harbor agreement by the European Court of Justice this October (Schrems I), hosting data outside of sovereign territory is a legal minefield. If you are serving Norwegian customers, your data needs to stay in Norway, and your security needs to assume the internet is hostile.

Pro Tip: Stop relying on VLAN isolation alone. VLAN hopping attacks are trivial if your switch configuration is sloppy. Treat eth1 (private network) with the same suspicion as eth0 (public network).

1. Identity is the New Perimeter

In a Zero Trust environment, IP addresses mean nothing. An IP can be spoofed. Access must be granted based on identity, not location. This starts with how you access your servers. If you are still using passwords for SSH, you are failing. If you are using standard port 22 exposed to the world, you are failing.

We lock down our CoolVDS instances immediately. Here is the standard /etc/ssh/sshd_config hardening we deploy on CentOS 7:

Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
AllowUsers deploy_admin

Notice AuthenticationMethods. This forces a two-step verification: first the SSH key, then the 2FA code. We use libpam-google-authenticator for this. It adds latency to the login process, but it stops credential theft dead in its tracks.

2. Encryption Inside the Wire

The old way: Terminate SSL at the load balancer (HAProxy/Nginx) and talk cleartext HTTP to the backend app servers to save CPU cycles.
The Zero Trust way: Encrypt everything.

With modern AES-NI instructions on CPUs (which we ensure are available on all CoolVDS KVM slices), the performance penalty for internal SSL is negligible. There is no excuse for cleartext traffic, even on the private loopback.

Just last week (December 3, 2015), Let's Encrypt entered Public Beta. This is massive. It means we can finally automate certificate issuance for every single endpoint without paying Thawte or Verisign a fortune. Here is how we grab a cert on a live server now:

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto certonly --standalone -d secure.mydomain.no

Script this. Put it in cron. If your internal API talks to your database without TLS, a compromised web node allows an attacker to sniff the entire customer database wire traffic.

3. Micro-Segmentation with IPTables

Every server is an island. On our infrastructure, we don't rely on the hosting provider's hardware firewall alone. We configure iptables (or firewalld on CentOS 7) to drop everything by default. Explicitly allow only what is necessary.

If you have a MySQL server, it should strictly accept connections only from the specific IP of the web server, on the specific port, and nothing else.

# Flush existing rules
iptables -F

# Default policy: DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow SSH only from VPN Gateway IP (10.8.0.5)
iptables -A INPUT -p tcp -s 10.8.0.5 --dport 22 -j ACCEPT

# Web traffic (if this is a web node)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

4. The VPN Gateway vs. Public Exposure

Never expose your management interfaces (cPanel, PHPMyAdmin, Jenkins) to the public internet. We use OpenVPN to create a secure tunnel into the management VLAN. It acts as the gatekeeper. You connect to the VPN, perform 2FA, and only then can you route packets to the backend services.

FeatureStandard VPS SetupCoolVDS Zero-Trust Setup
AccessPublic SSH Port 22VPN + SSH Keys + 2FA
Internal TrafficCleartext HTTP/MySQLTLS 1.2 Encrypted
FirewallPermissive / Edge onlyHost-based Micro-segmentation
VirtualizationOpenVZ (Shared Kernel Risk)KVM (Kernel Isolation)

Why Infrastructure Choice Matters

You cannot build a secure house on sand. Many