Как стать автором
Обновить

Кратко про XHTTP для VLESS: что, зачем и как

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров8.3K

Просили нас тут рассказать про протокол технологию XHTTP в контексте XRay, VLESS и прочих. Просили — рассказываем!

К сожалению, официальной документации по XHTTP практически нет, кроме весьма упоротого поста на гитхабе, который написан довольно своеобразно и не очень понятен людям «не в теме». Там есть еще в комментариях русский перевод с китайского, но он настолько плох, что лучше бы его не было (хотя можно читать ради здорового смеха — одна только «блокировка головки TCP» чего стоит).

Для начала немного истории. Классическое использование VLESS и подобных прокси‑протоколов (в том числе с использование XTLS‑Reality) предполагает подключение клиента напрямую к прокси‑серверу, который крутится на каком‑нибудь VPS. Однако во многих странах (и в России тоже) под блокировки (или замедления) начали попадать подсети популярных хостеров целиком, а в других странах цензоры начали отслеживать подключения к «одиночным» адресам с большим объемом трафика. Поэтому еще с давних времен обдумывались и проверялись идеи подключения к прокси‑серверам через CDN (сети доставки контента). Чаще всего для этого использовался websocket‑транспорт, но у этого варианта есть два больших недостатка: у него есть один характерный признак (не буду указывать его тут, чтобы не облегчать работу РКН), а во‑вторых, число CDN, которые поддерживают проксирование вебсокетов, не так уж велико, и хотелось бы иметь возможность проксироваться и через те, что не умеют.

Поэтому сначала в известном проекте Tor для бриджей (мостов) придумали транспорт meek, который позволял передавать данные с помощью многочисленные запросов‑ответов по HTTP, и таким образом позволял подключаться к мостам (прокси) через любые CDN. Чуть позже этот же транспорт реализовали в ненадолго воскресшем из мертвых V2Ray. Но у meek есть два очень существенных недостатка, которые вытекают из его принципа работы: скорость работы очень низкая (по сути дела у нас полудуплексная передача и огромный оверхед на постоянные запросы‑ответы), и из‑за огромного количества GET/POST‑запросов каждую секунду, бесплатные CDN довольно быстро могут нас выгнать на мороз, а платные — выкатить солидный счет.

Авторам XRay же в голову пришла отличная идея, как улучшить этот механизм: а что если разделить прием и передачу на два соединения — одно для приема, одно для передачи? Так появился транспорт SplitTunnel, который в результате дальнейшего развития превратился в XHTTP.

Сразу уточню две вещи. Первое, XHTTP — это не протокол, а именно транспорт. Обычно его используют для всем известного протокола VLESS, хотя в теории можно использовать и для других. Второе, XHTTP изначально придумывался для работы через CDN, но по факту он может использоваться и без CDN для прямого подключения к серверу, и это тоже дает определенные преимущества.

XHTTP имеет три режима работы:

  1. packet‑up — режим наиболее медленный (но все равно гораздо быстрее чем meek), но совместимый практически со всеми веб‑серверами и CDN. Используется одно соединение для передачи данных от сервера к клиенту, и множество короткоживущих соединений для передачи данных от клиента к серверу
    (здесь и далее под «соединение» понимается не конкретно TCP‑соединения, а сессия «запрос‑ответ» в HTTP, множество которых может жить внутри одно TCP‑соединения, но в любом случае, TCP‑соединения для трафика «туда» и «обратно» будут разные)

  2. stream‑up — более скоростной, но с худшей совместимостью — пролезает только через определенные (или определенно настроенные) веб‑сервера. Одно долгоживущее соединение для передачи «клиент→сервер», одно долгоживущее соединение для передачи «сервер→клиент».

  3. stream‑one — единственный режим, который не разделяет соединения для «туда» и «обратно», а всегда передает данные в обе стороны внутри только одного соединения. По сути дела то же самое, что обычный VLESS с HTTP‑заголовком (был такой транспорт в XRay раньше). Пролезает только через Nginx с директивой grpc_pass и через Cloudflare с включенной фичей gRPC (по факту gRPC там на самом деле не используется, это только обманка, чтобы Nginx и CF не вмешивались в передаваемые запросы‑ответы).

Какие же преимущества дает XHTTP?

  1. Возможность подключаться к серверу не только по HTTPS, но и через QUIC (надо на клиенте явно поставить ALPN h3) — может работать более эффективно при нестабильном канале связи или если HTTPS заблокирован, а QUIC заблокировать забыли;

  2. Возможность подключаться к прокси‑серверу используя TLS v1.2, при этом имея фингерпринт настоящего веб‑сервера. Тут поясню чуть подробнее. Фингерпринт — «отпечаток», набор определенных характеристик в реализации TLS и поведения веб‑сервера в целом, отличительные черты, так сказать. Fingerprint'ы у сервера XRay и у настоящего веб‑сервера (например, Nginx, Caddy, и др.) разные, и это может использоваться для детектирования прокси. Обычно для избегания этого используют XTLS‑Reality в так называемом режиме «steal from yourself» — когда вы маскируетесь под свой же собственный веб‑сервер, работающий на том же хосте. Проблема в том, что XTLS‑Reality работает только через TLS v1.3, а РКН уже не раз ловили на том, что они блокировали TLS v1.3 в сторону популярных хостеров. Используя XHTTP вы можете подключаться к прокси по TLS v1.2, при этом фингерпринт сервера будет аутентичным — потому что на 443 порту у вас будет слушать настоящий Nginx, а XRay будет стоять уже позади него.

  3. Возможность подключаться через CDN, в том числе которые не поддерживают Websockets и gRPC. При этом некоторые CDN до сих пор разрешают domain fronting, о котором рассказывал в своей статье MiraclePtr. Таким образом, вы можете маскироваться под чужой домен даже еще лучше, чем это было с XTLS‑Reality — теперь когда вы подключаетесь к прокси, вы не только подключаетесь с SNI какого‑нибудь чужого домена и получаете его настоящий сертификат в ответ, но и более того — вы подключаетесь именно к тому IP‑адресу, в который резолвится этот самый домен, и вы такой не один — к этому адресу с тем же SNI подключаются еще тысячи людей со всей страны, посещающие этот сайт. Идеально.

  4. Можно использовать browser dialer. Это решает схожую с п.2 проблему с fingerprint'ом, но уже не сервера, а клиента. XRay и подобные используют библиотеку uTLS чтобы маскироваться под fingerprint'ы популярных браузеров, но эта маскировка не стопроцентная. А с browser dialer схема выглядит так: вы открываете в браузере страницу со специальным скриптом, и ваш XRay‑клиент подключается не напрямую к прокси, а сначала к браузеру, а уже скрипт из браузера подключается к прокси. В итоге fingerprint и поведение клиента похожи на настоящий браузер настолько, насколько это вообще возможно — потому что фактически клиентом является сам настоящий браузер.

  5. И наконец, самое вкусное. В режимах packet‑up и stream‑up передаваемые данные разделяются как минимум на два подключения «туда» и «обратно», и это очень сильно затрудняет анализ паттернов трафика и всяких там TLS‑inside‑TLS. Но это еще не все. Кто сказал, что эти два подключения «туда» и «обратно» должны устанавливаться одинаковым образом и к одному и тому же адресу? XRay позволяет настроить их независимо. В итоге вы можете передавать данные «туда» через QUIC, а обратно получать через HTTPS. Или передавать данные «туда» по IPv6, а обратно получать их по IPv4. Или соединяться «туда» и «обратно» на разные IPv6-адреса. Можно даже вообще иметь два подключения к двум разным серверам у разных хостеров в разных странах. Можно слать данные в одну сторону напрямую, а в другую сторону через CDN. И естественно во всех этих случаях использовать разные домены. Короче, насколько хватит фантазии. Все это многократно усложняет анализ и блокировки.

    Несколько важных моментов:

    1. Вместе с XHTTP появился новый алгоритм мультиплексирования XMUX. Там ничего особо интересного, но и ничего сложного — интересующиеся могут перевести статью с гитхаба по ссылке выше автопереводчиком на английский, там все почти понятно

    2. XHTTP нельзя использовать с XTLS‑Vision. Защита от детектирования tls‑inside‑tls обеспечивается за счет мультиплексирования (тот самый XMUX из предыдущего пункта) и разделения потоков «туда‑обратно» (об этом было выше)

    3. XHTTP можно использовать с XTLS‑Reality (в этом случае по умолчанию выберется режим stream‑one, если явно не указано другое)

    4. XHTTP активно развивается, поэтому важно, чтобы версии XRay на клиенте и сервере были одинаковые — иначе могут быть странные глюки, либо вообще ничего не заработает

    5. Клиенты на базе Sing‑box не умеют в XHTTP. На базе XRay — пожалуйста. v2raN и v2rayNG работают без проблем

    6. Пример конфигурации XHTTP для клиента и сервера XRay, а также для Nginx можно найти в репе xray‑examples.

Вместо заключения. Самое важное

За последний год мы наблюдаем, что РКН, не справляясь с детектированием протоколов (которые можно детектировать по косвенным признакам или глубоким статистическим анализом, но для этого нужны мозги и деньги, и если вроде деньги есть, то с мозгами, видимо, ситуация не очень), перешел на более топорные меры с более сильным побочным эффектом, которые мы могли иногда наблюдать в некоторых регионах: блокирование HTTPS в сторону популярных хостеров, блокирование TLS v1.3 к ним же, блокирование некоторых CDN, блокирование неопознанных протоколов, шейпинг SSH‑подключений после превышения определенного объема переданных данных, и даже временное (от 15 минут до пары дней) усиление блокировок для конкретных абонентов, которые триггернули каие‑либо эвристики ТСПУ.

Поэтому напрашивается вывод, что дальнейшая тактика борьбы с цензурой должна строиться не на выдумывании более навороченных протоколов и методов маскировки, а на использовании особенностей самих механизмов блокировок — по крайней мере так, чтобы их эксплуатация была все дороже и дороже, а делать их было все сложнее и сложнее.

Например, сейчас в большинстве случаев детектирования и блокировки не применяются для трафика внутри страны. Напрашивается вариант, что первым пунктом назначения при подключении к прокси может быть какой‑нибудь дешевый отечественный VPS (к которому можно подключаться как угодно, хоть древним shadowsocks, или с Reality маскируясь под российский сайт), а уже с него трафик будет идти на прокси за границей.

А если у хостера тоже окажется ТСПУ и он начнет зверствовать — вспоминаем про механизм reverse proxy, bridge, portals, про которые тоже рассказывал MiraclePtr — потому что трафик «в обратную сторону» обычно тоже не фильтруется, и его фильтрация потребует гораздо больше ресурсов. И кстати, раз в статье упомянуты CDN, то еще подсказочка: CDN не обязательно должны быть иностранные. Think about it.

Теги:
Хабы:
+26
Комментарии9

Публикации