В этом посте я кратко поведаю о разных интересных возможностях XRay (клиент и сервер для протоколов VMess, VLESS, Trojan и других, в том числе с XTLS-Reality и XTLS-Vision), о которых, кажется, мало кто знает, но которые могут оказаться очень полезными.
Оглавление:
-
Фрагментирование запросов
-
QUIC-транспорт
-
Мониторинг и автоматический выбор outbound’а
-
Сбор статистики
-
Browser dialer
Fragment
На фоне недавних событий (замедление Youtube Роскомнадзором), многие открыли для себя инструменты типа GoodbyeDPI и подобных. Они работают с использованием различных трюков при передаче данных по протоколу TCP, благодаря которым цензурирующее оборудование (так называемое ТСПУ) при обработке TLS-handshake оказывается сбитым с толку и не понимает, на какой именно сайт вы пытаетесь попасть (потому что не может прочитать параметр «SNI» при установке TLS-соединения), и в итоге блокировка/замедление не срабатывает. XRay тоже умеет подобное, там это называется «Fragment».
Простейший конфиг XRay для этого будет выглядеть примерно так:
локальный прокси с fragment
{ "inbounds": [ { "listen": "127.0.0.1", "port": 1080, "protocol": "socks", "tag": "socks" } ], "outbounds": [ { "tag": "fragment", "protocol": "freedom", "settings": { "fragment": { "packets": "tlshello", "length": "100-200", "interval": "10-20" } }, "streamSettings": { "sockopt": { "tcpNoDelay": true } } } ] }
Запустив XRay с таким конфигом и настроив браузер на использование SOCKS-прокси на локальном (127.0.0.1) порту 1080, XRay будет фрагментировать заголовок ClientHello протокола TLS. Доступные параметры:
"packets"
:может быть «1-3» для фрагментации на уровне TCP (первые 1-3 отправки данных от клиента к серверу) либо «tlshello» для фрагментации TLS handshake;
"length"
: на кусочки какого размера дробить отправляемые данные;
"interval"
: пауза между отправкой фрагментов в миллисекундах;
Конкретные требуемые значения параметров могут отличаться в зависимости от типа (и даже версии софта) используемого оборудования DPI у провайдера, поэтому возможно чтобы получить нужный эффект придется с ними поэкспериментировать.
Fragment можно также комбинировать с использованием прокси-протоколов, например VLESS и других, пример конфига есть на github.
QUIC-транспорт
Еще из того, о чем недавно говорили на фоне замедления Youtube — протокол QUIC. Это разработка Google, которая использует UDP вместо TCP при доступе к веб-серверам, нацеленная на уменьшение времени установки соединения и улучшение скорости доступа за счет более эффективной передачи данных. В случае с замедлением Youtube у некоторых пользователей включение QUIC в браузере помогло решить проблему (а у некоторых наоборот, выключение). Причин тут может быть несколько. Во-первых, есть основание предполагать, что определенное оборудование ТСПУ… не умеет нормально разбирать заголовки QUIC-протокола (и из-за этого одно время Роскомнадзор даже резал такие подключения). Во-вторых, в браузере Chrome разработчики намеренно добавили фрагментацию данных при установке соединения — они таким образом пытались заставить разработчиков веб-серверов полностью следовать стандарту протокола, и эта фрагментации дала очень полезный побочный эффект для обхода цензуры (см. предыдущую часть статьи). В третьих, QUIC очень эффективно работает при потерях пакетов, а оборудование РКН замедляет Youtube именно таким образом.
И XRay умеет использовать QUIC в качестве транспорта для своих протоколов (VLESS, VMess, Trojan и другие). Вы можете спросить, зачем использовать QUIC-транспорт, когда можно использовать VLESS безо всяких транспортов (поверх обычного TLS), отвечу — всегда полезно иметь запасной альтернативный вариант, к тому же QUIC в XRay можно использовать по-разному.
Вариант раз — в чистом виде. С QUIC, к сожалению, не получится сделать что-то типа XTLS-Reality, когда вы прикрываетесь чужим доменом. В теории это возможно, но пока что никто такое не реализовал. Поэтому понадобится свой домен и TLS-сертификат для него (подойдет даже бесплатный домен от dynu.com и сертификат от LetsEncrypt). Конфиг XRay для примера:
VLESS c QUIC-транспортом
{ "inbounds": [ { "port": 443, "protocol": "vless", "tag": "quic", "settings": { "clients": [ { "id": "4c3fe585-bb09-89df-b284-e2dada14150f", "email": "user1" } ], "decryption": "none" }, "streamSettings": { "network": "quic", "quicSettings": {}, "security": "tls", "tlsSettings": { "certificates": [ { "certificateFile": "/etc/letsencrypt/live/yourdomain/fullchain.pem", "keyFile": "/etc/letsencrypt/live/yourdomain/privkey.pem" }] } }, "sniffing": { "enabled": true, "destOverride": [ "quic", "http", "tls" ] } } ], "outbounds": [ { "protocol": "freedom", "tag": "direct" }, { "protocol": "blackhole", "tag": "block" } ] }
Потом в клиенте настраиваете VLESS-подключение с нужным UUID, вводите адрес (домен) вашего сервера, выбираете QUIC в качестве транспорта — и все работает. Такое подключение будет со стороны выглядеть как настоящий QUIC на 443 UDP порту, но, к сожалению, настроить fallback (чтобы при заходе на UDP/443 открывался фейковый веб-сайт) в XRay возможности нет.
Второй вариант — использовать обфусцированный QUIC. Домен и сертификат для этого уже не нужны (их все равно никто не увидит). Со стороны передача данных будет выглядить как «нечто непонятное по UDP», примерно как в случае с AmneziaWG.
VLESS + обфусцированный QUIC (что-то непонятное по UDP)
{ "log": { "loglevel": "debug" }, "inbounds": [ { "port": 8443, "protocol": "vless", "tag": "quic", "settings": { "clients": [ { "id": "4c3fe585-bb09-89df-b284-e2dada14150f", "email": "user1" } ], "decryption": "none" }, "streamSettings": { "network": "quic", "quicSettings": { "security": "aes-128-gcm", "key": "hellohabr" } }, "sniffing": { "enabled": true, "destOverride": [ "quic", "http", "tls" ] } } ], "outbounds": [ { "protocol": "freedom", "tag": "direct" }, { "protocol": "blackhole", "tag": "block" } ] }
В данном случае используется шифр aes-128-gcm
(другой возможный вариант — chacha20-poly1305
) с ключом»hellohabr». Клиенты настраиваются аналогично предыдущему случаю, только надо отключить TLS, а вместо этого выбрать шифр и ключ.
И еще один вариант, близкий ко второму — замаскировать QUIC под DTLS (WebRTC, звонки в месседжерах), SRTP (FaceTime) или uTP (BitTorrent). Для этого нужно добавить параметр header:
... "streamSettings": { "network": "quic", "quicSettings": { "security": "aes-128-gcm", "key": "hellohabr", "header": { "type": "dtls" } } ...
«type» может быть «srtp», «utp», «dtls», «wechat-video» и «wireguard». Не забудьте на клиенте выбрать то же самое.
Помните, я в своей статье «Надежный обход блокировок в 2024: протоколы, клиенты и настройка сервера от простого к сложному» (заблокирована на территории РФ, но доступна через иностранные VPN/прокси) советовал mKCP как запасной вариант, работающий по UDP? К сожалению, начиная с какой-то из версий Xray оно сломано и тупит при определенных сценариях — жрет память, жрет процессор и тормозит, вплоть до полной невозможности работы. Транспорт QUIC в XRay работает гораздо стабильнее, и обладает всеми теми же возможностями обфускации.
Недостатка два. Первый, как я уже сказал, когда вы маскируетесь под «чистый» QUIC, нельзя добавить маскировочный сайт. Второй — вся эта красота работает только с клиентами на базе XRay-core, а те что на базе Sing-box в пролете (точнее, sing-box не поддерживает обфусцированный QUIC, чистый в теории должен работать, но не заработал).
Если вам нужен прокси поверх QUIC с маскировкой под сайт или под «непонытно что» и работающий с Sing-box, используйте Hysteria2.
Selectors и observatory — мониторинг и автоматический выбор outbound’а
Некоторые используют XRay для построения цепочек прокси. Например, вы находясь в России подключаетесь сначала к прокси-серверу находящемуся в России, а уже с него куда-нибудь за бугор. XRay позволяет контролировать доступность вышестоящих прокси-серверов (если у вас их несколько) и балансировать запросы между ними. Фичи называются selectors и observatory. Документация здесь.
Расскажу про конфиг вкратце. На верхнем уровне вашего конфига добавляете объект «observatory»:
"observatory": { "subjectSelector": [ "outbound1", "outbound2" ], "probeURL": "http://www.gstatic.com/generate_204", "probeInterval": "300s", "enableConcurrency": true },
В списке «subjectSelector» перечисляете имена outbound’ов которые надо проверять, в «probeURL» задаете адрес для теста, в «probeInterval» периодичность.
А потом в объекте «routing» описываете объект «balancers», например так:
"routing": { "domainStrategy": "IPIfNonMatch", "balancers": [ { "tag": "mybalancer", "selector": [ "outbound1", "outbound2" ], "strategy": { "type": "leastPing" }, "fallbackTag": "outbound3" },
В «selector» перечисляете outbound’ы, через которые можно подключаться «наружу», в fallbackTag можно указать outbound который XRay попытается использовать если все перечисленные выше окажутся недоступные (и он же будет использоваться сразу после старта пока еще не прошли проверки). И дальше вы можете использовать ваш «mybalancer» как обычный outbound — например указать его явно в правилах роутинга.
Сбор статистики
Можно получать в виде JSON статистику — кто из пользователей сколько скачал, по каким inbound’ам/outbound’ам, а если используете observables из предыдущего раздела — смотреть их доступность и время пинга. Удобно для интеграции в системы мониторинга типа Munin, Zabbix или Prometheus. Документация здесь: Метрики | Project X (xtls.github.io)
Browser dialer
Помните про TLS-fingerprint, он же отпечаток? У каждого браузера и каждой TLS-библиотеки он уникальный. В некоторых странах цензоры уже используют его для выявления подключений от прокси-клиентов, потому что у стандартной TLS-библиотеки языка Go он совсем не похож на отпечатки популярных браузеров. XRay может использовать uTLS — специально модифицированную библиотеку, которая умеет «прикидываться» браузерами, например, firefox и chrome, копируя их fingerprint’ы. Есть только проблема — если вы давно не обновляли клиент, fingerprint его может устареть, отставая от актуальных версий браузеров (в некоторых странах так блокировали Cloak, использовавший TLS fingerprint какой-то старой версии Firefox), а во-вторых, даже если фингерпринт похож, все равно какие-то нюансы поведения могут различаться, и цензоры рано или поздно могут вас на этом подловить.
Вы возможно слышали про naiveproxy, разработчику которого в погоне за максимально похожим на «настоящий» TLS fingerprint’ом пришла гениальная идея просто взять часть кода настоящего браузера Chromium и использовать его для установления соединения. У XRay есть идея не хуже — он может использовать настоящий браузер целиком 🙂 Работать оно будет только с websocket- или SplitHttp-транспортом, зато это прямо максимально аутентичная маскировка.
Использовать довольно просто. Конфигурируете XRay как обычно для вебсокетов или splithttp (можно создать подключение в Nekoray и экспортировать конфиг, чтобы проще было), а потом нужно запустить XRay с переменной окружения типа XRAY_BROWSER_DIALER=127.0.0.1:8080
. В Linux ее можно вставить сразу перед командой запуска xray, в Windows задать командой «set» перед запуском.
После этого открываете в браузере адрес http://127.0.0.1:8080 (выглядит оно как пустая страница), и XRay начинает использовать его как промежуточный пункт для соединения с удаленным прокси-сервером — вы можете увидеть в «Developer Tools -> Network» websocket-подключения парами, часть к локальному XRay, а часть к удаленному прокси-серверу.
Два важных нюанса: 1) в браузере, который вы используете как промежуточный транзит, не должно быть задано прокси в настройках (иначе запрос к удаленному прокси попадет снова на XRay, и получится бесконечный цикл); если вы используете TUN-интерфейс, то клиенты обычно делают исключение в маршрутах для адреса прокси назначения, но могут быть свои приколы. 2) количество одновременных вебсокет-подключений в браузере ограничено, поэтому рекомендуется использовать мультиплексирование (mux) в XRay. Между тем, ничто не запрещает открыть в браузере несколько вкладок, они будут использоваться для проксирования одновременно.
И наконец, не обязательно открывать окно браузера, Chrome можно запустить в headless mode (без видимого окна), например как-то так:
"c:\Program Files\Google\Chrome\Application\chrome.exe" --headless=new --remote-debugging-port=0 --no-proxy-server http://127.0.0.1:8080/
Здесь одной командой мы запускаем его в headless-режиме, отправляя сразу на локальный адрес XRay, отключаем использование прокси, и включаем remote debugging, чтобы можно было проверить если что-то вдруг пойдет не так.
ссылка на оригинал статьи https://habr.com/ru/articles/834290/
Добавить комментарий