XHTTP: Beyond REALITY #4113
Replies: 30 comments 76 replies
-
先顶再看,不明觉厉 |
Beta Was this translation helpful? Give feedback.
-
中文 | РусскийXHTTP: За гранью REALITYКраткое описание разработки: В середине 2024 года, @mmmray @ll11l1lIllIl1lll и другие, основываясь на принципе "раздельная пакетная отправка, потоковая загрузка" и деталях реализации, описанных @RPRX, разработали SplitHTTP, впервые добившись обхода большинства промежуточных устройств, поддерживающих HTTP, без ущерба для эффективности загрузки, и впервые массово реализовали QUIC H3 через CDN, открыв новую эру. Впоследствии были реализованы: Broswer Dialer, добавление отступов в заголовки для уменьшения сигнатуры (header padding), управление мультиплексированием (XMUX) и разблокировка REALITY. Затем разработку взял на себя @RPRX, реализовав настоящее разделение исходящего и входящего трафика и переименовав проект в XHTTP. Например, исходящий и входящий трафик могут быть IPv6 CDN H3 и IPv4 REALITY H2 соответственно (даже исходные IP-адреса могут различаться), Эта статья призвана помочь вам полностью понять принцип и дизайн XHTTP, чтобы вы могли лучше его использовать. Если вы хотите пожертвовать проекту Xray или собираете NFT, соответствующая информация находится в конце статьи, спасибо за поддержку!Руководство по быстрому стартуНесмотря на большое количество параметров у XHTTP, для них уже настроены значения по умолчанию. Если вы просто хотите использовать XHTTP, достаточно выполнить шесть шагов:
XHTTP по умолчанию использует мультиплексирование, что обеспечивает меньшую задержку по сравнению с Vision, но многопоточное тестирование скорости может показать худшие результаты, если не установить Кроме того, в клиентах v2rayNG есть глобальная настройка mux.cool, которую следует отключить перед использованием XHTTP, иначе не удастся подключиться к серверу Xray новой версии. Эту статью можно использовать как расширенную версию документации, поскольку она охватывает практически всё, что вы хотели бы знать о XHTTP, с объяснением каждого параметра. В конце статьи также приведен пример конфигурации, включающий все параметры с описанием сценариев их использования. Если вам неясен какой-либо параметр, найдите его название в тексте, чтобы найти подробное объяснение. Два базовых принципаТак же, как REALITY может маскироваться под чужой веб-сайт, основная идея противодействия цензуре заключается в увеличении "сопутствующего ущерба" для цензоров при блокировке, что делает их менее склонными к необдуманным действиям. По той же причине я в свое время сделал ставку на TLS и запутывание временных и длиновых характеристик трафика TLS. Многолетний опыт показывает, что GFW не будет постоянно блокировать весь пул IP-адресов крупного CDN, так как это затронет слишком много обычных сайтов. Таким образом, наша первоначальная цель для XHTTP заключалась в том, чтобы скрыть его за множеством различных CDN. Однако, чтобы предотвратить атаки на исходный сервер, CDN, за исключением специально поддерживаемых WS и gRPC, обычно кэшируют весь HTTP-запрос, прежде чем отправить его на исходный сервер. Многие промежуточные HTTP-устройства по умолчанию также работают таким образом. Исходя из этого, протокол Meek от Tor упаковывает исходящий и входящий трафик в отдельные HTTP-запросы для обхода этих промежуточных устройств, но скорость при этом крайне низка, поскольку он не использует "потоковую загрузку" XHTTP. Кстати, о недавно ставшей популярной теме "злоупотребления" CDN: очевидно, что CDN, не поддерживающие потоковую отправку, не предназначены для создания прокси-сервисов. Однако в борьбе с GFW мы считаем разумным и необходимым постоянно исследовать, разрабатывать и использовать как можно больше новых путей. Это вынужденная мера, и увеличение "сопутствующего ущерба" для цензоров требует от нас смешиваться с "нормальными" сервисами, что также неизбежно. Простейший пример: если в один прекрасный день будет введен белый список IP-адресов, и IP-адрес CDN окажется в нем, будете ли вы его использовать? В области антицензуры не действуют некоторые правила реального мира, но этот простой принцип почему-то многие не могут понять. Если вы все еще не понимаете, то такие транспортные уровни, как WebSocket, сейчас существуют только для обхода CDN. Как разработчик, вы можете удалить его, а как пользователь, вы можете предложить разработчику удалить его, чтобы своими действиями доказать, что "злоупотребление CDN" - это не просто очередной предлог для атаки на Xray, вызванный завистью и удовлетворением каких-то болезненных психологических потребностей, PACKET-UPЭтот раздел содержит много технических деталей. Обычные пользователи могут читать только выделенный текст. Для режима packet-up в XHTTP, обеспечивающего наилучшую совместимость ("пакетная отправка, потоковая загрузка"), мы выбрали следующую схему:
Пакетная отправка и Кроме того, как и другие транспортные уровни Xray, сервер принимает заголовок Это упрощенный, необходимый процесс работы режима packet-up. Однако остается небольшой вопрос: как конкретно реализовать и ограничить POST-запросы? Для этого есть три специальных параметра:
"Для одного прокси-запроса" означает, что каждый прокси-запрос считается отдельно и не влияет на другие, даже если они находятся в одном H2/H3 соединении. Это и есть значение sc (sub-connection). Чтобы уменьшить сигнатуру, первые два значения можно задать в виде диапазона, например, "500000-1000000" и "10-50" соответственно, с случайным выбором значения в каждом запросе. Эти параметры можно передать клиенту через H1 / H2 / H3Теперь, когда у нас есть режим packet-up, способный обходить практически все промежуточные HTTP-устройства, давайте обсудим кое-что интересное: QUIC H3 через CDN, то есть ту самую новую эру, которую открыл SplitHTTP. Понимание этого раздела особенно важно для гибкого использования XHTTP. Особенностью многих промежуточных HTTP-устройств, таких как CDN и Nginx, является преобразование версии HTTP. Например, они могут преобразовывать полученный H3-трафик в H1 или H2 при обращении к исходному серверу. Это означает, что наш XHTTP-сервер может прослушивать только H1 и H2, без необходимости прослушивания H3, в то время как клиент XHTTP может использовать H3. Это также поведение XHTTP-сервера по умолчанию: прослушивание только TCP-порта и обработка трафика H1 и H2. При включении TLS и указании только одного элемента "h3" в Для клиента XHTTP:
Если вам нужно узнать фактически используемую версию HTTP, host, а также режим XHTTP, разделение исходящего и входящего трафика и другую информацию на стороне клиента Xray, установите уровень логирования "info". Проксирование QUIC H3 через CDN, по крайней мере, XHTTP был первым, кто реализовал это в массовом масштабе, открыв новый путь, поскольку в некоторых регионах и у некоторых провайдеров цензура H3 не так строга, XMUXПоскольку мы упомянули H2 и H3, нельзя не упомянуть и их мультиплексирование: в обоих случаях это 0-RTT. Разница лишь в том, что у H3 нет проблемы блокировки заголовка TCP, которая есть у H2, и H3 поддерживает миграцию соединения, поэтому при смене сети на клиенте соединение не разрывается.
XMUX предоставляет параметры, которые можно комбинировать различными способами. Например, перед многопоточным тестированием скорости необходимо установить Примечание: отсутствие параметров эквивалентно установке всех значений в ноль, и будут использоваться три значения по умолчанию. Однако, если указан хотя бы один параметр, остальные параметры не будут иметь значений по умолчанию и должны быть указаны явно, за исключением первых двух параметров. Все остальные параметры можно указывать одновременно. Кроме того, при использовании XHTTP не следует включать mux.cool, и новая версия сервера Xray проверяет это, принимая только чистый XUDP. Некоторые выдержки о значениях по умолчанию для XMUX:
Ниже в статье также обсуждаются некоторые параметры Nginx. STREAM-UP/ONEНаконец, мы добрались до другого важного режима XHTTP: stream-up ("потоковая отправка, потоковая загрузка"). Как следует из названия, в этом режиме отправка данных также потоковая, что не снижает ее эффективность. Изначально он был разработан для REALITY, пока мы не обнаружили, что с маскировкой заголовков gRPC под H2 можно обходить CF (необходимо включить поддержку gRPC в панели управления), и обратные прокси-серверы, такие как Nginx, также хорошо его поддерживают (для Nginx рекомендуется
Способы их реализации (обычные пользователи могут пропустить):
Тогда те, кто часто использует gRPC, спросят: какие преимущества у stream-up по сравнению с транспортным уровнем gRPC?
Конечно, преимущества XHTTP по сравнению с WebSocket и HTTPUpgrade, помимо "отсутствия явной сигнатуры ALPN как http/1.1", вы, дочитав до этого места, уже наверняка поняли сами, поэтому я не буду их перечислять, Разделение исходящего и входящего трафикаИ, наконец, кульминация - еще одна новая эра: разделение исходящего и входящего трафика. Мы знаем, что сейчас GFW обнаруживает такие характеристики трафика, как TLS in TLS, основываясь на одном соединении. Таким образом, если мы разделим исходящий и входящий трафик на разные системы проверки, например, исходящий трафик будет идти через IPv4 TCP, а входящий - через IPv6 UDP, GFW не сможет сразу среагировать. А поскольку сервер XHTTP связывает исходящий и входящий трафик только на основе случайно сгенерированного UUID в пути, packet-up и stream-up изначально обладают возможностью настоящего разделения трафика, и благодаря тому, что XHTTP может проходить через различные CDN и использоваться с REALITY, существует бесконечное количество вариантов. На клиенте необходимо настроить "xhttpSettings": {
"host": "example.com",
"path": "/yourpath", // должно совпадать
"mode": "auto",
"extra": {
"headers": {
// "key": "value"
},
"xPaddingBytes": "100-1000",
"noGRPCHeader": false, // stream-up/one, только клиент
"noSSEHeader": false, // только сервер
"scMaxEachPostBytes": 1000000, // только packet-up
"scMinPostsIntervalMs": 30, // packet-up, только клиент
"scMaxBufferedPosts": 30, // packet-up, только сервер
"xmux": { // в основном h2/h3, только клиент
"maxConcurrency": "16-32",
"maxConnections": 0,
"cMaxReuseTimes": "64-128",
"cMaxLifetimeMs": 0,
"hMaxRequestTimes": "800-900",
"hKeepAlivePeriod": 0
},
"downloadSettings": { // только клиент
"address": "", // другой домен/IP
"port": 443,
"network": "xhttp",
"security": "tls",
"tlsSettings": {
...
},
"xhttpSettings": {
"path": "/yourpath", // должно совпадать
...
},
"sockopt": {} // будет заменено на sockopt из upload, если находится в "extra"
}
}
} Как видите, Если вы используете CDN, вы можете управлять разделением трафика, даже не изменяя настройки сервера. Например, вы можете выбрать один IPv4 для TLS H2 и один IPv6 для QUIC H3. Большинство CDN поддерживают "префикс домена", например, Например, после появления разделения трафика многие используют его для разделения исходящего трафика по каналам с лучшим исходящим соединением, а входящего — по каналам с лучшим входящим соединением, что также весьма практично. Выше приведен пример конфигурации, включающий все параметры, главным образом для того, чтобы показать, где должен быть указан каждый параметр, и объяснить параметры, которые не были подробно рассмотрены ранее:
Beyond REALITYВ начале прошлого года я вернулся и написал Beyond REALITY не означает замену REALITY, а означает превзойденную популярность. Без преувеличения, как это всегда бывает с Xray, появление XHTTP затмило все остальные транспортные уровни на основе HTTP. Это эра всеобщего господства XHTTP. Он станет более популярным, чем предыдущий успешный протокол REALITY, потому что характеристики XHTTP определяют более широкий охват. Наконец, надеюсь, что появление XHTTP немного вас поразит, как это неоднократно бывало в истории Xray: инновации и постоянное обновление — это кредо Xray. Если эта статья была вам полезна, поддержите REALITY NFT:
Благодаря вашей поддержке, цена Project X NFT выросла в пять-шесть раз. Для тех, кто колебался при первоначальной продаже Project X NFT, это хороший шанс наверстать упущенное. Конечно, мы будем еще более благодарны, если вы сможете поддержать Project X NFT:
|
Beta Was this translation helpful? Give feedback.
-
It's rumored that some CDNs are acting against using their services for proxy (not at a large scale yet) As someone who don't want to get banned by CDNs, i prefer WebSocket or gRPC w/o '/Tun', but not XHTTP with static URL Pattern and xPaddingBytes query string with many 0 data |
Beta Was this translation helpful? Give feedback.
-
笔记本上:嗯嗯嗯,好好好,嗯嗯嗯,好好好,嗯嗯嗯,好好好 |
Beta Was this translation helpful? Give feedback.
-
Six,Six,Six... |
Beta Was this translation helpful? Give feedback.
-
尝试过
|
Beta Was this translation helpful? Give feedback.
-
奈何本人没文化,一句牛逼行天下🥰 |
Beta Was this translation helpful? Give feedback.
-
建议文中优化下"extra"的说明: 对于mode配置,也建议文中增加链接: 如果正文没修改,读者对extra或mode有疑问,可以读这个回复里的链接 |
Beta Was this translation helpful? Give feedback.
-
这种配置算“关闭了mux.cool(我理解是tcp的mux)纯xudp”吗?如果不是最佳实践 应该是怎样 |
Beta Was this translation helpful? Give feedback.
-
Look good to all |
Beta Was this translation helpful? Give feedback.
-
可否考虑在跑H3时,配置启用了cMaxLifetimeMs连接过期时间参数后,能把过期的主连接中的子连接迁移到新连接中,这样规避对UDP的Qos。 |
Beta Was this translation helpful? Give feedback.
-
尝试理解下我们XTLS旗下一系列协议的关注点和逻辑,如果错了请 @RPRX 指正。 XTLS初代splice/direct/origin等----解决性能: VISION----解决TLS in TLS特征: REALITY----解决SNI封锁问题: XHTTP----解决翻墙协议普遍存在的“单一隧道”特征: |
Beta Was this translation helpful? Give feedback.
-
A specific question! |
Beta Was this translation helpful? Give feedback.
-
Hi @RPRX, is it possible to have Vision Seed with XHTTP+REALITY in future? |
Beta Was this translation helpful? Give feedback.
-
A proper english translated version of this article would be much appreciated. |
Beta Was this translation helpful? Give feedback.
-
比如上下行分离问世后,很多人的用法其实是把上行分给上行优的线路、把下行分给下行优的线路,这样也挺实用的。 读到这里大受震撼 |
Beta Was this translation helpful? Give feedback.
-
Is it possible to split UDP and TCP connections? For example, I want UDP connections to go to a certain port, and TCP connections to go 443 |
Beta Was this translation helpful? Give feedback.
-
老大厉害,但是参数多得的确让我这个用了reality一两年的用户眼花缭乱,能否整理几个使用场景的user case(比如套cdn的,不套cdn的,来回程合流的,来回程分流的)对每个场景给个C端和S端的配置模板,然后这个模板里建议用户哪些参数需要根据自己的服务器名称和ip进行自己配置调整,哪些建议用户不用自己配置,这样用起来的会有信心一点?作为还不算那么小白的用户,我现在upgrade到xhttp的最大的焦虑就是,我不知道改了或者配错了哪个参数,可能C/S两侧不一致就会导致不通,因为自己不知道怎么排查 |
Beta Was this translation helpful? Give feedback.
-
Does XHTTP work with traditional fallbacks? If we want it to mimic a real website when using CDN what options do we have? |
Beta Was this translation helpful? Give feedback.
-
Very interesting but completely incomprehensible. |
Beta Was this translation helpful? Give feedback.
-
xhttp多线程测速延迟时tcp+reality的2倍,maxConcurrency=1 |
Beta Was this translation helpful? Give feedback.
-
这样做流量特征与互联网中的主流流量相差甚远,反而容易被识别? |
Beta Was this translation helpful? Give feedback.
-
Why every POST request returns 400 code? I have configs like in https://github.com/chika0801/Xray-examples/tree/main/VLESS-SplitHTTP-TLS (I also log $status) and the status is always 400 or 499 (everything works fine though). It only happens when alpn is h2(client), when it's h3, post returns 200. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
中文 | Русский | EnglishXHTTP: Beyond REALITYDevelopment Overview: Afterwards, @RPRX took over development, achieving a true bidirectional split and renaming the project to XHTTP. With this innovation, the upstream and downstream connections can be totally independent—for example, upstream can be IPv6 CDN H3, while downstream can be IPv4 REALITY H2 (even using different source IPs)—once again heralding a new era. Following that, a streaming-up mode was developed, delivering upstream streaming efficiency without compromise. Additionally, the new Originally, this was meant to be a “Director’s Cut” version of documentation, but it accidentally turned into a full-blown article. This article aims to help you thoroughly understand the principles and design of XHTTP so you can make better use of it. If you wish to donate to the Xray project or collect NFTs, related information is at the end of the article. Thank you for your support!Quick Start GuideDon’t be intimidated by the many parameters of XHTTP. Most have sensible defaults. If you just want to use XHTTP, follow these six steps:
XHTTP comes with multiplexing by default. Its latency is lower than Vision, but multi-threaded speed tests might be less favorable unless you set Also, if you are using v2rayN or v2rayNG clients, they have a global You can treat this article as an enhanced documentation. It covers basically everything you might want to know about XHTTP and explains every parameter in detail. At the end, there’s a configuration example covering all parameters and their usage scenarios. If you’re unsure about any parameter, just search for it in this article. Two Fundamental LogicsJust like REALITY can masquerade as another website, the fundamental logic of anti-censorship is to increase the “collateral damage” that censors incur if they choose to block you, thereby deterring them from rash actions. My support for TLS and the timing/length obfuscation of TLS-based traffic back in the day shares the same rationale. Years of experience tell us that the GFW (Great Firewall) will not permanently block entire IP ranges of large CDNs, as that would affect too many regular websites. Thus, for XHTTP, our initial goal was to hide behind all sorts of CDNs. However, since most CDNs and other HTTP middleboxes (unless specially configured for WS or gRPC) tend to buffer the entire HTTP request before forwarding to the origin, tunneling data through them wasn’t straightforward. Tor’s Meek protocol packages traffic into separate HTTP requests to penetrate these middleboxes, but the speed is painfully slow since it doesn’t adopt XHTTP’s “streaming downstream.” What is “streaming downstream”? Imagine you’re downloading a large file from a website. The CDN, missing a cache hit, must fetch from the origin. It obviously can’t buffer the entire file before sending it to you. Instead, as the origin sends data, the CDN streams it to you immediately. This property—realtime downstream streaming—is the foundation of XHTTP’s “streaming downstream” and guarantees maximum downstream speed. For upstream, to maintain compatibility, XHTTP first implemented “packet-based upstream,” splitting data into POST requests. This reduces efficiency but upstream traffic is typically minimal for common proxy usage. Later, I added “streaming upstream.” With a gRPC header disguise, it can even penetrate CF over H2. Moreover, after rounds of optimization, the speed of packet-up mode can come close to stream-up. Regarding the debate on whether using CDNs in this manner constitutes “abuse”: obviously, a CDN that doesn’t support streaming upstream didn’t intend for you to set up a proxy this way. But we must keep exploring and employing as many methods as possible to combat censorship. We do this out of necessity. Increasing the censor’s “collateral damage” means mixing with “normal” services, which is inevitable. To put it simply: if one day an IP becomes whitelisted—and a CDN’s IP is inside that whitelist—would you use it or not? Anti-censorship doesn’t follow everyday rules; some people fail to understand this simple truth. If you still don’t get it, consider that transports like WebSocket now mainly exist to be tunneled through CDNs. If you believe this is abuse, as a developer you can remove it from the code; as a user you can request its removal. Take real action to prove that “abusing CDNs” isn’t just another excuse conjured up to attack Xray out of some twisted mindset. PACKET-UPThis section is highly technical. Non-developers may focus only on the bold parts. The most compatible mode for XHTTP—“packet-up” (packet-based upstream, streaming downstream)—is designed as follows:
Packet-up and Like other Xray transports, the server accepts That’s the simplified and essential packet-up flow. However, we still need to restrict or define the POST requests, which is achieved by three special parameters:
“Per proxy session” means these limits count separately for each proxied connection, even if they share the same H2/H3 connection. That’s what ‘sc’ (sub-connection) means. To reduce fingerprints, you can set ranges like H1 / H2 / H3With packet-up mode allowing tunneling through almost any HTTP middlebox, let’s discuss a fascinating aspect: QUIC H3 via CDN. Understanding this is crucial for mastering XHTTP. Many HTTP middleboxes convert HTTP versions—e.g., a CDN or Nginx might receive H3 and convert it to H1 or H2 when forwarding to the origin. This means our XHTTP server can just listen for H1 and H2 traffic without directly handling H3. Yet the XHTTP client can still use H3! This is the default behavior: the XHTTP server, by default, only listens on a TCP port and handles H1 and H2. When you enable TLS and set For the XHTTP client:
If you want to verify the actual HTTP version, host, mode, upstream/downstream separation, etc., just set the log level to "info." We were the first to implement widespread proxying of QUIC H3 over CDN—SplitHTTP era opened a new path. Even after discovering that stream-up plus gRPC headers can penetrate CF over H2, this doesn’t diminish the pioneering value of H3 over CDN. Different regions and ISPs may treat H3 differently. If some become lenient, you win; if others block it, well, at least you have options. XMUXSince we mentioned H2 and H3, we must talk about their multiplexing: both are 0-RTT. H3 avoids TCP head-of-line blocking and supports connection migration, so changing client networks doesn’t break the connection. XMUX is a simple but powerful interface designed to control and enhance multiplexing.
With XMUX parameters, you can craft various scenarios. For instance, to improve latency in multi-threaded speed tests, set Do not enable mux.cool when using XHTTP. The new Xray server checks this and only allows pure XUDP. A note on defaults:
In summary, XMUX offers flexible multiplexing controls. If you don’t specify anything, you get a balanced default. Otherwise, configure as needed. These parameters can also be distributed to clients via STREAM-UP/ONENow we get to another key feature: the “streaming upstream, streaming downstream” mode, called stream-up. As the name suggests, it also streams upstream data, achieving high upstream efficiency. Initially developed for REALITY, we discovered that adding a gRPC header disguise allows it to penetrate CF over H2. Nginx and other proxies also support it well (Nginx recommends
Some have reported that with CFT enabled, they can use stream-up, but an extra step is needed to use stream-one. Another CDN (forgot which) heavily throttles stream-one but not stream-up. Implementations (for developers):
Comparing stream-up with gRPC transport:
XHTTP’s advantages over WebSocket or HTTPUpgrade transports are numerous—no visible Upstream-Downstream SeparationThe grand finale: true upstream-downstream separation. Currently, GFW detection of TLS-in-TLS and other patterns focuses on a single connection. If we separate upstream and downstream into distinct paths—e.g., upstream over IPv4 TCP and downstream over IPv6 UDP—the GFW might be thrown off. Because XHTTP’s packet-up and stream-up modes were born with separate upstream and downstream channels associated via a UUID, they naturally enable genuine separation. On the client side, you set "xhttpSettings": {
"host": "example.com",
"path": "/yourpath", // must be the same
"mode": "auto",
"extra": {
"headers": {
// "key": "value"
},
"xPaddingBytes": "100-1000",
"noGRPCHeader": false, // stream-up/one, client only
"noSSEHeader": false, // server only
"scMaxEachPostBytes": 1000000, // packet-up only
"scMinPostsIntervalMs": 30, // packet-up, client only
"scMaxBufferedPosts": 30, // packet-up, server only
"xmux": { // h2/h3 mainly, client only
"maxConcurrency": "16-32",
"maxConnections": 0,
"cMaxReuseTimes": "64-128",
"cMaxLifetimeMs": 0,
"hMaxRequestTimes": "800-900",
"hKeepAlivePeriod": 0
},
"downloadSettings": { // client only
"address": "", // another domain/IP
"port": 443,
"network": "xhttp",
"security": "tls",
"tlsSettings": {
...
},
"xhttpSettings": {
"path": "/yourpath", // must be the same
...
},
"sockopt": {} // will be replaced by upload's when in "extra"
}
}
}
Because XHTTP can pass through CDNs, you might not need to change the server configuration at all to experiment with upstream-downstream separation. For instance, choose an IPv4 route (TLS H2) for upstream, and IPv6 route (QUIC H3) for downstream. CDNs usually support “domain fronting,” so upstream Some people use upstream-downstream separation to pick upstream routes that are better for outbound traffic and downstream routes that are better for inbound traffic. It’s quite practical. The example above includes all parameters to show where to place each.
If you want to confirm what HTTP version, host, XHTTP mode, or upstream-downstream separation the client ends up using, set logs to "info." Beyond REALITYLast year, I returned and introduced REALITY, which solved multiple pain points in one go, and it quickly became a stable staple. People often recommend REALITY when other solutions are blocked. Meanwhile, Xray has continuously improved and optimized other transports too. But XHTTP is the first natively integrated Xray transport—and it starts off big. After reading this article, you know that XHTTP and REALITY can work together. “Beyond REALITY” doesn’t mean to replace REALITY but to surpass its reach. As is always the style of Xray, XHTTP’s appearance leaves all other HTTP-based transports in the dust. It offers a comprehensive solution to all scenarios. It will likely become even more popular than REALITY, as its features inherently appeal to a broader range of use cases. Finally, I hope the advent of XHTTP brings a small shock and awe, just as Xray has repeatedly done before: innovation and progress are always at the heart of Xray’s faith. If you found this article helpful, please consider supporting by collecting a REALITY NFT:
With everyone’s support, the Project X NFT has already multiplied five to six times. If you missed out on Project X NFT’s initial offering, this is your chance to make up for it. If you can, please also consider supporting the Project X NFT:
If anything remains unclear, leave a comment below. I will update this article. |
Beta Was this translation helpful? Give feedback.
-
中文 | Русский
XHTTP: Beyond REALITY
开发简述:2024 年中,@mmmray @ll11l1lIllIl1lll 等人基于 @RPRX 所述的“分包上行、流式下行”原理及实现细节开发出了 SplitHTTP,首次实现了不牺牲下行效率的同时穿透绝大多数支持 HTTP 的中间盒,并首次大规模实现了 QUIC H3 过 CDN,开启了一个崭新的时代,浏览器转发 Broswer Dialer 支持、减少特征的 header padding、控制复用的 XMUX、解锁 REALITY 也相继被安排上。随后 @RPRX 接手开发,实现了真正的上下行分离并更名为 XHTTP,比如上下行可以分别是 IPv6 CDN H3、IPv4 REALITY H2(源 IP 都可以不同),
这下又开启了一个崭新的时代,紧接着开发了不牺牲上行效率的流式上行 stream-up 模式、可以分享全部细节配置的 extra 方案,并给 stream-up 模式加上了默认的 gRPC header 伪装,实现了 H2 流式上行过 CDN,取代了传统的 gRPC 传输层,当初发现这也行就不会有它了,最后将 HTTP 传输层作为 stream-one 模式并入 XHTTP,使其也拥有了 header padding、XMUX、gRPC header 伪装等特性。至此,我们有了完全体 XHTTP:各种姿势穿透中间盒、上下行分离、丝滑的 XMUX 等应有尽有,XHTTP 全场景通吃的时代正式到来。原为导剪版文档,不小心写成了文章。这篇文章旨在帮助你透彻地理解 XHTTP 的原理、设计,以便更好地使用它。
如果你要捐助 Xray 项目、收藏 NFT,相关介绍在文末,感谢支持!
快速上手指南
别看 XHTTP 的参数较多,其实都调好了默认值,如果你只是想用 XHTTP 的话,只需遵循六步:
path
,其它不填即可alpn
选 "h3" 即可使用 QUICaddress
填 IP,serverName
(SNI)填域名即可mode
选 "packet-up",兼容性最强XHTTP 默认有多路复用,延迟比 Vision 低但多线程测速不如它,除非测速前设了
"maxConcurrency": 1
,参考 XMUX 小节。此外 v2rayN&G 客户端有全局 mux.cool 设置,用 XHTTP 前记得关闭,不然连不上新版 Xray 服务端。
这篇文章可以当增强版文档用,它基本上涵盖了关于 XHTTP 你想要了解的所有内容,对每个参数都有解释,文末也有一份涵盖了所有参数的配置示例,并且标注了每个参数的使用场景,如果你对哪个参数不清楚,文内搜索参数名即可找到该参数的详细解释。
两个底层逻辑
正如 REALITY 可以伪装成别人的网站,反审查的根本逻辑就是增加审查者执行封锁时的“附带伤害”,使审查者不敢贸然封锁,我当年看好 TLS 以及 TLS 上流量的时序、长度特征混淆也是同理。多年经验告诉我们 GFW 不会永久封锁大型 CDN 的整个 IP,否则会波及太多常规网站,那么对于 XHTTP,我们最初的目标就是把它隐藏在众多各种各样的 CDN 后面。然而 CDN 为了防止源站遭受攻击,除了有特殊支持的 WS、gRPC 外,一般会缓存完整个 HTTP 请求再发给源站,许多 HTTP 中间盒默认也是这样的行为。据此,Tor 的 Meek 协议把往返流量包装为了一个个 HTTP 请求以穿透这些中间盒,但速率惨不忍睹,因为它没有采用 XHTTP 的“流式下行”。什么是“流式下行”呢?想象一下你正在一个网站上下载一个很大的文件,CDN 没击中缓存于是回源拿,但显然它不太好像上行一样先缓存完整个文件让你干等,而是源站发来多少数据,CDN 就即时转发给你,这就是 XHTTP “流式下行”的基础,也保证了最重要的下行速率可以拉满。至于上行,出于兼容性考虑,XHTTP 首先实现的是“分包上行”,即把上行流量包装为一个个 POST 请求,它的效率显然会打折扣,但好在对于一般的代理需求而言上行流量极少。此后我加了“流式上行”,并且我们发现加上 gRPC header 伪装后还能 H2 流式上行穿透 CF,而我几轮优化”分包上行“后速率甚至直追”流式上行“。
顺便谈一下最近又比较火的套 CDN 是否属于“滥用”的问题:显然不支持流式上行的 CDN 其本意并非让你用来搭建代理服务,但我们为了对抗 GFW,不断探索、开发、利用尽可能多的新路是合理且必要的,是不得已而为之,且增加审查者的“附带伤害”就是要求我们混入“正常”服务,这也是不可避免的。举个最简单的例子:哪天 IP 白名单了而 CDN 的 IP 在里面,你用还是不用?反审查这一领域并不适用现实世界的一些规则,这么简单的道理却一直都有人想不明白。 如果还是没想通,那像 WebSocket 这样的传输层现在仅为了套 CDN 而存在,作为开发者可以删掉它,作为用户可以建议开发者删掉它,以自身的实际行动来证明“滥用 CDN”并不只是为了眼红攻击 Xray 这一为满足某些病态心理的日经无聊行为而找出的又一个借口罢了,
与此同时身体却很诚实,与此同时不难窥见,有些人的虚伪本质已经暴露无遗。PACKET-UP
这一小节技术细节太多,非开发者可以只看粗体部分。
对于 XHTTP 兼容性最强的“分包上行、流式下行”,即 packet-up 模式,我们是这样设计的:
客户端
POST /yourpath/sameUUID/seq
以发送上行数据:客户端
GET /yourpath/sameUUID
启动下行,服务端响应头包含:X-Accel-Buffering: no
以告知中间盒禁用缓冲Cache-Control: no-store
以告知中间盒无需缓存Content-Type: text/event-stream
以伪装成 server-sent events(兼容性更好,可以设置noSSEHeader
以关闭)Transfer-Encoding: chunked
,H2/H3 则不需要为了避免浏览器转发 Browser Dialer 遇到跨域限制,服务端针对所有 GET、POST 的响应头都会包含:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
为了解决 HTTP 请求头和响应头的固定长度特征:
?x_padding=000...
(放 query string 是为了防止 Browser Dialer 产生不必要的 OPTIONS 请求),默认长度为 100-1000,每次请求随机,服务端默认会检查它是否在服务端允许的范围内X-Padding: 000...
,默认长度为 100-1000,每次响应随机xPaddingBytes
分包上行、
?x_padding=000...
会产生较多、较长的日志,你可以在反代软件中设置不记录它们。此外,和 Xray 的其它传输层一样,服务端也接受
X-Forwarded-For
header 以取得客户端的真实 IP,也会依据服务端设置的host
来检查客户端发来的 host(个人建议是没事别设,毕竟已经隐藏在 path 后面了)。以上就是 packet-up 模式的最简化、必要流程,不过此时还有个小问题:如何具体实施、限制 POST 请求?有三个专属参数:
scMaxEachPostBytes
:客户端每个 POST 最多携带多少数据,默认值 1000000 即 1MB,该值应小于 CDN 等 HTTP 中间盒所允许的最大值,服务端也会拒绝大于该值的 POSTscMinPostsIntervalMs
:仅客户端,基于单个代理请求,客户端发起 POST 请求的最小间隔,默认值 30 毫秒scMaxBufferedPosts
:仅服务端,基于单个代理请求,服务端最多缓存多少个 POST 请求,默认值 30 个,超限断连“基于单个代理请求”的意思是每个代理请求各自计数、互不影响,即使它们在同一条 H2 / H3 连接内,这便是 sc 即 sub-connection 的含义。为了减少指纹,前两个值可以设为范围的形式,比如分别为字符串 "500000-1000000"、"10-50",每次随机。这些参数都可以通过
extra
下发给客户端,文末有说明。此外值得一提的是,Xray 最新版优化了 packet-up,速率甚至直追 stream-up,主要利好 QUIC H3 过 CDN。H1 / H2 / H3
既然我们有了几乎能穿透所有 HTTP 中间盒的 packet-up 模式,让我们来讨论一个有趣的东西:QUIC H3 过 CDN,即当初 SplitHTTP 那个崭新的时代,理解这一小节对于灵活使用 XHTTP 尤为重要。
很多 HTTP 中间盒的一个特性就是会进行 HTTP 版本的转换,比如 CDN、Nginx 会将收到的 H3 流量转为 H1 或 H2 流量回源,也就是说我们的 XHTTP 服务端可以仅监听 H1 和 H2,无需监听 H3,但 XHTTP 客户端却可以使用 H3。
这也是 XHTTP 服务端的默认行为:仅监听 TCP 端口并处理 H1 和 H2 流量。 当启用 TLS 并在
alpn
处仅设置一个元素 "h3" 时,服务端将仅使用 quic-go 监听 UDP 端口并处理 H3 流量,但是目前不建议你这样做,而应将 XHTTP 隐藏在真正的 Nginx、Caddy 后面以减少指纹特征,这也是 XHTTP 相较于其它 QUIC 类代理的重要优点之一,另一个当然是能过 CDN。 此外 H3 的拥塞控制为应用层实现,理论上你可以修改这些反代软件的 QUIC 拥塞控制算法并编译,以实现有些人想要的暴力发包。对于 XHTTP 客户端:
alpn
仅有 "http/1.1" 则使用 HTTP/1.1(但 Xray 并不会允许它修改 uTLS 浏览器指纹伪装)alpn
仅有 "h3" 则使用 quic-go H3tlsSettings
都会失效)如果你要确认 Xray 客户端实际使用的 HTTP 版本、host,以及 XHTTP mode、上下行分离等信息,将日志调至 "info" 级别即可。
代理的 QUIC H3 过 CDN,至少 XHTTP 是首个大规模实现的,开了条新路,毕竟有的地区、有的运营商对 H3 审查不严,
不过也有的会 Q 死。即使后来我们开发了 stream-up 模式并发现了加上 gRPC header 伪装就能穿透 CF,也只作用于 H2,看来这个崭新的时代的含金量还在不断上升。XMUX
既然我们提到了 H2 和 H3,就不得不提它们的多路复用:均为 0-RTT,区别是 H3 没有 H2 的 TCP 队头阻塞问题,并且支持连接迁移,客户端换网也不会断。
那么经常研读 RFC 的朋友就会问了:如何具体控制它们的多路复用?我们设计了一个简洁而强大的接口,即 XMUX:maxConcurrency
:每条 TCP/QUIC 连接中最多同时存在多少代理请求,连接中的代理请求数量达到该值后 core 会建立新的连接,以容纳更多的代理请求。XMUX 全为 0 时该项默认值为 "16-32",每次随机。maxConnections
:最多同时存在多少条连接,连接数达到该值前每个新的代理请求都会开启一条新的连接,此后 core 会开始复用已有的连接。该值与maxConcurrency
冲突,只能二选一。默认值 0,即不限制,支持填写范围,每次随机。cMaxReuseTimes
:一条连接最多被复用几次,复用该次数后将不会被分配新的代理请求,将在内部最后一条代理请求关闭后断开。XMUX 全为 0 时该项默认值为 "64-128",每次随机。cMaxLifetimeMs
:一条连接最长“存活”多久,存活该时间后将不会被分配新的代理请求,将在内部最后一条代理请求关闭后断开。默认值 0,即不限制,支持填写范围,每次随机。hMaxRequestTimes
:@xqzr 发现 Nginx 默认最多允许每条 TCP/QUIC 连接累计承载 1000 个 HTTP 请求,XMUX 全为 0 时该项默认值为 "800-900" 取随机,否则该项默认 0 即不限制。该项基于 HTTP 请求计数,一般来说 stream-one 只产生一个 HTTP 请求,stream-up 是两个,packet-up 则是 N 个。该项计数不严谨,且 Golang 的 GET 请求有自动重试,故不建议顶格填写,那些 CDN 什么的要试出来。其中 packet-up 上行循环 POST 时若超过该值会自动切换到另一个 TCP/QUIC 连接,占它一个 reuseTimes 但不占 concurrency。 其实按 XMUX 的三项默认值,stream-* 不会超限,就 packet-up 会超,而它是 H3 的默认 mode,所以新增该项又主要是利好了 H3。hKeepAlivePeriod
:H2 / H3 连接空闲时客户端每隔多少秒发一次保活包,默认 0,即 Chrome H2 的 45 秒,或 quic-go H3 的 10 秒。它是 XMUX 里唯一不允许填范围(该项取随机才是特征)且允许填负数(比如填 -1 关掉空闲保活包)的项,建议留 0。XMUX 提供的这些参数可以组合出各种用法,比如多线程测速前需要设
"maxConcurrency" 1
,而“无限”复用可以设"maxConnections" 1
。即使你懒得研究也没事,当这些值全为 0 时就会取到上面写的三个默认值,相当于隔段时间就换个新的 H2/H3 主连接,相当丝滑,不会有 gRPC、HTTP 传输层始终复用同一条连接导致的“断流”体验。同样,这些参数都可以通过extra
下发给客户端。注:全不填也相当于全为零,会取到三个默认值,但若填了任一项,其它项就没有默认值了,全都要自己填,除前两项外其它项均可同时填。
此外,使用 XHTTP 时不要启用 mux.cool,并且新版 Xray 服务端已有检查,只接受纯 XUDP。
关于 XMUX 的默认值,一些摘录:
文章下方还有讨论一些 Nginx 参数。
STREAM-UP/ONE
终于轮到 XHTTP 的另一个重要模式了:“流式上行、流式下行”的 stream-up,顾名思义这种模式的上行也是流式的,从而不会牺牲上行效率。 它本来是为 REALITY 而开发的,直到我们发现加个 gRPC header 伪装 H2 就能穿透 CF(需要在面板中开启 gRPC 支持),并且 Nginx 等反代软件的支持也不错(Nginx 推荐 grpc_pass,简单省事),所以
mode
默认值 "auto" 的行为是:downloadSettings
时 stream-up),否则 packet-up它们的实现方式是(非开发者可以跳过):
POST /yourpath/sameUUID
即可,也有?x_padding=000...
POST /yourpath/
即可,响应即为下行,双向流式,请求头、响应头均有 header padding/yourpath
,实际请求的是/yourpath/
,若末尾没有/
会自动补上Content-Type: application/grpc
以伪装成 gRPC(可以设置noGRPCHeader
以关闭)noSSEHeader
那么经常使用 gRPC 的朋友就会问了:stream-up 比 gRPC 传输层有什么优势呢?
当然,XHTTP 相较于 WebSocket、HTTPUpgrade 的优势,除了“没有 ALPN 为 http/1.1 的显著特征”外,相信你都看到这里了,心里也早已有了答案,我就不一一列举了,
主要是太多了也不好列。上下行分离
压轴登场的当然是又一个崭新的时代:上下行分离。 我们大概知道,现在 GFW 针对 TLS in TLS 等流量特征的检测是基于单条连接,那么如果我们把上下行拆分到不同的审查系统,比如上行跑 IPv4 的 TCP,下行跑 IPv6 的 UDP,GFW 就会一时反应不过来。而由于 XHTTP 服务端仅基于 path 中随机生成的 UUID 关联上下行,packet-up 和 stream-up 天生就具有真正的上下行分离能力,且由于 XHTTP 可以穿透各种 CDN、可以搭配 REALITY 等,可选姿势也无限多。对于客户端,需要设置
downloadSettings
:可以看出,
downloadSettings
其实就是一套全新的streamSettings
,但是多了类似于 VLESS 出站中的address
和port
以指向另一个入口。显然其中network
必须为 "xhttp"(不可省略),security
可以为 "tls" 或 "reality"。sockopt
项不存在时会继承上行,且由于其中有些参数只作用于本地、分享后会出问题,若处于extra
中(可去掉)则为强制继承上行。除该特例外,上下行分离时下行配置是完全独立的,不会继承上行的任何配置,而且比如,即使上下行均未填 XMUX 从而取默认值时,它们分别在 range 内 roll 出的确定值也是相互独立、无关的,这样随着时间的推移,上下行的复用完全不对称,切换主连接的时间点也不同,反分析效果更好。因为 GFW 若要对上下行分离动手,“主连接发起的时间点相同”肯定是最重要的切入点,所以以后 XHTTP 还会允许一开始就以不同的时间点发起上下行连接。其实如果你套了 CDN,甚至不需要修改服务端配置就可以玩转上下行分离,比如你可以优选出一个 IPv4 跑 TLS H2,再优选出一个 IPv6 跑 QUIC H3。而且 CDN 基本都支持“同域域前置”,比如上行
serverName
填 "a.example.com",下行serverName
填 "b.example.com",上下行host
均填 "c.example.com",实现外部 SNI 看起来也不同,当然如果你本来就有两个域名就更好了。如果你没有任何域名的话,也可以开两台 VPS、开两个 REALITY 玩上下行分离:无论是 CDN 加反代,还是 REALITY 加回落,只要最终以同一 path 抵达同一 VPS 上的同一 XHTTP 入站即可。总之由于 XHTTP 到处都能用,可随意搭配出来的组合是无限的,唯一的问题是脑洞够不够大。比如上下行分离问世后,很多人的用法其实是把上行分给去程优的线路、把下行分给回程优的线路,这样也挺实用的。
上面贴出了一份涵盖了所有参数的配置示例,主要是为了让大家知道每一项应该写在哪,并说明一下前文中没怎么解释的参数:
extra
是host
、path
、mode
以外的所有参数的原始 JSON 分享方案,当extra
存在时,只有该四项会生效。且分享链接中只有这四项,GUI 一般也只有这四项,因为extra
中的参数都相对低频,且应当由服务发布者直接下发给客户端,不应该让客户端随意改。补充说明:“下发”的意思是“人去下发”,就是服务发布者写好
extra
后整个放进分享链接,客户端直接作为自己的extra
就可以用。host
的行为与 Xray 其它基于 HTTP 的传输层一致,客户端发送 host 的优先级为host
>serverName
>address
。服务端若设了host
,将会检查客户端发来的值是否一致,否则不会检查,建议没事别设。host
不可填在headers
内。Beyond REALITY
去年初我回归并写了
秒天秒地秒空气的REALITY,一举解决了多个痛点,然后就天天泡夜店没怎么管了,连文章都鸽到了现在还没完成,XUDP UoT Migration 更可惜,去年文章快写完了都没发,不知不觉 REALITY 已悄然成长为直连主力,经常能看到 XX 被封了下面的评论是推荐换 REALITY,口碑是有目共睹的,甚至因为过于稳定,这里都没以前热闹了。虽然 Xray 也为其它 transports 做出过大量优化、改进,但 XHTTP 是第一个 Xray 原生的传输层,第一个就整了波大的,当你看完这篇文章,也清楚 XHTTP 可以和 REALITY 一起用:Beyond REALITY 的意思并非是取代 REALITY,而是流行程度超越 REALITY。毫不夸张地说,正如 Xray 一贯的风格,XHTTP 的出现使得其它基于 HTTP 的传输层全部黯然失色,这就是 XHTTP 全场景通吃的时代。它将会比上一个成功的协议 REALITY 更加流行,因为 XHTTP 的特性就已经决定了它的覆盖面会更广。
最后,希望 XHTTP 的出现能够给大家带来一点小小的震撼,正如 Xray 历史上多次做到的那样:变革、推陈出新,始终是 Xray 的信仰。
若本文对你有所帮助,支持一个 REALITY NFT:
一篇介绍 REALITY 的文章将于接下来几天发布变成了介绍 XHTTP在大家的支持下,Project X NFT 已翻五六倍,对于 Project X NFT 首发时观望的朋友,这是一次弥补遗憾的好机会。
当然若你有余力,能支持个 Project X NFT 就更感谢了:
0xDc3Fe44F0f25D13CACb1C4896CD0D321df3146Ee
若还有哪里不清楚请在下方留言,我会更新文章,
建议不要过早出翻译版。Beta Was this translation helpful? Give feedback.
All reactions