What a VPN Actually Does (And Why Most Devs Use It Wrong)

Published: (June 11, 2026 at 01:02 PM EDT)
5 min read
Source: Dev.to

Source: Dev.to

Every developer I know has a VPN. Most of them have it running while they’re logged into Google, sending data through Chrome, and using apps that do their own certificate pinning — which means the VPN is protecting approximately nothing meaningful in that moment. This isn’t a knock on VPNs. It’s a scoping problem. Here’s what the tool actually covers, what leaks around it, and how to test it properly. A VPN operates at Layer 3 (Network) of the OSI model. It creates an encrypted tunnel — typically using WireGuard, OpenVPN, or IKEv2/IPSec — between your device and a VPN server. All IP traffic gets routed through that tunnel. Protocol comparison:

Protocol Speed Security Port Notes

WireGuard ⭐⭐⭐ Fast ⭐⭐⭐ Strong UDP 51820 Modern, audited, ~4000 lines of code

OpenVPN ⭐⭐ Medium ⭐⭐⭐ Strong TCP 443 / UDP 1194 Battle-tested, ~100k lines

IKEv2/IPSec ⭐⭐⭐ Fast ⭐⭐ Good UDP 500/4500 Native on mobile, good reconnect

L2TP/IPSec ⭐ Slow ⭐ Weak UDP 1701 Avoid — potentially compromised

WireGuard is the correct choice in 2026 unless you have a specific reason not to use it. Smaller codebase = smaller attack surface. Most audited VPN providers now use it by default. The VPN handles IP routing. It doesn’t handle everything else. DNS leaks are the most common issue. If your system’s DNS resolver isn’t explicitly routed through the tunnel, your DNS queries go directly to your ISP — revealing every domain you visit even with the VPN active. Test this from the terminal:

Check your current DNS resolver

cat /etc/resolv.conf

Test for DNS leak (run while VPN is active)

Should show your VPN provider’s DNS, not your ISP’s

nslookup whoami.akamai.net

More thorough test

dig +short myip.opendns.com @resolver1.opendns.com

Most reputable VPN clients handle DNS routing automatically, but worth verifying — especially on Linux where DNS management is fragmented across systemd-resolved, dnsmasq, and NetworkManager depending on your distro. WebRTC leaks expose your real IP through browser APIs even when a VPN is active. This is a browser-layer problem, not a network-layer problem. // WebRTC leak test — run in browser console while on VPN // If this returns your real IP, you have a WebRTC leak const pc = new RTCPeerConnection({ iceServers: [{ urls: ‘stun:stun.l.google.com:19302’ }] }); pc.createDataChannel(”); pc.createOffer().then(offer => pc.setLocalDescription(offer)); pc.onicecandidate = (e) => { if (e.candidate) { const ip = e.candidate.candidate.match(/(\d+.\d+.\d+.\d+)/); if (ip) console.log(‘IP exposed via WebRTC:’, ip[1]); } };

Fix: Firefox has media.peerconnection.enabled in about:config. Chrome requires an extension or a VPN client with WebRTC leak protection built in. Application-layer tracking doesn’t touch the network layer at all. If you’re authenticated in your browser, that session follows you. Cookies, localStorage, IndexedDB — none of this is affected by routing your IP through Amsterdam. A kill switch blocks all traffic if the VPN connection drops. Without it, your traffic briefly reverts to your real IP when the tunnel reconnects. This is the correct default for any privacy-sensitive setup. On Linux with ufw:

Block all traffic by default

sudo ufw default deny outgoing sudo ufw default deny incoming

Allow only traffic through VPN interface (tun0 for OpenVPN, wg0 for WireGuard)

sudo ufw allow out on tun0 sudo ufw allow out on wg0

Allow LAN traffic if needed

sudo ufw allow out on eth0 to 192.168.0.0/16 sudo ufw allow out on eth0 to 10.0.0.0/8

sudo ufw enable

WireGuard users can use PostUp/PreDown hooks in the config for a more integrated approach: [Interface] PrivateKey = Address = 10.x.x.x/32 DNS = 1.1.1.1

PostUp = iptables -I OUTPUT ! -o wg0 -m mark ! —mark $(wg show wg0 fwmark) -j REJECT PreDown = iptables -D OUTPUT ! -o wg0 -m mark ! —mark $(wg show wg0 fwmark) -j REJECT

Split tunneling lets you route specific traffic through the VPN while everything else goes directly. Useful when you need VPN for specific services but don’t want to tunnel your local development traffic or internal network requests. Most GUI clients support this natively. For WireGuard directly: [Peer] PublicKey = Endpoint = :51820

Route only specific subnets through VPN instead of all traffic

AllowedIPs = 10.0.0.0/8, 172.16.0.0/12

vs. route everything:

AllowedIPs = 0.0.0.0/0, ::/0

✅ Your ISP can’t see which domains you visit ✅ Traffic encrypted against public WiFi eavesdropping ✅ Your IP hidden from destination servers ✅ DNS queries protected (if configured correctly) ❌ No protection against cookie/session tracking ❌ No protection against browser fingerprinting ❌ No protection while authenticated in any app or service ❌ No protection from the VPN provider themselves The tool solves a specific set of network-layer problems. For application-layer privacy, you need application-layer solutions — content blocking, session isolation, fingerprint-resistant browsers. If you’re setting up a VPN for a team or personal setup and want the technical layer done properly: WireGuard, verified DNS routing, kill switch enabled, and DNS leak tested before you trust it. Everything else is marketing. Consumer version — what this means for people who don’t want to touch iptables: lucas8.com/what-vpn-actually-protects

0 views
Back to Blog

Related posts

Read more »

The spec is in the wrong place

My day job is at a large tech company. Hundreds of engineering teams, and every one of them is somewhere different on AI adoption. Some are still treating codin...

The Heuristics Say Don't

A culture that only records its disasters ends up with a biased archive. Wars documented, plagues chronicled, collapses catalogued. The quiet decades go unwritt...