Console Login

Zero-Trust Architecture in a Post-Schrems II World: Implementing Identity-Aware Infrastructure on Linux

The Firewall is a Lie: transitioning to Zero-Trust in 2020

If the events of this year have taught us anything, it is that the perimeter is gone. The traditional "Castle and Moat" architecture—where we blindly trusted everything inside the LAN and blocked everything outside—collapsed the moment our workforce went remote in March. But there is a second, quieter explosion that happened in July: the ECJ's Schrems II ruling.

For CTOs and Systems Architects operating in Europe, and specifically here in Norway, the implication is brutal. Relying on the perimeter security of US-owned cloud providers is no longer just a technical risk; it is a compliance minefield. Privacy Shield is dead. Data residency is now a matter of legal survival.

This article isn't about buying expensive "Zero-Trust" appliances. It is about architecting it yourself using standard Linux tools available in Ubuntu 20.04 LTS, replacing implicit trust with explicit identity verification at every layer.

The Core Principle: Never Trust the Network

In a Zero-Trust model, we assume the network is hostile. A packet originating from 192.168.1.5 implies nothing about the legitimacy of the request. We must move authentication from the network layer (IPs, VLANs) to the application layer (mTLS, OIDC, SSH Certificates).

Pro Tip: Zero Trust adds latency. Every request requires authentication and encryption handshakes. If you attempt this on budget spinners with spinning rust (HDD) or oversold CPUs, your application will crawl. We run these workloads on CoolVDS NVMe instances in Oslo because the low latency to the NIX (Norwegian Internet Exchange) helps offset the overhead of the encryption stack.

Layer 1: The Mesh Overlay (WireGuard)

Forget OpenVPN. It is too slow, too bloated, and runs in userspace. With the release of Linux Kernel 5.6 earlier this year, WireGuard is finally mainline. It is the foundation of a modern secure mesh. It uses modern cryptography (Curve25519) and operates directly in the kernel space.

Here is how to set up a bastion interface on Ubuntu 20.04 that accepts traffic only from authenticated peers, effectively cloaking your VPS from port scanners.

# Install WireGuard
sudo apt update && sudo apt install wireguard

# Generate keys
wg genkey | tee privatekey | wg pubkey > publickey

Configure the interface at /etc/wireguard/wg0.conf. Note the strict AllowedIPs setting. We are not creating a gateway; we are creating a point-to-point trust link.

[Interface]
Address = 10.0.0.1/24
SaveConfig = true
PostUp = ufw route allow in on wg0 out on eth0
PostDown = ufw route delete allow in on wg0 out on eth0
ListenPort = 51820
PrivateKey = 

[Peer]
# The Developer's Laptop
PublicKey = 
AllowedIPs = 10.0.0.2/32

Once up, drop all non-WireGuard traffic using UFW, leaving only the UDP port exposed. This makes your SSH and Database ports invisible to the public internet.

sudo ufw allow 51820/udp
sudo ufw allow in on wg0 to any port 22
sudo ufw enable

Layer 2: Mutual TLS (mTLS) with Nginx

WireGuard secures the transport, but what about the application? If you are hosting an internal API or a staging environment, a login screen is not enough. You want the web server to reject the handshake before it even serves a single byte of HTML if the client doesn't possess a valid certificate.

mTLS is the gold standard here. We act as our own Certificate Authority (CA).

1. Generate the CA and Client Keys

# Create CA
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt

# Create Client Key
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr

# Sign Client Key
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

2. Configure Nginx (v1.18)

In your server block, enable ssl_verify_client. This creates a hard gate. Without the certificate loaded in the browser or passed via curl, the server returns a 400 Bad Request immediately.

server {
    listen 443 ssl http2;
    server_name internal-api.coolvds.com;

    ssl_certificate /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;

    # mTLS Configuration
    ssl_client_certificate /etc/nginx/certs/ca.crt;
    ssl_verify_client on;

    location / {
        proxy_pass http://localhost:8080;
    }
}

Layer 3: SSH Certificates (No more Authorized_Keys)

Managing ~/.ssh/authorized_keys files across 50 servers is a disaster waiting to happen. It creates static trust anchors that never expire. Netflix and Facebook solved this years ago with SSH Certificate Authorities.

Instead of trusting a public key, the server trusts a CA. You sign a developer's key for 8 hours. When the certificate expires, access is revoked automatically.

On the Server (CoolVDS Instance):

# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/user_ca.pub

On the CA Machine (Your Admin Workstation):

ssh-keygen -s ca_key -I user_identity -n root -V +8h user_key.pub

This outputs user_key-cert.pub. The user logs in with this certificate. No cleanup required when they leave the company.

The Hardware Reality of Encryption

Implementing WireGuard, mTLS, and SSH signing adds computational overhead. We often see "soft lockups" on cheap VPS providers when high-throughput encrypted traffic hits a CPU that is being stolen by noisy neighbors.

Feature Standard VPS CoolVDS Architecture
CPU Model Generic Xeon (Old Gen) High-Frequency (3.0GHz+)
Storage I/O SATA SSD (Shared) NVMe (Direct Path)
Data Sovereignty Often routed via Frankfurt/US Strictly Norway (Oslo)

When you are terminating SSL/TLS twice (once at the mesh level, once at the app level), I/O wait times become the bottleneck. This is why for our internal deployments at CoolVDS, we strictly use KVM virtualization. It prevents the "container breakout" risks associated with older shared kernel exploits, and it guarantees the CPU cycles needed for heavy cryptographic lifting.

Conclusion

The era of trusting the LAN is over. By layering WireGuard for network opacity, mTLS for application identity, and SSH CAs for access control, you build a fortress that doesn't care where the user is sitting—be it a home office in Bergen or a coffee shop in Trondheim.

However, security is useless if the application becomes unusable due to latency. Encryption demands performance. Ensure your underlying infrastructure is up to the task.

Ready to build your Zero-Trust bastion in Norway? Deploy a high-performance KVM instance on CoolVDS today and keep your data under Norwegian jurisdiction.