GFW Technical Review 11 – Advanced TLS Evasion
Trojan and the TLS-based evasion family raised the bar for censorship circumvention – by hiding proxy traffic inside genuine TLS sessions, they made protocol-level detection effectively impossible. But the GFW adapted. Statistical fingerprinting – TLS ClientHello analysis, certificate inspection, TLS-over-TLS timing patterns, behavioural profiling – gave the censor new tools to distinguish proxy-carrying TLS from ordinary HTTPS, even without breaking encryption or identifying a custom protocol.
Each of these fingerprinting techniques exploits a specific gap between what a proxy’s TLS connection looks like and what a real browser-to-website connection looks like. The next generation of evasion tools takes a targeted approach: identify each gap and close it individually. NaïveProxy tackles the TLS fingerprint problem by using a real browser’s network stack. XTLS addresses the TLS-over-TLS performance and fingerprinting issue by splicing encrypted streams. And REALITY eliminates the certificate and domain problem entirely by borrowing credentials from real, high-profile servers.
Together, these tools represent the current state of the art in circumvention – and the closest anyone has come to making proxy traffic truly indistinguishable from legitimate HTTPS.
NaïveProxy: Become the Real Browser
TLS fingerprinting is one of the GFW’s most effective tools against TLS-based proxies. Every TLS implementation produces a subtly different ClientHello. Browsers like Chrome and Firefox produce well-known fingerprints; Go’s crypto/tls, used by Trojan, V2Ray, and most other circumvention tools, produces a distinctly different one.
The uTLS library addressed this by allowing Go applications to spoof their ClientHello to mimic a browser. But mimicry is inherently fragile. Chrome updates its TLS behaviour with every release – new cipher suites, new extension orderings, new GREASE values. Each update changes the fingerprint, and uTLS must be updated to match. If the mimicry falls behind, the fingerprint no longer matches any real browser in the wild and the connection becomes identifiable. Worse, the mimicry is only skin-deep: uTLS can fake the ClientHello, but subsequent TLS behaviour may still betray the underlying Go stack.
NaïveProxy’s insight was to abandon mimicry entirely: instead of faking a Chrome fingerprint, use Chrome’s actual code.
Architecture
NaïveProxy is built on top of Chromium’s network stack. Specifically, it directly uses the source code of Chromium’s net library, which handles TLS, HTTP, certificate verification, and connection management. The result is that a NaïveProxy connection is, at the TLS level, byte-for-byte identical to a Chrome connection – because it is a Chrome connection, produced by the same code.
The proxy mechanism uses standard HTTP semantics. The local application establishes a SOCKS5 or HTTP connection with the NaïveProxy client, which then forwards the request by issuing an HTTP/2 CONNECT request to the destination through Chromium’s net stack. This is not a custom protocol – CONNECT tunnelling is a standard part of HTTP that enterprise forward proxies have used for decades. The server authenticates the client via HTTP Basic Authentication, carried inside the encrypted TLS tunnel.
NaïveProxy does not need a custom server-side implementation because it relies on standard HTTP semantics. Any web server with forward proxy capability can do the job. A common setup simply runs a Caddy instance with a forward proxy plugin, a real certificate, and a reverse proxy to fall back unauthenticated traffic to a real website.
Trade-offs
NaïveProxy offers a near-perfect solution to TLS fingerprinting – you cannot be more real than Chromium itself. But it leaves a few problems unaddressed and comes with some additional costs:
- TLS-over-TLS. NaïveProxy still uses an outer TLS channel for all payload, meaning any TLS connections going through the channel create the double-encryption problem. It mitigates this by adding random padding bytes to the first eight frames in each direction to obscure length-based fingerprinting.
- Performance. Like Trojan, a NaïveProxy connection incurs one or two additional round trips (depending on TLS version) from its handshake. As an optimisation, subsequent connections after the first reuse the HTTP/2 session via H2 Fast Open to avoid the RTT cost – but this creates back-to-back H2 packets consistently, a pattern that is not very common in normal browsing.
- Complexity. NaïveProxy pulls upstream Chromium C++ source code directly into its repository and makes minor modifications. This dependency makes both the code itself and the build process complicated, and significantly limits portability – especially to mobile platforms.
XTLS: Become the Real TLS
Traditional TLS-based proxies have the double-layer TLS problem. When the user browses HTTPS websites, the payload gets encrypted twice – once by the inner layer between browser and website, and again by the outer layer between proxy client and server. This is both a performance issue and a potential fingerprinting surface.
XTLS addresses this by eliminating the outer-layer encryption for already-encrypted payload. During the inner TLS handshake phase, XTLS behaves like a normal TLS proxy – the outer TLS layer encrypts everything, including the inner handshake messages, to hide the inner SNI. But once the inner handshake completes and the connection transitions to the Application Data phase, the data flowing through the proxy is already encrypted by the inner TLS session. At this point, XTLS performs what it calls a “splice” – it stops encrypting the inner data with the outer TLS layer and instead passes the inner TLS records through directly.
XTLS has gone through multiple iterations by its author, RPRX, due to fingerprinting issues in earlier versions. The latest iteration is named Vision. XTLS/Vision is purely a transport-layer concept – it does not handle any proxy functionality itself. It is therefore used in combination with VLESS, which provides the proxy logic. RPRX also forked V2Ray into Xray, integrating XTLS/Vision into the Xray ecosystem.
The main benefit of XTLS is performance: eliminating the redundant encryption layer roughly halves the cryptographic overhead for bulk data transfer. From a traffic fingerprinting perspective, the inner TLS handshake still occurs inside the outer TLS layer, so XTLS/Vision still needs to add padding bytes around those initial packets to obscure their characteristic lengths.
REALITY: Become the Real Website
Of all the fingerprinting vectors, the certificate and domain problem is perhaps the most fundamental. Every TLS-based proxy before REALITY required the operator to:
- Register a domain name
- Obtain a TLS certificate for that domain
- Host a fallback website to make the domain look legitimate
This process is not only cumbersome but also leaves traces. As discussed in Post 10, the GFW not only checks the server’s TLS fingerprint but also examines the SNI and certificate, cross-referencing public registries to detect suspicious domains. No amount of protocol-level perfection can overcome this problem. REALITY eliminates it entirely by removing the need for your own domain and certificate.
Certificate Masquerading
REALITY – also created by RPRX and implemented in Xray-core – takes a fundamentally different approach to TLS authentication. Instead of presenting its own certificate, the proxy server borrows the certificate of an entirely unrelated, legitimate server. The operator configures REALITY with a target – the “dest” server – such as www.microsoft.com or www.apple.com, any major website with a strong reputation.
Here is what happens when a client connects:
From the GFW’s perspective, the connection looks like a standard TLS handshake with www.microsoft.com. The SNI in the ClientHello says microsoft.com. The certificate returned is Microsoft’s genuine certificate. The TLS fingerprint matches a real browser. There is nothing to distinguish this from a legitimate visit to Microsoft’s website.
What actually happens is more nuanced. When the REALITY server receives a ClientHello, it initiates its own TLS connection to the real microsoft.com and relays the genuine ServerHello and certificate back to the client. But the server does not simply proxy the entire TLS handshake – that would make it a transparent man-in-the-middle, unable to read the encrypted tunnel. Instead, the REALITY protocol uses a separate authentication mechanism based on short-lived keys.
The client and server share a pre-configured key pair and a set of “short IDs.” During the TLS handshake, the client embeds authentication material into the Session ID field – a field that is essentially unused in TLS 1.3 and whose contents appear random to an outside observer. The server relays this ClientHello to the dest server (microsoft.com) and completes a TLS handshake with it. Simultaneously, it validates the embedded material to confirm the client is authorised. If validation fails – for instance, if the GFW sends an active probe – the server simply relays the dest server’s responses in full, so the prober sees nothing but the Microsoft website.
If validation succeeds, the server completes a TLS handshake with the client directly by generating a self-signed certificate on the fly. To minimise fingerprintable characteristics, the server replicates the dest server’s TLS patterns – ServerHello content, cipher spec, and other negotiation parameters – but replaces Microsoft’s certificate with its own, establishing a TLS session for the proxy. Crucially, the server certificate is encrypted in TLS 1.3, so the GFW cannot tell whether the certificate belongs to Microsoft or to the proxy.
Three Birds with One Stone
REALITY solves three longstanding problems of TLS-based proxies in a single design:
- Server fingerprint. REALITY always presents the dest server’s handshake response back to the client, eliminating ServerHello fingerprints entirely.
- Certificate and domain registration. REALITY uses the dest server’s domain and certificate as a disguise while relying on a self-signed certificate underneath. This eliminates the need to register or purchase a domain and certificate, and – more importantly – prevents domain name analysis.
- Active probing. Any unauthenticated probe sees the dest server directly. There is no need to set up a fallback web server the way Trojan requires.
The Looming Risk
REALITY is both operationally simpler and more resistant to the GFW’s analysis than its predecessors. Its only additional requirement is TLS 1.3, which has become common enough to be unremarkable. However, there is a potential risk: the misalignment of IP addresses and domains.
REALITY can borrow someone else’s domain name, but it cannot borrow their IP address. This creates an analysis surface for the GFW. Imagine the GFW observes thousands of connections from Chinese IP addresses to a particular VPS IP, all with SNI microsoft.com, but the VPS IP does not belong to Microsoft’s known IP ranges. The GFW could cross-reference the destination IP with the SNI’s expected IP ranges and flag the mismatch. This would be a strong signal for the use of REALITY. To date, the GFW has not demonstrated this capability at scale, but the risk is real and well understood in the community.
The Modern Evasion Stack
The success of XTLS and REALITY has rallied the community around the Xray ecosystem. The current state-of-the-art evasion stack typically comprises Xray-core, uTLS, VLESS, XTLS/Vision, REALITY, and TLS 1.3.
On the client side, Xray with uTLS produces a Chrome TLS fingerprint. NaïveProxy is theoretically superior for fingerprint authenticity, but it is not integrated with the Xray ecosystem. The proxy layer uses VLESS for its simplicity, and the XTLS/Vision transport provides padding and splice optimisation. With REALITY, the TLS handshake is performed under the identity of a major website. The server validates the REALITY authentication and additionally performs VLESS UUID authentication, then establishes the TLS channel – which is ultimately spliced by XTLS/Vision to eliminate double-layer encryption for the bulk data flow.
This modern stack eliminates most protocol-level fingerprints. The GFW’s traditional TLS fingerprinting methods no longer work against it. However, the behavioural and contextual signals remain. No transport-layer protocol improvement can address the fundamental issue of IP address reputation. That is not a problem protocol designers can solve – it is something operators must account for.
Closing Thoughts
The development of circumvention technologies has been closely coupled with the evolution of security protocols on the broader internet. As the internet moves more of its infrastructure under encryption, the balance tilts against the GFW. The widespread adoption of HTTPS and TLS made TLS-based evasion tools possible. The evolution of TLS 1.3 – with its encrypted certificates and streamlined handshake – made REALITY possible. In recent years, the rise of HTTP/3 and QUIC has opened a new frontier for the circumvention community. Hysteria, a QUIC-based protocol, has emerged as the next chapter in this ongoing arms race.
References
- klzgrad. naiveproxy. https://github.com/klzgrad/naiveproxy
- XTLS. Xray-core. https://github.com/xtls/xray-core
- XTLS. REALITY. https://github.com/XTLS/REALITY
Enjoy Reading This Article?
Here are some more articles you might like to read next: