Contents

Choosing an SNI

The hostname you present in the ClientHello is the single most load-bearing string in your config — and different SNIs get wildly different treatment.

REALITY and plain TLS both send the hostname you’re “visiting” in the clear, inside the ClientHello’s Server Name Indication. That one string is what most SNI-based censorship actually keys on — so which name you put in serverName / serverNames decides whether your connection is blocked, throttled, or waved through, independent of everything else in your config. This page is about choosing it well; the complementary lever — hiding or splitting the SNI so it can’t be read at all — lives in finalmask & fragment and TLS & uTLS.

transport/internet/reality/config.go transport/internet/tls/config.go

The SNI has to be a site you can actually borrow

For REALITY the SNI is not decorative — the server relays unauthenticated handshakes to dest, so the name in serverNames must be a real TLS 1.3 site that behaves the way its certificate claims. A good borrow target is a foreign domain that speaks TLS 1.3 and HTTP/2, is not behind a CDN you don’t control, is not already on the local blocklist, and ideally is hosted close to your server so the latency of the borrowed handshake matches your server’s location.

{
	"realitySettings": {
		"dest": "example.com:443",
		"serverNames": ["example.com"],
		"fingerprint": "chrome"
	}
}
Same connection, three fates — the censor branches on the SNI before it inspects anything else

China: a domestic SNI is a liability, not a disguise

Under the GFW, pointing REALITY at a domestic Chinese hostname is discouraged — not because the name is magic, but because a China-branded SNI arriving at a foreign IP is an obvious mismatch, and many popular domestic sites are CDN-fronted or otherwise fragile to borrow. The reliable choice is a foreign site with TLS 1.3 + H2, not on the blocklist, hosted near your VPS.

Russia: some SNIs are effectively exempt from the TSPU

Russia’s TSPU inspects the opening of a TLS connection and, if it can’t place the SNI on a permitted list, throttles the flow to a crawl after roughly the first 16 KB (about the first dozen data packets) — but connections to certain critical-infrastructure names are left alone. Domains like microsoft.com and other services the state can’t afford to break are, in practice, “freed” from that early throttle, so a handshake presenting such an SNI survives where an arbitrary foreign name gets choked.

That makes SNI selection a real anti-throttle lever in Russia: an exempt borrow target can walk past the 16 KB block that a random domain trips. It is also a moving target — exemptions are added and removed — so pair it with fragmentation (finalmask & fragment) rather than betting everything on one lucky name.

Don't

Grab a famous domain at random

Using a heavily-blocked or CDN-fronted giant (or a domestic name from your own country) invites either an SNI/IP mismatch or borrowing a site whose handshake you can’t actually relay cleanly.

Do

Pick for the local filter's blind spot

In Russia, favor an SNI the TSPU won’t throttle (a critical-service name). Under the GFW, favor a clean foreign TLS 1.3 + H2 site near your server. Match the borrow to the local rule.

When the SNI itself must disappear

If even presenting any fixed SNI is risky, stop sending it in the clear. Encrypted Client Hello (ECH) seals the real SNI inside an outer “cover” name so the censor can’t read it at all, and fragment’s tlshello mode splits whatever SNI you do send across TLS records so a stateless matcher can’t reassemble it. These stack with a good name choice — they are the layer you add when name selection alone stops being enough. See TLS & uTLS for ECH and finalmask & fragment for fragmentation.