[{"data":1,"prerenderedAt":65},["ShallowReactive",2],{"blog-post-xhttp-for-vless-what-it-is-why-it-exists-and-how-to-use-it":3},{"id":4,"meta":5,"title":21,"author":22,"body":26,"introduction":58,"date":59,"tags":60,"category":63,"blog_image":64,"intro":58,"featured":10},1201,{"type":6,"detail_url":7,"html_url":8,"slug":9,"show_in_menus":10,"seo_title":11,"search_description":11,"first_published_at":12,"alias_of":13,"parent":14},"blog.BlogPage","https:\u002F\u002Fwww.staging.doprax.rocks\u002Fd\u002Fapi\u002Fv2\u002Fpages\u002F1201\u002F","https:\u002F\u002Fwww.staging.doprax.rocks\u002Fd\u002Fdoprax-blogs\u002Fxhttp-for-vless-what-it-is-why-it-exists-and-how-to-use-it\u002F","xhttp-for-vless-what-it-is-why-it-exists-and-how-to-use-it",false,"","2026-04-22T10:09:08.514933Z",null,{"id":15,"meta":16,"title":20},109,{"type":17,"detail_url":18,"html_url":19},"blog.BlogIndexPage","https:\u002F\u002Fwww.staging.doprax.rocks\u002Fd\u002Fapi\u002Fv2\u002Fpages\u002F109\u002F","https:\u002F\u002Fwww.staging.doprax.rocks\u002Fd\u002Fdoprax-blogs\u002F","Doprax Blogs","XHTTP for VLESS: What It Is, Why It Exists, and How to Use It",{"id":23,"username":24,"full_name":25},5,"Swetlana","Swetlana A",[27,34,40,46,52],{"type":28,"value":29,"id":33},"section",{"title":30,"content":31,"subsections":32},"A Bit of Background","\u003Cp data-block-key=\"j7wzl\">The classic way to use VLESS (or similar proxy protocols, including those paired with XTLS-Reality) is straightforward: the client opens a direct connection to a proxy server running on a VPS somewhere. That worked fine for years.\u003C\u002Fp>\u003Cp data-block-key=\"94gs8\">Then things changed. In several countries — Russia being the most visible example — censors began blocking or throttling entire IP ranges belonging to well-known hosting providers. Elsewhere, detection systems started flagging single IP addresses that receive unusually high traffic volumes. Direct connections stopped being reliable.\u003C\u002Fp>\u003Cp data-block-key=\"f0dl5\">The obvious workaround was to route proxy traffic through a CDN. Most implementations used the WebSocket transport. But WebSocket-over-CDN has two real problems:\u003C\u002Fp>\u003Cul>\u003Cli data-block-key=\"8it41\">It has a recognizable signature (we won't spell it out here — no need to make DPI operators' jobs easier).\u003C\u002Fli>\u003Cli data-block-key=\"6cqko\">Only a limited set of CDNs actually support WebSocket proxying, and you'd rather not be restricted to that short list.\u003C\u002Fli>\u003C\u002Ful>\u003Cp data-block-key=\"4d37t\">The Tor project hit this problem first and invented the \u003Cb>meek\u003C\u002Fb> transport for its bridges. Meek tunnels data through long sequences of ordinary HTTP request\u002Fresponse pairs, which means it works through essentially any CDN. The briefly revived V2Ray project adopted meek as well.\u003C\u002Fp>\u003Cp data-block-key=\"frub2\">Meek solves the CDN compatibility problem but introduces two new ones baked into its design:\u003C\u002Fp>\u003Cul>\u003Cli data-block-key=\"d0j21\">\u003Cb>It's slow.\u003C\u002Fb> The request\u002Fresponse model is effectively half-duplex, and the constant round-trips add enormous overhead.\u003C\u002Fli>\u003Cli data-block-key=\"d8ei9\">\u003Cb>It's expensive.\u003C\u002Fb> The flood of GET\u002FPOST requests per second gets you kicked off free CDN tiers quickly, and on paid tiers it generates painful invoices.\u003C\u002Fli>\u003C\u002Ful>\u003Cp data-block-key=\"ejk5f\">The XRay team looked at meek and asked a good question: what if you split sending and receiving onto two separate connections? That idea became the \u003Cb>SplitTunnel\u003C\u002Fb> transport, which evolved into what we now call \u003Cb>XHTTP\u003C\u002Fb>.\u003C\u002Fp>",[],"0d6f8007-eb4a-4951-beeb-35e4c239325b",{"type":28,"value":35,"id":39},{"title":36,"content":37,"subsections":38},"Two Things to Clear Up First","\u003Cp data-block-key=\"j7wzl\">Before going further, two clarifications that save a lot of confusion:\u003C\u002Fp>\u003Cp data-block-key=\"eii1o\">\u003Cb>XHTTP is a transport, not a protocol.\u003C\u002Fb> It's typically paired with VLESS, but in principle it could carry other protocols too.\u003C\u002Fp>\u003Cp data-block-key=\"26gv5\">\u003Cb>XHTTP was designed for CDN use, but it doesn't require a CDN.\u003C\u002Fb> You can absolutely use it for direct client-to-server connections, and doing so still brings real advantages.\u003C\u002Fp>\u003Ch2 data-block-key=\"bi7bo\">The Three Modes\u003C\u002Fh2>\u003Cp data-block-key=\"8rc3i\">XHTTP operates in one of three modes. The choice determines both performance and compatibility.\u003C\u002Fp>\u003Ch3 data-block-key=\"bctgh\">1. packet-up\u003C\u002Fh3>\u003Cp data-block-key=\"epnvg\">The slowest of the three — but still dramatically faster than meek — and also the most compatible. It works with almost any web server or CDN.\u003C\u002Fp>\u003Cp data-block-key=\"8suij\">Under the hood: one connection carries server-to-client traffic, while client-to-server traffic is split across many short-lived connections.\u003C\u002Fp>\u003Cp data-block-key=\"3o38v\">A note on terminology: when we say \"connection\" here, we don't strictly mean a TCP connection. We mean an HTTP request\u002Fresponse session. Many of these sessions can share a single TCP connection. But in all cases, the TCP connections used for inbound and outbound traffic will be different.\u003C\u002Fp>\u003Ch3 data-block-key=\"8g63g\">2. stream-up\u003C\u002Fh3>\u003Cp data-block-key=\"e2c3i\">Faster than packet-up, but more picky about what it runs through. Only works with certain web servers (or ones specifically configured for it).\u003C\u002Fp>\u003Cp data-block-key=\"cgo8v\">Uses one long-lived connection for client→server traffic and another long-lived connection for server→client traffic.\u003C\u002Fp>\u003Ch3 data-block-key=\"9i1rm\">3. stream-one\u003C\u002Fh3>\u003Cp data-block-key=\"d5e8c\">The odd one out. This is the only mode that doesn't split inbound and outbound traffic — both directions share a single connection. Functionally, it's close to plain VLESS with an HTTP header (XRay used to have exactly that transport).\u003C\u002Fp>\u003Cp data-block-key=\"12qi6\">Stream-one only passes through Nginx with the grpc_pass directive, or through Cloudflare with the gRPC feature enabled. Worth noting: gRPC isn't actually being used here. It's just a decoy — a shape that makes Nginx and Cloudflare leave the traffic alone.\u003C\u002Fp>",[],"2ab3b52d-c334-47bc-acde-5ece2e7b8028",{"type":28,"value":41,"id":45},{"title":42,"content":43,"subsections":44},"Why XHTTP Is Worth the Trouble","\u003Cp data-block-key=\"j7wzl\">Here's what you get by adopting XHTTP.\u003C\u002Fp>\u003Ch3 data-block-key=\"do56\">1. HTTPS or QUIC\u003C\u002Fh3>\u003Cp data-block-key=\"5jrv1\">You can connect to the server over HTTPS as usual, or switch to QUIC by explicitly setting ALPN to h3 on the client. QUIC tends to perform better on flaky networks, and it's a useful escape hatch when HTTPS is blocked but whoever set up the blocking forgot about QUIC.\u003C\u002Fp>\u003Ch3 data-block-key=\"au829\">2. Authentic server fingerprints over TLS 1.2\u003C\u002Fh3>\u003Cp data-block-key=\"268ct\">This one deserves some unpacking.\u003C\u002Fp>\u003Cp data-block-key=\"4lt65\">A TLS \"fingerprint\" is the combination of subtle characteristics in how a server implements TLS — its quirks, its behaviors, the order of things. An XRay server and a real Nginx or Caddy instance leave different fingerprints, and that difference is enough to out a proxy to a sufficiently motivated inspector.\u003C\u002Fp>\u003Cp data-block-key=\"99c3b\">The standard defense is XTLS-Reality in \"steal from yourself\" mode: your proxy masquerades as a real web server that happens to be running on the same host. The catch is that XTLS-Reality requires TLS 1.3 — and censors have been caught blocking TLS 1.3 to popular hosting ranges specifically because of this.\u003C\u002Fp>\u003Cp data-block-key=\"6t2sn\">XHTTP sidesteps this by letting you use TLS 1.2, with a perfectly authentic fingerprint, because a real Nginx is the thing listening on port 443. XRay sits behind it.\u003C\u002Fp>\u003Ch3 data-block-key=\"3oqhl\">3. CDN flexibility (including domain fronting)\u003C\u002Fh3>\u003Cp data-block-key=\"56jml\">XHTTP works through CDNs that don't support WebSocket or gRPC. And because some CDNs still permit domain fronting (MiraclePtr covered this technique in depth on Habr), you can take masquerading further than XTLS-Reality alone allows.\u003C\u002Fp>\u003Cp data-block-key=\"1t4a2\">The picture looks like this: when you connect, you present the SNI of some unrelated popular domain, you get that domain's real certificate back, and you're hitting the actual IP address that domain resolves to — along with thousands of other people in the country who happen to be visiting that site at the same time. You're hiding in a crowd, not pretending to be one person.\u003C\u002Fp>\u003Ch3 data-block-key=\"e82gm\">4. Browser dialer\u003C\u002Fh3>\u003Cp data-block-key=\"u3nq\">This solves the fingerprint problem from the client side. XRay (and similar tools) use the uTLS library to imitate popular browsers' TLS fingerprints, but imitation is never perfect.\u003C\u002Fp>\u003Cp data-block-key=\"16kp4\">With browser dialer, the flow changes: you load a small script in your real browser, and your XRay client routes through that browser instead of connecting directly. The proxy sees a fingerprint and behavior that are indistinguishable from a real browser — because they \u003Ci>are\u003C\u002Fi> a real browser.\u003C\u002Fp>\u003Ch3 data-block-key=\"8eno3\">5. Asymmetric connection paths\u003C\u002Fh3>\u003Cp data-block-key=\"8ia6o\">This is the most interesting one. In packet-up and stream-up modes, your data is already split across separate inbound and outbound connections. That alone makes pattern analysis and TLS-in-TLS detection significantly harder.\u003C\u002Fp>\u003Cp data-block-key=\"dii4g\">But here's the thing: nothing requires those two connections to be identical. XRay lets you configure them independently. Some of what that enables:\u003C\u002Fp>\u003Cul>\u003Cli data-block-key=\"sf8l\">Send outbound over QUIC, receive inbound over HTTPS.\u003C\u002Fli>\u003Cli data-block-key=\"h2fm\">Outbound over IPv6, inbound over IPv4.\u003C\u002Fli>\u003Cli data-block-key=\"fgatm\">Outbound and inbound pointed at different IPv6 addresses.\u003C\u002Fli>\u003Cli data-block-key=\"ain5e\">Two connections going to two entirely different servers, different hosting providers, different countries.\u003C\u002Fli>\u003Cli data-block-key=\"2pq54\">One direction direct, the other through a CDN.\u003C\u002Fli>\u003Cli data-block-key=\"851hd\">Different domains for each direction.\u003C\u002Fli>\u003C\u002Ful>\u003Cp data-block-key=\"4qecf\">Mix and match as creatively as you want. Every variation you add makes analysis and blocking more expensive for whoever is watching.\u003C\u002Fp>",[],"ef043821-efda-4b07-868a-85dc3e42a80e",{"type":28,"value":47,"id":51},{"title":48,"content":49,"subsections":50},"Points Worth Knowing","\u003Cp data-block-key=\"j7wzl\">A handful of technical details that will save you time:\u003C\u002Fp>\u003Cul>\u003Cli data-block-key=\"abvh4\">\u003Cb>XMUX\u003C\u002Fb> — a new multiplexing algorithm — ships alongside XHTTP. Nothing revolutionary, but nothing tricky either. The GitHub write-up covers it adequately if you run it through an auto-translator.\u003C\u002Fli>\u003Cli data-block-key=\"eb0dc\">\u003Cb>XHTTP is not compatible with XTLS-Vision.\u003C\u002Fb> Protection against TLS-in-TLS detection comes from the multiplexing (XMUX) and the inbound\u002Foutbound splitting instead.\u003C\u002Fli>\u003Cli data-block-key=\"6dnai\">\u003Cb>XHTTP does work with XTLS-Reality.\u003C\u002Fb> When you combine them, stream-one mode is selected by default unless you override it.\u003C\u002Fli>\u003Cli data-block-key=\"3825t\">\u003Cb>XHTTP is under active development.\u003C\u002Fb> Keep the XRay versions on the client and server matched. Version mismatches produce weird, hard-to-debug failures or plain silence.\u003C\u002Fli>\u003Cli data-block-key=\"e887\">\u003Cb>Sing-box-based clients don't support XHTTP.\u003C\u002Fb> XRay-based clients do. v2rayN and v2rayNG both handle it without issue.\u003C\u002Fli>\u003Cli data-block-key=\"9o6t0\">\u003Cb>Example configurations\u003C\u002Fb> for XHTTP with XRay client, server, and Nginx live in the \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FXTLS\u002FXray-examples\u002Ftree\u002Fmain\u002FVLESS-XHTTP3-Nginx\">xray-examples repository\u003C\u002Fa>.\u003C\u002Fli>\u003C\u002Ful>",[],"2229a2f7-5983-4d6b-b7a8-b1a8b3fc7f01",{"type":28,"value":53,"id":57},{"title":54,"content":55,"subsections":56},"The Bigger Picture","\u003Cp data-block-key=\"j7wzl\">A closing thought worth taking seriously.\u003C\u002Fp>\u003Cp data-block-key=\"f4dir\">Over the past year, censorship systems have been losing ground on the protocol-detection front. Spotting traffic by indirect signals or deep statistical analysis is possible, but it requires both budget and expertise. The money may be there; the expertise less so. In response, censors have shifted to blunter measures with heavier collateral damage: blocking HTTPS to popular hosting providers wholesale, blocking TLS 1.3 to those ranges, blocking entire CDNs, blocking anything they can't identify, throttling SSH connections after a certain data threshold, and temporarily (from fifteen minutes to several days) tightening restrictions on individual subscribers whose traffic tripped some DPI heuristic.\u003C\u002Fp>\u003Cp data-block-key=\"bfki2\">The implication is that the next generation of circumvention probably shouldn't be about inventing ever-cleverer protocols and masking techniques. It should be about exploiting the weaknesses of the blocking mechanisms themselves — making them progressively more expensive to operate and progressively harder to maintain.\u003C\u002Fp>\u003Cp data-block-key=\"4k0u3\">One concrete example: domestic traffic usually isn't filtered in most of these systems. Which suggests a layout where the first hop from the client is a cheap in-country VPS — reached however you like, even with an old Shadowsocks config, or with Reality masquerading as a local website — and from there the traffic continues to the real proxy abroad.\u003C\u002Fp>\u003Cp data-block-key=\"9kema\">And if a hosting provider starts running DPI of its own and causing problems, the reverse-proxy\u002Fbridge\u002Fportal patterns that MiraclePtr has written about come into play, because return traffic typically isn't filtered either, and filtering it would cost orders of magnitude more compute.\u003C\u002Fp>\u003Cp data-block-key=\"38nkb\">One more hint while we're on the topic of CDNs: they don't have to be foreign ones. Think about it.\u003C\u002Fp>\u003Cp data-block-key=\"17tr6\">\u003C\u002Fp>\u003Cp data-block-key=\"dl28r\">\u003Ci>PS: Deploying a VLESS + XHTTP setup on a fresh VM? Doprax ProVM instances give you clean IPs, 1 Gbps ports, unlimited traffic, and European locations with low latency to the regions that need this kind of setup most. Spin one up in under a minute and you're ready to configure.\u003C\u002Fi>\u003C\u002Fp>",[],"0e6a17c1-f7f8-4fad-a9de-efdf964baddb","\u003Cp data-block-key=\"r6x6i\">XHTTP keeps coming up in conversations about XRay, VLESS, and modern proxy setups — usually without much of an explanation. Official documentation is thin. The one GitHub discussion that covers it is written in a style that's hard to parse if you're not already deep in the ecosystem, and the machine translations floating around don't help. So here's a clean, practical overview.\u003C\u002Fp>","2026-04-02",[61,62],"vless","xhttp","updates","\u002Fd\u002Fmedia\u002Foriginal_images\u002Fdoprax_xhttp_vless.png",1792480193189]