G
GuideDevOps
Lesson 21 of 28

VPN & Tunneling Protocols

Part of the Networking Basics tutorial series.

A VPN (Virtual Private Network) creates a secure, encrypted tunnel through an untrusted network. It's essential for remote work, connecting datacenters, and protecting sensitive traffic. Understanding VPN protocols and tunneling is critical for modern infrastructure.

What is a VPN?

VPN (Virtual Private Network) creates a private network over a public network:

User in Coffee Shop
         ↓ (encrypted tunnel through internet)
    [VPN Tunnel]
         ↓
Private Network (company, datacenter)
         ↑
   Now appears as local user

Why VPNs matter:

  • Security — Encrypt traffic from snooping
  • Privacy — Hide real IP address
  • Access Control — Connect remote sites securely
  • Compliance — Meet data protection requirements

Types of VPNs

Client-to-Site (Remote Access):

Remote User's Device
    ↓
[Client VPN software]
    ↓ (encrypted)
[VPN Server]
    ↓
Internal Network

Result: Remote user connects to company network

Site-to-Site:

Office A Network
    ↓
[VPN Gateway]
    ↓ (encrypted through internet)
[VPN Gateway]
    ↓
Office B Network

Result: Two networks securely connected

VPN Tunneling Protocols

ProtocolTypeSpeedSecuritySetupDevOps Use
OpenVPNSoftwareModerateExcellentComplexRemote access
WireGuardKernelVery FastModernSimpleVPN, site-to-site
IPSecKernelVery FastExcellentComplexSite-to-site, datacenters
SSH TunnelSoftwareModerateGoodVery SimpleQuick tunneling
L2TP/IPSecKernelFastGoodModerateLegacy remote access

OpenVPN

Why OpenVPN:

  • Open source, widely trusted
  • Works over TCP or UDP
  • Cross-platform (Linux, Windows, Mac, mobile)
  • Very flexible configuration
  • Popular with VPN providers

OpenVPN Architecture:

Client                          Server
   ↓                               ↓
[OpenVPN Client] ←→ [OpenVPN Server]
   ↓ (encrypted)                   ↓
Internet connection          Listens on port 1194
   ↑                               ↑

Install OpenVPN:

# Ubuntu/Debian
sudo apt-get install openvpn openvpn-easy-rsa
 
# Generate certificates (Public Key Infrastructure)
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
./easyrsa init-pki
./easyrsa build-ca
./easyrsa gen-req server nopass
./easyrsa sign-req server server

Server Configuration (/etc/openvpn/server.conf):

# Port and protocol
port 1194
proto udp

# Network settings
dev tun
server 10.8.0.0 255.255.255.0

# Certificates
ca ca.crt
cert server.crt
key server.key
dh dh.pem

# Encryption
cipher AES-256-CBC
auth SHA256

# Keep connection alive
keepalive 10 120

# Push settings to clients
push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 8.8.8.8"

# Enable port forwarding
port-share 0.0.0.0 443

Client Configuration (client.ovpn):

client
dev tun
proto udp

remote vpn.example.com 1194

resolv-retry infinite
nobind

ca ca.crt
cert client.crt
key client.key

cipher AES-256-CBC
auth SHA256

verb 3

Connect to VPN:

sudo openvpn --config client.ovpn

WireGuard

Why WireGuard:

  • Extremely simple (4,000 lines of code vs 100,000+ for OpenVPN)
  • Lightning fast (kernel-space)
  • Modern cryptography defaults
  • Perfect for infrastructure
  • Growing adoption

WireGuard Architecture:

Peer A →→ Encrypted Tunnel →→ Peer B
         (WireGuard)

Install WireGuard:

# Ubuntu/Debian
sudo apt-get install wireguard wireguard-tools
 
# Generate keys
wg genkey | tee private.key | wg pubkey > public.key

Server Configuration (/etc/wireguard/wg0.conf):

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-private-key>

# Client 1
[Peer]
PublicKey = <client1-public-key>
AllowedIPs = 10.0.0.2/32

# Client 2
[Peer]
PublicKey = <client2-public-key>
AllowedIPs = 10.0.0.3/32

Client Configuration (/etc/wireguard/wg0.conf):

[Interface]
Address = 10.0.0.2/24
PrivateKey = <client-private-key>

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Start WireGuard:

sudo ip link add dev wg0 type wireguard
sudo ip addr add 10.0.0.1/24 dev wg0
sudo ip link set wg0 up
 
sudo wg set wg0 listen-port 51820 private-key <(wg genkey)
 
# Or use wg-quick
sudo wg-quick up wg0

IPSec (IP Security)

Why IPSec:

  • Industry standard for site-to-site
  • Works at network layer (all protocols)
  • Very secure
  • Native to most enterprise equipment
  • Datacenter-to-datacenter standard

IPSec Components:

IKE (Internet Key Exchange)
  ↓ Negotiates encryption parameters
  ↓
AH (Authentication Header)
  ↓ Signs data integrity
  ↓
ESP (Encapsulating Security Payload)
  ↓ Encrypts data
  ↓
Socket layer - Protected traffic

IPSec Modes:

  • Transport Mode: Encrypt payload only (host-to-host)
  • Tunnel Mode: Encrypt entire IP packet (site-to-site)

Install IPSec (strongSwan):

sudo apt-get install strongswan strongswan-swanctl
 
# Generate keys
ipsec pki --gen --type rsa --size 4096 --outform pem > private.pem

Server IPSec Configuration (/etc/ipsec.conf):

config setup
    charondebug = "ike 2, knl 2"

conn office-to-datacenter
    left = 203.0.113.1
    leftsubnet = 192.168.1.0/24
    right = 198.51.100.1
    rightsubnet = 10.0.0.0/24
    ike = aes256-sha256-modp2048!
    esp = aes256-sha256!
    keyingtries = 0
    ikelifetime = 10h
    lifetime = 1h
    dpd_action = restart
    auto = start
    authby = secret

SSH Tunnels

Why SSH Tunnels:

  • Simplest VPN-like solution
  • SSH already installed everywhere
  • Perfect for quick tunneling
  • No additional software needed
  • Great for emergency access

Local Port Forwarding (access remote service):

# Forward local port 8080 to remote server's MySQL
ssh -L 8080:database.example.com:3306 [email protected]
 
# Now: localhost:8080 → database.example.com:3306 (encrypted)
mysql -h localhost -P 8080

Remote Port Forwarding (expose local service):

# Forward remote port 9000 to local service
ssh -R 9000:localhost:8080 [email protected]
 
# Now: server.example.com:9000 → localhost:8080

Dynamic Port Forwarding (SOCKS proxy):

# Create SOCKS proxy
ssh -D 1080 [email protected]
 
# Configure app to use SOCKS proxy on localhost:1080
# All traffic goes through SSH tunnel

Persistent SSH Tunnel (systemd):

[Unit]
Description=SSH Tunnel to Database
After=network.target
 
[Service]
Type=simple
User=app
ExecStart=/usr/bin/ssh -N -L 5432:db.internal:5432 [email protected]
Restart=always
RestartSec=10
 
[Install]
WantedBy=multi-user.target

VPN in Kubernetes

VPN into Kubernetes Network:

# Access pods from local machine
kubectl port-forward pod/my-pod 8080:8080
 
# Access service
kubectl port-forward svc/my-service 3306:3306
 
# Now any tool can connect:
mysql -h localhost -P 3306

Site-to-Site VPN for Multi-Cloud:

apiVersion: v1
kind: ConfigMap
metadata:
  name: wireguard-config
data:
  wg0.conf: |
    [Interface]
    Address = 10.100.0.1/24
    ListenPort = 51820
    PrivateKey = {key}
    
    [Peer]
    PublicKey = <other-datacenter-key>
    Endpoint = 198.51.100.1:51820
    AllowedIPs = 10.200.0.0/24

Deploy WireGuard as sidecar or DaemonSet for cluster-to-cluster connectivity.

Common VPN Issues

"Can't connect to VPN"

1. Check VPN server running
   sudo systemctl status openvpn@server
 
2. Verify client certificate is valid
   openssl x509 -in client.crt -text -noout
 
3. Check firewall allows port
   sudo ufw status | grep 1194
   sudo iptables -L | grep 1194
 
4. Test connectivity
   telnet vpn.example.com 1194

"VPN connects but no internet"

1. Check routing table
   route -n
   
2. Verify gateway is set
   ip route show
   
3. Check NAT/masquerading
   sudo iptables -L -n -t nat | grep MASQUERADE
 
4. Enable IP forwarding on server
   echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward
   
   # Make permanent
   echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
   sudo sysctl -p

"VPN is slow"

1. Check packet loss
   ping -c 100 vpn.example.com | grep "% packet loss"
 
2. Measure throughput
   iperf3 -c vpn.example.com
 
3. Check encryption overhead
   Check CPU usage: top
 
4. Switch to faster protocol
   WireGuard faster than OpenVPN
   UDP better than TCP

"Can't reach specific hosts through VPN"

1. Verify routing on VPN client
   route -n | grep -E "VPN|10\\."
 
2. Check firewall rules on destination network
   Can destination ping VPN server?
 
3. Verify split tunneling not blocking traffic
   Should route through VPN, not local
 
4. Test with traceroute
   traceroute destination-host

VPN Best Practices

1. Use Modern Protocols

✓ WireGuard for new deployments
✓ OpenVPN for flexibility/compatibility
✗ L2TP/IPSec (legacy)
✗ PPTP (insecure, deprecated)

2. Strong Encryption

✓ AES-256 for data
✓ SHA-256 for authentication
✓ 2048-bit DH or elliptic curve
✗ Weaker ciphers

3. Certificate Rotation

# Regenerate certificates every 1-2 years
/etc/openvpn/easy-rsa/easyrsa gen-req server nopass
/etc/openvpn/easy-rsa/easyrsa sign-req server server
 
# Restart OpenVPN
sudo systemctl restart openvpn@server

4. Monitor VPN Usage

# OpenVPN: check connection logs
tail -f /var/log/openvpn/status.log
 
# WireGuard: show peers
sudo wg show
 
# Monitor bandwidth
nethogs

5. Network Isolation

✓ Place VPN servers in DMZ
✓ Firewall internal networks behind VPN server
✓ Don't expose internal services directly
✗ Don't put VPN server on same network as databases

6. Kill Switch

# If VPN drops, block internet
sudo iptables -A INPUT -i eth0 -j DROP
sudo iptables -A OUTPUT -o eth0 -j DROP
 
# Allow only VPN
sudo iptables -A INPUT -i tun0 -j ACCEPT
sudo iptables -A OUTPUT -o tun0 -j ACCEPT

DevOps VPN Patterns

Bastion Host Access:

Local Dev Machine
    ↓
SSH to Bastion (VPN-like)
    ↓
SSH to Internal Servers

# Often combined with VPN for extra security

Multi-Datacenter Replication:

DC1 Database
    ↓ (VPN site-to-site)
DC2 Database

Replication encrypted end-to-end

Encrypted CI/CD Pipelines:

CI/CD Runner
    ↓ (VPN tunnel)
Private Docker Registry
Private Package Repository
Private Kubernetes Cluster

All communication encrypted

Key Concepts

  • VPN = Virtual Private Network for secure tunneling
  • Client-to-Site = Remote user accessing company network
  • Site-to-Site = Two networks securely connected
  • OpenVPN = Flexible, popular tunneling protocol
  • WireGuard = Modern, fast, simple protocol
  • IPSec = Industry standard, layer 3 encryption
  • SSH Tunnel = Simplest tunnel option
  • Encryption = Protects data in transit
  • Authentication = Verifies packet source
  • Always use VPN for sensitive traffic and remote access