Does Your VPN Actually Protect You? Leak Tests, Kill Switch, and DNS
A VPN is a promise about a network path that almost nobody re-checks after the first week: client updates, router changes, a split-tunnel rule or an OS upgrade can all quietly alter it. Here is a protocol you can run and repeat identically, and what passing does not prove.
The short version
Test three states, not one: baseline (VPN off), connected, and after a forced disconnect. Record results with the endpoint name and date, so a later run is comparable.
Six checks cover the common failures: the address a site sees, which resolver answered, IPv6, WebRTC, the kill switch, and split tunnelling.
None of this makes you anonymous: a VPN moves trust from your ISP and local network to your provider, and it does not hide you from a site you log into.
What a VPN is defending
Every check below needs a threat model: a VPN protects the path between your device and the exit server, so a local observer cannot read your traffic in cleartext, and the destination sees the exit server's address rather than yours. Anonymity is not the claim — the provider terminates your traffic, your ISP can see that you connected, and any account you sign into identifies you whatever address it came from.
Set the baseline
Note four things with the VPN off, because without them the connected results mean nothing: the public IPv4 and IPv6 addresses a test site reports; the DNS servers the OS uses; whether the browser resolves names itself or through a network DNS filter (see the DNS-level blocking guide); and the exit address you expect.
# Windows
ipconfig /all
nslookup example.com
# macOS
scutil --dns | head -40
# Linux
resolvectl status
dig example.com Check 1: the address sites actually see
Connect, then reload the test page — a page opened before connecting keeps reporting the old answer. Use an endpoint that reports IPv4 and IPv6 together, so partial coverage cannot look like full coverage; ipleak.net shows the address a request arrived with, not a geolocation guess.
| Result | Reading |
|---|---|
| Exit address only | Tunnel carries this traffic |
| Exit plus baseline address | Something bypassed the tunnel — check split tunnelling, IPv6 |
| Exit address, wrong location | Wrong exit, or stale geolocation data |
| Baseline address only | Not connected, or this app is outside the tunnel |
Retest in a second browser and a non-browser application: some clients tunnel only certain traffic by default.
Check 2: DNS, which is two questions
The first is which resolver answers. If queries still go to your ISP's resolver, it learns every name you look up even though the content is tunnelled. Confirm the resolver in your baseline output changed to one the client provides.
The second is which path the query takes:
- A browser using DNS over HTTPS may resolve through a third-party resolver, bypassing whatever the VPN configured — check the browser's own setting first.
- A network DNS filter installed on the system may take queries first, so the answer you see came through a path neither product controls.
Check 3: IPv6
A tunnel is frequently IPv4-only while the interface keeps a routable IPv6 address, and systems generally prefer IPv6 when it is available: unhandled, that traffic leaves the physical interface and the destination records your true address. Ask an IPv6-aware endpoint for its view while connected:
- No IPv6 reported. Usually correct for an IPv4-only tunnel: you lose IPv6-only services and gain no leak.
- An IPv6 address belonging to the exit. The client handles it deliberately.
- Your baseline IPv6 address. Fix this first: if the client's documentation does not say how it handles IPv6, disable IPv6 on the interface or use a client that does.
Check 4: WebRTC
WebRTC is a browser API for peer connections (the specification is public at the W3C); establishing one gathers candidate interface addresses, so a scripted page can read things about your local network that plain requests never exposed. Read results carefully, because "leak" is used loosely here:
- A private address such as
192.168.x.xtells the page about your LAN layout, not your public location; browsers often mask it with anmDNSname. - A public address matching your baseline is the one to act on: a candidate came from the physical interface.
- An address matching the tunnel exit is expected.
Behaviour differs by browser and version, so test yours and retest after updates. Restricting WebRTC can break conferencing tools, so decide case by case.
Check 5: the kill switch, tested honestly
Pressing "disconnect" inside the client is the weak test: a graceful disconnect lets the client tear down its own block. Do this instead, with something long-running in progress:
- Start a sustained transfer, such as a large download.
- Force the tunnel to drop without the client's cooperation: unplug the upstream link, disable the physical adapter, or block the VPN protocol at the router.
- Read the outcome. Good: traffic stops and resumes only when the tunnel returns. Bad: the transfer continues, or a new connection succeeds over the physical interface.
- Restore the link and confirm the client reconnects rather than leaving you silently unprotected.
- Test persistence: reboot with the switch enabled and check it is still armed, then re-check after a client update.
Find out whether the switch is application-level or a genuine system firewall rule; that decides what survives a client crash. Browsers with their own DNS settings, and updater services, do not always respect the default block.
Check 6: split tunnelling, the leak you configured
Split tunnelling is a hole by design, so test what it excludes. With "allow local network" on, traffic to private ranges leaves through the physical interface — intended, but those destinations can see you. Check each excluded application from the exit point of view, not the client's status text: an excluded browser shows your real address. Look for rules you did not write, such as update services or captive-portal handling. After removing a rule, flush caches, restart the application and re-test — stale routes produce both false passes and false failures.
What passing cannot show
- Provider behaviour. Nothing you run locally shows whether a provider keeps logs or honours its policy. Treat "no logs" as a contractual statement.
- Exit reputation. A clean tunnel leaving from a shared address can still be blocked, rate-limited, or flagged.
- Malware, accounts, and correlation. The tunnel carries traffic and does not vet it; a positioned observer can compare timing without reading contents.
- Endpoint quality. Results depend on which endpoint and browser you used. Two disagreeing is normal — record which said what.
Do not quote or invent leak percentages: there is no honest figure, since it depends on client version, platform, protocol and configuration.
A record you can repeat
| Field | Baseline | Connected | After forced drop |
|---|---|---|---|
| Public IPv4 seen | |||
| IPv6 seen / resolver that answered | |||
| Long transfer outcome | n/a | n/a | |
| Client version, OS build, endpoint, date | |||
If you are still choosing a service, protocol support and kill-switch behaviour are among the differences that matter — see ExpressVPN vs NordVPN, NordVPN vs Surfshark, and our VPN service picks. Router-level setups move the tunnel to another device, so some of these checks belong on the router; the VPN router roundup covers that case.
Frequently asked questions
Does passing every leak test mean I am anonymous?
No. It means the tunnel behaves as claimed on your device. Your provider still terminates your traffic, sites still identify your session and anything you submit, and your ISP still sees that you connected to a VPN.
WebRTC showed a 192.168 address. Is that a leak?
It discloses a private interface address to the page — a privacy nuisance, not exposure of your public location, and browsers often mask it behind mDNS. The result to act on is a public address matching your baseline.
IPv6 is unavailable while connected. Should I fix it?
Usually that is the safe outcome of an IPv4-only tunnel, at the cost of IPv6-only services. The case to fix is a routable IPv6 address that still exists alongside the tunnel.
How often should I re-test?
After every client, OS, router, protocol or configuration change and every new network, plus a monthly pass on the quick checks.