Active Probing and Why a Server Must Stay Silent Consistently

Passive analysis only flags a suspicious address; then the censor connects itself. What gives away a server that simply does not answer, and why silence has to be consistent.

2026-08-31 GIGATAP Team #vpn
#vpn#anticensorship#probing#opsec#shadowsocks

Active Probing and Why a Server Must Stay Silent Consistently

Discussions of camouflage usually centre on the passive observer: what it sees in passing traffic. But there is a second half of the problem that tends to come up later. A censor need not stop at watching: it can connect to the server itself and tell it apart from an ordinary web server by the manner of refusal alone.

The two-stage scheme#

Fully analysing every connection is expensive. So a cheap two-stage scheme is used instead.

1. PASSIVE: cheap features on the stream
   entropy, first packet lengths, absence of markers
        │
        ▼ the address is flagged as suspicious
        │
2. ACTIVE: separate infrastructure connects on its own
   sends prepared requests, watches the response
        │
        ▼
   distinctive response? ──► address goes on the blocklist

The first stage filters out almost everything and runs on the stream. The second is expensive but applies to a small share of addresses.

Research on the blocking of Shadowsocks described this in detail: suspicion arose from the length and entropy of the first data packet, after which probes of several types were sent to the address — from thousands of different source addresses.

Why is the naive defence not enough?#

The obvious answer is not to answer a bad request. Close the connection, send nothing. That is insufficient, because what is distinguishable is not only response content but the way the connection closes.

That is insufficient, and the reason is subtle.

Work presented at NDSS in 2020 showed that several systems specifically designed against probing were still distinguishable — not by response content but by the network stack’s behaviour when closing the connection. TCP flags and close timings supplied enough to tell them apart from each other and from ordinary services.

In other words: a server that stays correctly silent at the application layer gives itself away by how it stays silent.

What the probe compares Why it distinguishes
How long before the connection closed the timeout is a characteristic implementation constant
Which flags it closed with RST versus FIN — stacks differ
How many bytes arrived before closing reveals how far the parser read
Whether it is identical across garbage types the difference is itself a trait

Three requirements#

Concrete rules follow, and all three appear in the specifications of mature protocols.

Keep reading on error. Do not terminate the connection at the moment bad authentication is detected; keep reading. Terminating at a characteristic moment is a signal in itself.

Close consistently. Identical flags and timings for any malformed input. The difference between “wrong password” and “garbage” must not be observable.

Do not reveal how much was read. The Shadowsocks 2022 specification explicitly requires that close behaviour not disclose the number of bytes the parser consumed — otherwise a byte-at-a-time probe finds the length of a secret prefix by binary search.

BAD — a length oracle
probe: 1 byte of garbage    → immediate RST
probe: 16 bytes of garbage  → immediate RST
probe: 32 bytes of garbage  → 3 s pause, then FIN  ← the parser got here
                                                     prefix length found

GOOD — behaviour independent of input
probe: any garbage          → identical behaviour, identical timing

Replay resistance#

A separate vector: a captured handshake from a legitimate user is a ready-made probe.

A censor can replay a recorded exchange and see whether the server answers the same way. Observations show replays arriving both immediately and weeks later.

Hence the requirement on a replay filter: it checks both a nonce and a timestamp. Time alone will not catch an immediate replay. A nonce alone will not survive a server restart.

A related subtlety about clocks: a strict time tolerance defends against replay better but makes the server fragile to clock drift. Protocols that allow an hour of skew compensate with a separate cache — that is, they apply both mechanisms together rather than choosing between them.

The fallback path: your own site or somebody else’s#

TLS camouflage has a fork that affects probe resistance.

Scheme What answers the probe Risk
Your own site behind the same address your web server, behaviour under your control you need a working site
A borrowed third-party site their server, behaviour outside your control a change in their policy moves you to a grey list

The second option depends on a third party. Observations of Iranian infrastructure describe a grey list keyed on “the server did not answer as expected” — and whether a borrowed site answers is not yours to control.

A practical criterion when picking a camouflage target: does it answer an arbitrary client stably and predictably. A single check proves nothing here; you need a series.

What to check on your own side#

A short list, verifiable in one sitting:

Whether behaviour is identical across kinds of bad input. Empty request, random bytes, truncated handshake, valid prefix with a wrong ending.

Whether behaviour matches a reference web server. Compare not “does it answer” but the distribution: codes, close flags, delays.

Whether the replay filter survives a restart. An in-memory cache is cleared on restart — and the replay window opens.

Whether the camouflage target is stable. A series of requests, not one.

Conclusion#

Probing is the second half of the camouflage problem, and it is about the server rather than the traffic.

The key formulation is short: absence of an answer is also an answer. A server that stays silent in a characteristic way is no less distinguishable than one that answers with a characteristic banner.

The goal is not to be silent, but to be silent the way something ordinary is silent — and identically to everything that is not a legitimate client.

Terms#

  • Active probing - a censor connecting to a server directly to determine what runs on it.
  • Length oracle - a difference in close behaviour that reveals how many bytes the parser consumed.
  • Replay filter - a mechanism that rejects the replay of a previously recorded handshake.

FAQ#

Is simply not answering enough?#

No. Close timings and TCP flags are distinguishable, so a server gives itself away by how exactly it stays silent.

Why does a replay filter need both a timestamp and a nonce?#

Time alone will not catch an immediate replay; a nonce alone will not survive a server restart.

Your own site or a borrowed one as the fallback?#

Your own. A third party’s behaviour is outside your control, and a change in their policy moves you to a grey list.

Further reading#