DEV Community

Cover image for I Fingerprinted 6 Commercial VPNs in 200ms with Open-Source DPI. Here's the Wireshark Data
Evilork
Evilork

Posted on

I Fingerprinted 6 Commercial VPNs in 200ms with Open-Source DPI. Here's the Wireshark Data

TL;DR: Modern DPI engines like nDPI detect OpenVPN/WireGuard traffic in under 200ms with 97% accuracy. I tested 6 commercial VPNs. 5 leaked their protocol immediately. Here’s exactly how, with packet captures.

The Problem Nobody Talks About

When you read “best VPN” articles, they all talk about the same things: speed, server count, no-logs policy, kill switch.

Nobody talks about whether your ISP can see that you’re using a VPN at all.

This matters more than you think:

  • Crypto exchanges (Binance, OKX, Bybit) flag VPN IPs and require additional KYC, sometimes locking funds
  • Payment processors (Stripe, Adyen) decline transactions from known VPN ranges
  • State-level DPI in Russia/Iran/China actively profiles VPN users for further monitoring
  • Anti-fraud systems at banks treat your account as high-risk

If your VPN protocol is detectable - and 95% are - you’re not anonymous, you’re flagged.

The Test Setup

Hardware: Mac M4 Max + remote VPS for traffic mirroring.

Tools:

  • Wireshark for capture
  • nDPI (the same library powering most ISP-grade DPI hardware)
  • tshark for automated parsing
# Capture VPN handshake
sudo tshark -i en0 -w vpn_handshake.pcap -a duration:30

# Run through nDPI
ndpiReader -i vpn_handshake.pcap -v 2 | grep -E "VPN|Detected"

# Measure time-to-detection
ndpiReader -i vpn_handshake.pcap -j output.json
jq '.flows[] | {proto: .detected_protocol_name, ms: .first_seen_ms}' output.json
Enter fullscreen mode Exit fullscreen mode

I tested each VPN on default settings (what 95% of users use), then ran their “stealth mode” if available.

The Results

Provider Default Protocol Time to Detect Stealth Mode TTD with Stealth
Provider A (mainstream, top-3 by revenue) OpenVPN 180ms Obfuscated 720ms
Provider B (mainstream) WireGuard 90ms None n/a
Provider C (privacy-focused) IKEv2 250ms None n/a
Provider D (mainstream) OpenVPN+XOR 420ms XOR scramble 420ms (no improvement)
Provider E (Asia-focused) Shadowsocks (legacy) 1,100ms None n/a
Provider F (indie, self-hosted) VLESS Reality NOT DETECTED n/a n/a

5 out of 6 leaked their VPN signature in under 1.5 seconds.

The one that didn’t is running VLESS+Reality, a protocol from the XRay project that’s been around since 2023 but mainstream VPNs refuse to adopt.

What Actually Gets Detected

Here’s a sanitized snippet from the nDPI output for Provider B (WireGuard):

{
  "flow_id": 42,
  "src_ip": "10.0.0.5",
  "dst_ip": "[redacted]",
  "detected_protocol": "WireGuard",
  "protocol_category": "VPN",
  "confidence": "DPI",
  "first_seen_ms": 90,
  "fingerprint": {
    "udp_payload_first_byte": "0x01",
    "packet_size_pattern": [148, 92, 92],
    "handshake_signature": "wg_initiation"
  }
}
Enter fullscreen mode Exit fullscreen mode

WireGuard’s first packet ALWAYS starts with 0x01 followed by a fixed-size payload. There is no way to disguise this without modifying the protocol itself - and if you modify it, it’s no longer WireGuard.

This is the dirty secret of “modern” VPN protocols: they were designed for performance and security against passive eavesdroppers, NOT against active traffic analysis.

Why VLESS+Reality Wins

Reality doesn’t try to hide that you’re using a VPN. It doesn’t even try to obfuscate the traffic.

It does something smarter: it pretends to be a real TLS connection to a real high-traffic website.

Client → "Hi server.com, I want to connect"  
Server → [forwards initial handshake to actual server.com]
         [returns real TLS certificate from server.com]
Client → [verifies it's the real server.com]
         [now switches to VPN tunnel under the same connection]
Enter fullscreen mode Exit fullscreen mode

To DPI, this looks 100% identical to:

  • A user visiting microsoft.com
  • A user visiting cloudflare.com
  • A user visiting any whitelisted destination

JA3 fingerprint matches Chrome. SNI matches a real CDN. Certificate is real. There’s literally nothing to detect.

The Code

If you want to test your own VPN, here’s a minimal script:

import subprocess
import json
import sys

def test_vpn_fingerprint(interface: str = "en0", duration: int = 30) -> dict:
    """Capture and analyze VPN traffic for protocol fingerprinting."""
    pcap_file = "/tmp/vpn_test.pcap"
    json_file = "/tmp/vpn_test.json"

    # Capture traffic
    subprocess.run([
        "sudo", "tshark", "-i", interface,
        "-w", pcap_file, "-a", f"duration:{duration}"
    ], check=True)

    # Analyze with nDPI
    subprocess.run([
        "ndpiReader", "-i", pcap_file, "-j", json_file
    ], check=True)

    with open(json_file) as f:
        data = json.load(f)

    vpn_flows = [
        flow for flow in data.get("flows", [])
        if "VPN" in flow.get("detected_protocol_name", "")
        or flow.get("detected_protocol_name") in [
            "WireGuard", "OpenVPN", "IPSec", "L2TP"
        ]
    ]

    if vpn_flows:
        print(f"⚠️  VPN detected in {vpn_flows[0]['first_seen_ms']}ms")
        print(f"    Protocol: {vpn_flows[0]['detected_protocol_name']}")
        return {"detected": True, "details": vpn_flows[0]}

    print("✅ No VPN signature detected in capture window")
    return {"detected": False}

if __name__ == "__main__":
    result = test_vpn_fingerprint()
    sys.exit(0 if not result["detected"] else 1)
Enter fullscreen mode Exit fullscreen mode

Run this with your VPN connected. If you get the warning - your VPN is detectable.

Install requirements:

# macOS
brew install wireshark ndpi

# Ubuntu  
sudo apt install tshark ndpi-utils
Enter fullscreen mode Exit fullscreen mode

What This Means for You as a Developer

If you’re building anything that requires real network privacy:

  1. Don’t trust a VPN provider’s marketing. Test it.
  2. Self-host with VLESS+Reality if you can. The 3X-UI panel makes it a 10-minute setup.
  3. If you must use commercial, look for providers explicitly running Reality/Hysteria2/SS-2022. They exist but they’re small.
  4. Consider what you’re protecting against. If it’s your ISP seeing what site you visit - any VPN works. If it’s your IP getting profiled - you need DPI-resistant protocols.

The Bigger Picture

The VPN industry is stuck in 2018. They’re optimizing for speed and “no-logs policies” while the threat model has completely shifted.

State actors and large corporations don’t need to read your traffic. They just need to know you’re using a VPN. That alone is enough to:

  • Add you to a watchlist
  • Trigger anti-fraud at your bank
  • Lock your exchange account
  • Profile you for further investigation

The protocol matters more than the provider. Stop paying $10/month for legacy protocols dressed up in nice apps.

Discussion

I’d love to see results from other devs running this script on their VPNs. Drop a comment with:

  • Provider name (or anonymized “Provider X”)
  • Default protocol
  • Time-to-detection in ms

Bonus points if you find a mainstream provider that survives DPI. I haven’t found one.


Code is MIT-licensed, do whatever you want with it. If you reproduce these tests on more providers, I’d love to see a write-up.

Top comments (1)

Collapse
 
evilork profile image
Evilork

Disclaimer for transparency: I'm building a small VPN service on Reality myself (proxysvpn.com). Numbers in the post are real and reproducible - methodology stands regardless of which provider you choose. AmneziaVPN, several Outline forks, and a few other indie projects pass the same test. Point of the post is the protocol, not any specific brand