Replies: 1 comment 1 reply
-
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
Xray-core already ships the
fragmentsetting in thefreedomoutbound (packets: "tlshello"), which has been invaluable for bypassing SNI-based DPI filters. Thank you to the maintainers for that feature — it saved a lot of users for a long time.However, in the past months Iran's national DPI has adapted. The classic TCP-segment fragmentation that
fragmentproduces is now reassembled by the DPI before inspection, so the SNI becomes visible again and blocked SNIs (e.g.*.cloudfront.net,*.cloudflare.com, various others) get the connection RST'd or silently stalled after Server Hello.Field observation (Iran, 2026-04 — reproduced on MCI, Irancell, MobinNet (mobile) and Shatel, MKH (fixed-line)):
curldirect: TLS handshake to*.cloudfront.netRSTs after Server Hello.Xray-core with:
Same RST / stall behavior. DPI is no longer fooled by TCP-layer fragmentation.
Dedicated external spoofing tools (
patterniha/SNI-Spoofing,aleskxyz/SNI-Spoofing-Go,therealaleph/sni-spoofing-rust) successfully bypass the block using techniquesfragmentdoes not implement.What the external tools do that
fragmentdoes notseq_num) — the most effective technique against current Iranian DPI. After the TCP 3-way handshake completes, a fully-valid fake ClientHello is injected as a raw packet carrying an allowed SNI, but withseq_num = syn_seq + 1 - len(payload), which falls outside the server's receive window. The DPI reads the fake SNI and whitelists the flow; the server's TCP stack silently discards the packet (out-of-window); the real ClientHello follows immediately on the correct sequence and is processed normally. Requires raw-socket / kernel-hook packet injection (WinDivert on Windows,NFQUEUEon Linux,pfdivert on BSD/macOS).letsencrypt.org). The DPI consumes it; the real ClientHello follows on the same TCP stream. Weaker than technique number 1 because some DPIs parse both ClientHellos and still match on the second, but works in pure userspace without raw sockets.IP_TTLsetsockopt).Why this belongs in Xray-core
fragmentsetting already established the precedent that anti-censorship primitives belong in-core.127.0.0.1.Proposed config schema
Extend the existing
fragment(or add a siblingsniSpoofblock) onstreamSettings.sockoptso it's available to all outbounds (VLESS, VMess, Trojan, etc.), not onlyfreedom:{ "streamSettings": { "sockopt": { "sniSpoof": { "mode": "seqInject", "fakeSni": "letsencrypt.org", "ttl": 4, "recordSize": "30-60", "delay": "5-15" } } } }Field reference:
mode"seqInject"|"fakeHello"|"tlsRecord"|"ttl"|"disorder"fakeSniseqInject,fakeHello,ttlttlttlrecordSizetlsRecorddelayseqInject,fakeHello,ttlmodeis a single value for now; combinations can be added later. Defaults chosen so the block is a drop-in replacement for the existingfreedom.fragmentuse case.Scope proposal (incremental PRs)
streamSettings.sockopt(all outbounds)IP_TTLsetsockopt / raw socket permissionseq_num)NFQUEUE(Linux) /pfdivert (BSD/macOS) — build-tag gatedPRs 1–3 are pure userspace Go and should land without elevated privileges. PRs 4–6 require raw-socket / kernel-hook packet injection and should be gated behind a build tag so the default binary stays dependency-free. Among these, PR number 6 is the most impactful against current Iranian DPI, based on field testing of external tools implementing this exact technique.
References
proxy/freedom/freedom.gofragment implementation.Ask
fragment(add amodefield) vs. a new siblingsniSpoofblock?Happy to submit PR number 1 (TLS record fragmentation) first as a proof of concept if there's interest. A reference implementation of PR number 6 (TCP sequence injection) already exists as a standalone Windows proxy using WinDivert and could be ported to an Xray transport wrapper.
Beta Was this translation helpful? Give feedback.
All reactions