You do not need a real account to find out whether a kill switch holds; that is exactly what a test puts at risk. The check creates a short window where traffic may or may not leave outside the tunnel, so the payload should be something you can lose. I run this now with a decoy page and a spare browser profile, and it gives a clearer answer than the browser-plus-webmail routine I used before. What follows walks the same order the client presents: the setting, the destination, the transition, then the evidence.

The test answers one narrow question: during this transition, can this application reach the network outside the tunnel? It says nothing about whether the rest of the policy is sensible. Keep the scope that small and the result is worth writing down.

Find the switch and its scope in the client

Open the client and locate the blocking setting before you change any network state. Vendors name it differently: kill switch, lockdown mode, network lock, block traffic outside the tunnel. The label tells you less than the options inside it. What matters is whether the block applies always, or only when the app decides a tunnel has just failed, and whether it covers every application or a selected list.

Then list the transitions your client can actually perform. A user-initiated disconnect, quitting the app and losing contact with the server are three different code paths in most clients, and they do not share one blocking policy. Some release the block when the app exits. Others leave filter rules installed until something removes them. Read the vendor's settings reference for the build you run instead of assuming, then write down which of the three you are testing.

Record the profile as well: protocol, address families, and whether split tunnelling is enabled. A whole-device claim is meaningless if the profile deliberately excludes a few applications, and an exclusion you configured is not a leak. OpenVPN Connect's settings reference is the kind of page that names which toggle changes which behaviour, though the labels differ per client.

Pick a decoy destination that also works without the tunnel

The decoy needs two properties, and skipping either one produces an unreadable result. It must be reachable directly when the tunnel is down and the block is off, or "it stopped answering" could simply mean the host is gone. And it must not need a login, a cookie or a payment, so a leak costs you a log line instead of a session.

A static page on a host you control is the clean choice. A spare virtual machine running a plain HTTP server is nearly as good, and a public connectivity-check page works if you accept that its availability is outside your control. Note the address, the port, the address family and whether the request needs a name lookup, because each of those becomes a variable you may have to isolate later.

Establish the baseline before touching the switch. With the tunnel up, the decoy must answer through the tunnel, which proves the policy route works. With the tunnel down and the block off, it must answer directly, which proves the destination is alive. Only then does a failure in the blocked state tell you anything.

Run the transitions in a fixed order

Take the transitions one at a time and give each a few seconds to settle, because clients often tear down and rebuild rules in that gap. Running the same short check every time keeps the observations comparable:

curl -sS -o /dev/null -w 'http=%{http_code}\n' --max-time 5 http://decoy.example/
echo "curl_exit=$?"
dig +short decoy.example
curl -6 -sS -o /dev/null -w 'v6_http=%{http_code}\n' --max-time 5 http://decoy.example/
echo "curl_v6_exit=$?"
TransitionExpected with the block onFailure signature
Manual disconnectDecoy stops answering within secondsDecoy still returns 200
Server or path failureBlocked, with no exemption for the old endpointDirect access during the gap
Quit the appClient-dependent; record what happensBlock disappears with the process
Wi-Fi to EthernetBlock holds until the tunnel returnsTraffic flows mid-change

The quit-the-app row deserves its own run even if you never close the client in normal use. If the block releases on exit, a crash or a forced update hands you the same exposure, and that is a fact about the deployment, not about your patience. On Windows the equivalent probes are Resolve-DnsName decoy.example and curl.exe -s -o NUL -w "%{http_code}" http://decoy.example/.

Separate a block from a broken resolver

A page that fails to load has several causes, and only one of them is the switch working. If the name does not resolve, you have learned that DNS is blocked or broken, not that the data path is blocked. Probe a literal address as well, so the answer does not depend on resolution at all.

curl's exit codes keep those cases apart: 6 is a name-resolution failure, 7 means the connection was refused, 28 is a timeout. A blocked route usually shows up as a timeout or a refusal against a literal address. A DNS-only block leaves 6 behind and hides everything else. A cached page or a captive portal fools the eye, which is why the exit code, not the screen, is the evidence.

Repeat the probe over IPv6 with a literal address. A block that covers IPv4 and ignores IPv6 is common enough to deserve its own line in your notes, and a client that disables IPv6 outside the tunnel should fail cleanly on both families.

Record the scope the result covers

When the tunnel is back, confirm recovery: the decoy answers through the tunnel, the resolver returns answers, and the policy sits where you left it. Then undo the experiments. A temporary firewall rule, a debug route or a test profile left in place will confuse the next run and can outlive the app.

A single pass covers one client build, one profile, one transition and one address family. Write those four down with the outcome:

  • Client build and platform, and whether the setting is per-profile or global.
  • Profile, protocol, and any split-tunnel exclusions.
  • Transition tested, and how you triggered it.
  • Address families and DNS, with curl exit codes for the blocked and unblocked states.

If any line is blank, the test is not finished. Roaming means repeating the network-change row. An unattended reboot means checking that the rules come back, which is a question about restore order rather than about the switch. Re-run the sequence after a client update, because the toggles rarely change while the behaviour behind them does. Keep the decoy around: nothing to rotate, and the next check takes five minutes.

ХӀокхунах тера йаззамаш