Skip to content
iplogs.com

Comparing VPN Detection Methods: Exit Lists, Probing, and Browser Signals

By T Hussain · · 9 min read

Five ways to detect a VPN, scored on scalability, freshness and false positives: exit-node lists, DPI, flow-based ML, browser self-checks and active probing.

Ask five people how to detect a VPN and you get five different answers, because there are five genuinely different families of method, and each one trades accuracy against scale in a different place. This post scores each family against four criteria that actually matter in production, then ends with the architecture that comes out on top: not one method, but several layered under a weighted score.

Four questions to score a method on

  • Does it work on a cold lookup? Most VPN-detection calls are for an IP a service has never seen before, with no traffic or browser access to that visitor. A method that only works once you already have packets or a page load in hand is useless for that call, however good it is.
  • How fast does it go stale? VPN exit IPs rotate. Mullvad reshuffles relays; consumer-ISP leases change hands. A list refreshed once a quarter is already wrong for a meaningful slice of it on day one.
  • What does a false positive cost? Blocking a real customer is usually worse than letting one VPN user through, so a method that trades recall for a lower false-positive rate is winning, not losing.
  • Does it scale past a handful of providers? There are a few thousand VPN and proxy apps on the app stores today, most of them white-labelled onto a handful of backend SDKs. A method that needs bespoke work per provider does not reach that long tail.

Method 1 — Exit-node enumeration

Connect to every server a provider offers, record the exit IP, repeat on a schedule. It is the oldest method and, for the servers it covers, the most accurate: a fresh list produces close to zero false positives, because you are not inferring anything, you are reading a fact back.

The weakness is coverage and freshness at scale. Connecting to every region of every provider by hand does not reach very far past the five or six brands everyone has heard of, and a cron job that reconnects once a day is already behind a provider that rotates relays hourly. IPLogs pulls this data a different way where possible: directly from each provider's own infrastructure API — Mullvad's relay JSON, PIA's server list, IVPN's gateway list, AirVPN's status endpoint — refreshed every 6–12 hours, plus the X4BNet community aggregator for the providers that auth-wall their own API. A registry of per-app collectors extends that to several hundred white-labelled apps sharing a handful of backend SDKs, published as open datasets under CC-BY.

Scores: cold lookup — yes. Staleness — depends entirely on refresh interval; hours, not months. False positives — close to zero on a fresh list. Scale — good once the per-provider work is automated, but it only ever covers infrastructure someone has already catalogued. A brand-new server on an unlisted IP is invisible to this method until the next person adds it.

Method 2 — Deep packet inspection

A VPN tunnel changes what the IP and TCP headers look like: MTU gets smaller to leave room for the outer encapsulation, MSS values stop matching the client's claimed OS, and OpenVPN over UDP has its own header shape. Diffing a tcpdump capture against a known-clean baseline surfaces these reliably.

The catch is the first criterion above: this method needs the actual packets of the connection, which means standing in the path — an ISP, a firewall, or the server the traffic is destined for. A third-party service answering "is 1.2.3.4 a VPN" cold has no packets to inspect; it never sees that visitor's connection to anyone. So DPI is a real and useful technique, just not one a detection API can apply to an arbitrary IP it is asked about.

Scores:cold lookup — no, by definition. Staleness — low, header behavior doesn't rot the way a list does. False positives — moderate; vendors can and do normalize these values. Scale — fine once you're in the path, but that is a big precondition.

Method 3 — Flow-based timing analysis

Instead of header bytes, train a model on the statistical shape of a flow: packet sizes, inter-arrival timing, the small extra latency a VPN hop adds. Published results report accuracy above 95% on research datasets.

It inherits DPI's core limitation — no live traffic, no flow to analyze — and adds its own: labeled training data is expensive to collect and goes stale as providers change, and the output is a probability that some traffic looks tunneled, not which provider it is or whether a specific IP is a VPN server right now.

Scores: cold lookup — no. Staleness — the model drifts as provider behavior changes; needs retraining. False positives — the published numbers look good, but transfer to traffic unlike the training set is the usual failure mode. Scale — poor; this is an ISP or network-operator tool, not a lookup API.

Method 4 — Browser-side self-checks

There is one case where a third party does get traffic-adjacent access on a cold IP: a first-party page the visitor loads themselves. Run a script in that page and you can read things the network alone can't — the browser's timezone and language against the IP's geolocation, a WebRTC leak of the real local address, or which DNS resolver actually answered a lookup.

IPLogs runs this as a self-check flow: the page resolves a per-visit token through dl.iplogs.comand the API's own IPv4/IPv6-only hosts, and compares the resolver and network that answered against the visitor's own IP. A resolver sitting on a different network, in a different country, from a hosting address fires dns_leak or dual_stack_leak; an Apple user agent arriving over a non-Apple TCP stack fires resip_client_mismatch. None of this works for a cold lookup of someone else's IP — it only works because the visitor's own browser is running the check.

Scores: cold lookup — no, first-party only. Staleness — not applicable, it runs live every time. False positives — low when gated correctly (mobile carriers and satellite links need their own exceptions). Scale — excellent for the first-party case, zero reach beyond it.

Method 5 — Active probing

The one family most write-ups skip: instead of asking what a provider published, or what the visitor's browser reports, ask the suspect server directly. Send an OpenVPN HARD_RESET to UDP/1194, a WireGuard handshake-initiation to UDP/51820, an IKEv2 SA_INIT to UDP/500, a SOCKS5 greeting, an HTTP CONNECT. A real VPN or proxy server answers in its protocol's own shape; an ordinary host drops the packet or sends a RST.

This inverts exit-node enumeration's weak point. A list only catches infrastructure someone has already catalogued; a probe tests what the IP actually does, right now, regardless of whether it is on anyone's list yet. It needs no live traffic from the client being looked up and works on a cold lookup of any address, which is why it is worth the engineering cost of running probes safely and at a rate that does not look like an attack.

Scores:cold lookup — yes. Staleness — low; it measures the server's current behavior, not a published snapshot. False positives — needs care (some corporate gateways and CDN edges answer oddly) but is high-confidence when it hits. Scale — good; one probe set per protocol covers every server on that protocol, listed or not.

No single method wins — layering does

Line the five up and a pattern falls out: exit lists and active probing both work cold and both age well, but each has a recall gap the other fills — lists miss unlisted infrastructure, probes miss anything that doesn't answer a protocol handshake (a tunnel running entirely over HTTPS, say). DPI and flow analysis need traffic access most detection services never get. Browser self-checks are the strongest signal available, but only for the one visitor running the check.

The architecture that falls out of scoring it this way is aweightedone, not a single best method: refreshed exit lists and aggregator feeds for known infrastructure, active probing to catch what isn't listed yet, RTT-timing checks (see the SNITCH paper, NDSS 2025) to catch tunnels that pass every protocol probe, and browser self-checks layered on top for the first-party case — with network-level evidence capped so it can never alone reach a "detected" verdict. The six-layer version of this is written up in how VPN detection actually works, and the measured result of combining them is on the accuracy page: 0.4% false positives and zero misses against a 1,043-IP ground-truth set, 100% on a 500-server Mullvad sample and 100% on Tor. No method on this list gets there alone.