Console Login

Zero Trust Architecture in 2024: Implementing Strict Access Control on Norwegian Infrastructure

The Castle is Burning: Why Perimeter Security Failed Us

For the last decade, we treated our internal networks like a trusted sanctuary. Once you VPN'd past the firewall, you had the keys to the kingdom. In 2024, that mindset is negligent. The rise of supply chain attacks and sophisticated lateral movement means we must assume the breach has already happened. As a CTO or Lead Architect operating in the EEA, specifically Norway, the stakes aren't just technical—they are legal. Schrems II and strict Datatilsynet oversight mean that where your data lives and who can see it is a matter of business survival.

We are done with the "hard outer shell, soft gooey center" approach. We are moving to Zero Trust: verify explicitly, use least-privileged access, and assume breach. But this isn't about buying a shiny SaaS tool. It's about fundamental infrastructure hygiene.

Here is how we build a Zero Trust architecture using standard Linux tools available today on reliable infrastructure like CoolVDS.

1. The Foundation: Isolation at the Hardware Level

You cannot build secure software on insecure hardware. If you are running sensitive workloads on budget container-based VPS providers (OpenVZ/LXC), you are sharing a kernel with neighbors you do not know. A kernel panic or exploit in a neighbor's container can impact you.

We require KVM (Kernel-based Virtual Machine) virtualization. It provides hardware-level isolation. At CoolVDS, every instance is a KVM slice with dedicated NVMe storage. This ensures that memory pages and CPU instructions are strictly segregated. Before we even touch an SSH config, we provision a KVM instance in Oslo to ensure low latency and data residency compliance.

Pro Tip: Check your virtualization type. Run systemd-detect-virt. If it says 'lxc' or 'openvz' for a production database, migrate immediately. On CoolVDS, it returns 'kvm'.

2. Identity-Based Access (mTLS) instead of IP Whitelisting

IP addresses are ephemeral and easily spoofed. In a Zero Trust model, services communicate based on cryptographic identity, not network location. We use Mutual TLS (mTLS). In this setup, the client must present a valid certificate signed by your internal Certificate Authority (CA) to even initiate a handshake.

Let's configure Nginx (v1.24+) to reject any connection without a valid client certificate. This effectively hides your application from the public internet, even if the port is open.

Generating the CA and Client Keys

First, create a simple CA on your secure admin machine:

openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Now, generate a client key and sign it:

openssl genrsa -out client.key 4096 openssl req -new -key client.key -out client.csr openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

Nginx Configuration for mTLS

Here is the block you drop into your CoolVDS instance's nginx config to enforce this:

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

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

    # The magic happens here
    ssl_client_certificate /etc/nginx/ssl/ca.crt;
    ssl_verify_client on;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header X-Client-DN $ssl_client_s_dn;
    }
}

If you try to curl this endpoint without the cert, Nginx drops the connection instantly. No application logic is wasted processing unauthorized requests.

curl --cert client.crt --key client.key https://internal-api.coolvds-client.no

3. SSH Hardening: Certificates over Keys

Managing public keys for a team of 20 developers across 50 servers is a nightmare. Keys get lost, people leave, and revocation is messy. In 2024, we use SSH Certificates. You sign a developer's key with an expiry of 8 hours. If their laptop is stolen tomorrow, the key is already useless.

On the server side (your CoolVDS instance), you trust the CA, not individual keys.

Server Configuration (sshd_config)

Add the CA public key to the server and update the config:

# /etc/ssh/sshd_config TrustedUserCAKeys /etc/ssh/user_ca.pub AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u

Now, sign a user's key on your bastion host:

ssh-keygen -s ca_key -I user_id -n root,devops -V +8h id_rsa.pub

This generates id_rsa-cert.pub. The developer uses this to log in. No more stray keys in ~/.ssh/authorized_keys.

4. Micro-Segmentation with WireGuard

VLANs are clunky. For securing traffic between your web servers and your database (which should definitely be on separate CoolVDS instances for reliability), we use WireGuard. It is built into the Linux kernel, incredibly fast, and creates an encrypted mesh overlay.

Instead of trusting the datacenter switch, we trust the WireGuard interface `wg0`. Here is a configuration for a database server that only accepts traffic from specific application peers.

WireGuard Config (Database Node)

# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = 

# Web Server 1 Peer
[Peer]
PublicKey = 
AllowedIPs = 10.0.0.2/32

# Web Server 2 Peer
[Peer]
PublicKey = 
AllowedIPs = 10.0.0.3/32

Bring it up with:

wg-quick up wg0

Now, bind your database (PostgreSQL/MySQL) to listen only on `10.0.0.1`. Even if the public firewall fails, the database is inaccessible to the internet.

5. The Final Layer: NFTables

iptables is legacy. In 2024, we use nftables for atomic rule replacement and better syntax. We need a default-drop policy. If traffic isn't explicitly allowed, it dies.

Strict NFTables Ruleset

This configuration ensures that only SSH (guarded by certificates) and WireGuard traffic are allowed on the input chain, plus standard web ports if it's a public facing node.

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # Accept localhost and established traffic
        iifname "lo" accept
        ct state established,related accept

        # Allow WireGuard VPN traffic
        udp dport 51820 accept
        iifname "wg0" accept

        # Allow SSH (Rate limited)
        tcp dport 22 ct state new limit rate 10/minute accept

        # ICMP is necessary for MTU path discovery
        ip protocol icmp accept
    }
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Load this with nft -f /etc/nftables.conf. This is the level of control you need. Managed cloud load balancers often obscure this logic. On a CoolVDS unmanaged instance, you own the kernel, the network stack, and the firewall rules. You are in control.

Why Infrastructure Matters for Zero Trust

You can script all the above, but if the underlying host is oversold or suffers from I/O wait due to noisy neighbors, your mTLS handshakes will timeout and your database replication over WireGuard will lag. Zero Trust adds a slight computational overhead due to constant encryption and verification.

This is why CoolVDS uses high-frequency CPUs and pure NVMe storage. We don't throttle your encryption operations. When you are building a fortress, you need a foundation of granite, not sand. For Norwegian businesses, combining this technical rigour with our Oslo-based data residency offers a compliance posture that is hard to beat.

Stop relying on the perimeter. Assume the network is hostile. Encrypt everything.

Ready to lock down your infrastructure? Deploy a KVM instance on CoolVDS today and start building your Zero Trust architecture.