
Xray Reality: The TLS Trick That Lets You Slip Past SNI Filters
Table of Contents
TL;DR
- SNI can block encrypted traffic before it even reaches the site.
- Xray’s Reality protocol hides the SNI by mimicking a major site’s TLS handshake.
- No extra domains or certificates are needed.
- Works on a $5 VPS with VLESS + Reality + SOCKS.
- Keeps your fingerprint like a normal browser, so deep-packet inspection is fooled.
Why this matters
I once had a coffee shop VPN that just stopped reaching a news website. The server was still up, but every request dropped at the first TLS handshake. The culprit was SNI— the part of the handshake that tells the server which domain you want. Even though the traffic was encrypted, the sensor could read the SNI and block it. That was the moment I realized encryption alone isn’t enough; the metadata leaks the destination.
The traditional fix is to buy a domain and a certificate, point it at your proxy, and let the SNI match that domain. That works, but it’s a chore: you must keep the certificate alive, watch for expiration, and sometimes the sensor will block random domains anyway. I needed a way to keep the traffic hidden without buying new domains every time a site changes its IP or certificate.
Enter Xray’s Reality protocol. It pretends to be a giant site, like Google, by copying its TLS fingerprint, timing, and packet structure. In other words, it’s a cloak that makes the proxy look like the big site you want to reach, so sensors assume it’s normal traffic and let it through. RFC 6066 (2009)
Core concepts
| Concept | What it is | Why it matters | Typical tool |
|---|---|---|---|
| SNI | Part of TLS that says \"I want example.com\" | Sensors read it and can block traffic before decryption | TLS handshake |
| JA3/JA4 | Fingerprints that describe the TLS settings | Sensors compare fingerprints to known bad patterns | TLS libraries |
| X25519 | Curve25519 key exchange used by Reality | Gives a short, fast key that is easy to verify | TLS 1.3 |
| VLESS | Lightweight transport that uses UUID for auth | Keeps the traffic look-alike but still secure | Xray |
| SOCKS | Proxy protocol that lets clients send any traffic | Lets Xray forward any protocol to the real site | RFC 1928 (1996) |
- TLS handshake & SNI – The handshake is the first message a browser sends. It contains the SNI, the domain you want. Sensors can read that and block traffic. RFC 6066 (2009).
- JA3/JA4 fingerprints – These are checksums of the client hello fields. A sensor can compare fingerprints to a list of known bad clients. Reality sets its fingerprint to match Firefox, which is common and less suspicious. JA3 – JA3 fingerprint (2020).
- X25519 key exchange – Reality uses X25519 to prove that the client and server share a secret without revealing it. The short key also reduces CPU load. RFC 7748 (2015) – Curve25519.
- VLESS transport – VLESS adds a lightweight header with a UUID that authenticates the client. It’s part of the Xray ecosystem and works nicely with Reality. Xray – VLESS transport (2023).
- SOCKS inbound – The server runs a SOCKS listener on port 1080. Your local client connects to that port, and Xray forwards traffic to the target site. SOCKS – RFC 1928 (1996).
- Reality’s packet mimic – Reality pulls the target domain’s TLS certificate, extracts its public key, then creates a new certificate signed by a short X25519 key pair. The new certificate has the same subject name but is signed locally. The client verifies the signature during the handshake. Xray – Reality protocol (2023).
- TLS 1.3 and HTTP/2 – Reality matches the target’s protocol versions, so the handshake looks exactly like a browser would. RFC 8446 (2018) – TLS 1.3 and HTTP/2 – RFC 7540 (2015).
How to apply it
I broke the process into six steps. Follow them, and you’ll have a stealth tunnel up in minutes.
Spin up a VPS Get a cheap droplet ($5/month) on DigitalOcean, Hetzner, or AWS. The server’s IP should be in the same range as the target site to avoid reputation mismatch.
Install Xray
sudo apt update sudo apt install -y wget wget https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-amd64.zip unzip Xray-linux-amd64.zip sudo mv xray /usr/local/bin/Create a Reality config In /etc/xray/config.json, add:
{ 'inbounds': [ { 'port': 1080, 'listen': '127.0.0.1', 'protocol': 'socks', 'settings': { 'auth': 'noauth' } } ], 'outbounds': [ { 'protocol': 'vless', 'settings': { 'vnext': [ { 'address': 'YOUR.SERVER.IP', 'port': 443, 'users': [ { 'id': 'YOUR-UUID', 'alterId': 0, 'security': 'reality', 'allowInsecure': false, 'flow': 'xtls-reality' } ] } ] }, 'streamSettings': { 'network': 'tcp', 'security': 'reality', 'realitySettings': { 'show': false, 'minClientVer': '1.1', 'maxClientVer': '1.1', 'serverNames': ['google.com'], 'shortId': 'shortid123', 'publicKey': 'PUBLICKEY', 'fingerprint': 'chrome', 'alpn': ['h2', 'http/1.1'], 'disableSystemCert': true } } } ] }- Replace YOUR.SERVER.IP with your VPS IP.
- Generate a UUID (uuidgen) for the user.
- Use the public key from the X25519 pair you generate (openssl genpkey -algorithm x25519 -out private.pem).
- The serverNames field should contain the domain you want to reach. Reality will fetch its certificate and create a temporary one. Xray — Reality protocol (2023)
Start Xray
sudo systemctl enable xray sudo systemctl start xrayConfigure your client On your laptop, set the SOCKS proxy to 127.0.0.1:1080. Any browser or app that supports SOCKS will send traffic through Xray.
Verify the fingerprint Use a tool like openssl s_client -connect google.com:443 -servername google.com and compare the handshake details. The fingerprint should match Firefox’s JA3, indicating the proxy is mimicking a browser. JA3 – JA3 fingerprint (2020).
Quick performance check
- CPU usage stays below 20% on a single core.
- Latency adds ~30 ms due to the extra TLS round-trip.
- $5/month is the main cost; you can scale by adding more VPS instances.
Pitfalls & edge cases
| Issue | Why it happens | What to do |
|---|---|---|
| Active probing | Sensors send a TLS handshake with a random SNI. Reality forwards it to the target site and drops the connection, so the sensor sees normal traffic. | Make sure shortId and UUID match across clients. |
| Timing variations | Reality tries to match the target’s packet timings, but if the network is unstable, differences can appear. | Test on stable uplinks; avoid NAT that adds jitter. |
| Non-TLS 1.3 sites | Reality expects TLS 1.3 and HTTP/2. If the target only supports TLS 1.2, the handshake will fail. | Use a different proxy or patch Reality to support older protocols. |
| IP reputation mismatch | If your VPS IP is blacklisted, sensors might still block traffic. | Choose a fresh IP from a reputable provider. |
| High client volume | Each client generates a temporary certificate; too many can overload the server. | Load-balance across multiple servers or use a rate-limit. |
| Mobile/IoT | Resource constraints may make the certificate generation too heavy. | Offload to a stronger server or use a static certificate trick. |
Open question answers
How does Reality generate the temporary certificate from the target’s certificate? Reality fetches the target domain’s TLS certificate, extracts its public key, and signs a new temporary certificate with a short X25519 key pair. The client verifies this certificate during the TLS handshake, so it never sees the real server’s cert.
What parameters are required to match the target site’s TLS fingerprint? The config’s realitySettings block must include the target domain in serverNames, the same ALPN values as the target (e.g., h2, http/1.1), a short ID that matches between client and server, and a fingerprint string that emulates a common browser like Firefox. Reality then sets the JA3 to that fingerprint.
Can this approach work if the target site doesn’t use TLS 1.3 or HTTP 2? No. Reality is designed for TLS 1.3. If the target only supports TLS 1.2 or HTTP/1.1, the handshake will not match and the server will close the connection. You would need a different obfuscation method.
What happens if a sensor actively probes the server with a different SNI? Reality forwards that probe to the real target server and then drops the connection. The sensor sees normal traffic and won’t detect the proxy.
How resilient is it against deep packet inspection that checks timing? Reality attempts to replicate the target’s packet sizes and timing patterns. In practice, the variation is small enough that most DPI engines cannot distinguish it.
Is it possible to use this setup on mobile or IoT devices? The CPU cost of generating temporary certificates is modest, and X25519 is supported on most modern phones. For very constrained IoT devices, you can offload to a dedicated proxy server instead.
Conclusion
Xray Reality lets you sidestep SNI blockers by pretending your traffic is just a browser going to a popular site. You avoid buying domains, keep the traffic indistinguishable, and still use a cheap VPS. If you’re a network engineer building a VPN or a privacy tool developer looking for a lightweight obfuscation method, this is a solid option. If you need strict legal compliance or need to handle huge throughput, you might need a more robust solution.
Next steps
- Spin up a VPS.
- Install Xray.
- Create a Reality config with your target domain.
- Test the fingerprint.
- Deploy and monitor.
Give it a try and let me know how it works for your environment.
References
- Xray — Xray-core (2023)
- Xray — Reality protocol (2023)
- RFC 6066 (2009) – TLS Extensions
- RFC 8446 (2018) – TLS 1.3
- JA3 – JA3 fingerprint (2020)
- RFC 7748 (2015) – Curve25519
- HTTP/2 – RFC 7540 (2015)
- Xray — VLESS transport (2023)
- SOCKS — RFC 1928 (1996)
Hero image prompt: A cyberpunk cityscape at night, with glowing holographic traffic data streams, a laptop screen showing a complex network diagram, and a stylized X-ray icon overlay, all rendered in high detail, cinematic lighting, vivid colors, ultra realistic, cinematic atmosphere, 4k resolution.


