TLS, IPSec, and WireGuard aren’t just about making network traffic "private"; they’re fundamentally about establishing trust in a hostile environment.

Let’s watch WireGuard set up a tunnel in real-time. Imagine two machines, client (192.168.1.10) and server (192.168.1.20).

client configuration (/etc/wireguard/wg0.conf):

[Interface]
PrivateKey = <client_private_key>
Address = 10.0.0.2/24
ListenPort = 51820

[Peer]
PublicKey = <server_public_key>
Endpoint = 192.168.1.20:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24

server configuration (/etc/wireguard/wg0.conf):

[Interface]
PrivateKey = <server_private_key>
Address = 10.0.0.1/24
ListenPort = 51820

[Peer]
PublicKey = <client_public_key>
AllowedIPs = 10.0.0.2/32

After starting WireGuard on both: sudo wg-quick up wg0

On client, we can ping server’s WireGuard IP: ping 10.0.0.1

And on server, we can ping client’s WireGuard IP: ping 10.0.0.2

This seems like simple routing, but WireGuard has just performed a complex dance. It used the PublicKey values to authenticate each other before any data was sent. The PrivateKey on each side is kept secret, and the corresponding PublicKey is shared. When client sees server’s public key, it knows it’s talking to the intended server because only that server possesses the matching private key. This is asymmetric cryptography in action, establishing a shared secret key for that session only via the Noise protocol handshake. This ephemeral session key is what encrypts the actual data packets.

The AllowedIPs are crucial. On the client, AllowedIPs = 10.0.0.0/24, 192.168.1.0/24 means that any traffic destined for the WireGuard subnet (10.0.0.0/24) or the server’s local network (192.168.1.0/24) should be sent through the WireGuard tunnel. On the server, AllowedIPs = 10.0.0.2/32 means that only traffic originating from that specific client IP (10.0.0.2) is accepted through this peer configuration. It’s a whitelist for what traffic is allowed into the tunnel from a specific peer.

The core problem these protocols solve is the inherent insecurity of public networks. You can’t trust that data sent over the internet hasn’t been tampered with or read by an intermediary. TLS secures application-layer traffic (like web browsing via HTTPS), IPSec secures network-layer traffic (often used for VPNs to connect entire networks), and WireGuard is a modern, simpler VPN protocol. They all use public-key cryptography to authenticate endpoints and symmetric cryptography to encrypt the actual data, but they differ in their scope, complexity, and implementation.

TLS, typically used in HTTPS, involves a handshake where the server presents a certificate (signed by a Certificate Authority, or CA) to prove its identity. The client verifies this certificate against its trusted CA store. If valid, they negotiate a symmetric encryption key for the session. IPSec is more complex, often involving two layers: the Authentication Header (AH) for integrity and authenticity, and Encapsulating Security Payload (ESP) for confidentiality, integrity, and authentication. It can operate in tunnel mode (encrypting the entire original IP packet) or transport mode (encrypting only the payload). WireGuard, by contrast, is designed for simplicity and performance, using the Noise protocol framework for its handshake and modern crypto primitives like ChaCha20-Poly1305 for encryption.

A key insight is that the Endpoint in WireGuard is not just a destination IP; it’s the only IP that WireGuard will listen to for traffic associated with that peer. If the Endpoint IP changes, the connection breaks unless you update the configuration. This is a deliberate design choice for simplicity and security, avoiding complex NAT traversal issues that plague older VPN protocols, but it means you need to know the public IP address of your peers.

The next hurdle is often managing multiple peers or dealing with dynamic IP addresses, which leads into topics like dynamic DNS and more sophisticated VPN gateway setups.

Want structured learning?

Take the full Computer Networking course →