@MasterYoba А не затруднит пояснить за топологию этой схемы, пытаюсь понять, как это все работает. Вот есть клиент, который хочет сходить на экстремистский Твиттер. Обычно он идет на ваш прокси и там в туннеле сообщает вам, что хочет посетить Твиттер, наш прокси сервер ему его приносит в зашифрованном туннеле. А тут куда запрос клиента в вашем случае идет? На сервер Cloudflare или на ваш UP домен? Куда дальше идет ответ с Твиттера, как он понимает, что нужно ответить на DOWN домен? И какую роль тут играет Cloudflare?
Нет, разницы никакой, этот ipv6 служит только для стыковки сервера с cloudflare и цензору он не виден. Можно всё повесить на один ipv4 адрес, именно так китайцы в конфигах выше и делают. У меня просто был дополнительно свободный ipv6 адрес, cloudflare с ними дружит, и я захотел сделать вот так.
Минус пока в том, что все популярные клиенты на Sing-Box, а его авторы запрос на поддержку XHTTP дропнули и не известно, будут ли вообще его прикручивать. Поэтому нам остается только V2RayN.
Так подождите, а V2RayN поддержку 32бит выпилили что ли. В 6 версии была же вроде
Всё то же самое, просто соединение с прокси сервером строится не напрямую, а через cloudflare. Клиент сначала строит “честное” tls соединение с сервером Cloudflare с SNI вашего купленного домена, а внутрь него заворачивает соединение с экстремистским твиттером посредством vless с выбранным транспортом через ваш VPS прокси-сервер. VPS сервер как бы спрятан за CDN как за щитом, внешний наблюдатель видит только обращение к ip-адресам CF и SNI вашего домена, но про сам VPS ничего не знает. Всё что может сделать цензор - забанить ваш домен, который легко сменить.
Вот тут очень хорошая статья по этой теме:
Из минусов тут только характеристика трафика tls-in-tls, как раз с которой вроде как и должен помогать транспорт xhttp. Теперь с ним запросы от клиента идут по одному “каналу” к CDN с внешним SNI domain1, а ответы от сервера по второму каналу с внешним SNI domain2. Насколько это эффективно - черт его знает, но выглядит перспективнее, чем “простое” проксирование через CDN с транспортом вебсокет или grpc.
@MasterYoba Я правильно понял, что эти ваши домены просто висят в воздухе, получается, зарегистрированы на CF и все, на них нет никаких сайтов? А Xray сервер у вас на третьем домене или на голом IP? Или как?
Домен зарегистрированный в CF указывает на IP-адрес vps сервера (v4 или v6 - без разницы), весь трафик к этому домену на 443 порт CF проксирует через себя, т.е. при DNS резолвинге отдаёт клиенту не IP-адрес сервера, а IP-адреса своих “промежуточных” серверов.
На vps сервере на 443 порту слушает nginx, а там уже можно хостить любой контент, и веб сайты в том числе. То есть можно сделать domain1.com/mywebsite - ваша веб-страничка с котиками, domain1.com/proxy - grpc_pass на сокет, где слушает xray. Вообще, чем об этом так рассуждать проще самому посмотреть и поиграться, цена вопроса - рублей 100 за какой-нибудь самый дешевый домен (главное не .ru/su/рф), а cloudflare бесплатен.
А как можно не указывать порт при создании inbound в панели 3x ?
Я когда ввожу /dev/shm/xrxh.socket,0666 и выбираю порт 0, панель возвращает значение 1 вместо 0 )
Оставить как есть. В json файле конфигурации и в списке входящих соединений в панеле будет 0. Почему-то в настройках инбаунда он 1 показывает, недоработка UI.
Настроил раздельный XHTTP по китайским гайдам. С одним доменом даже обошелся и через 3X-UI по большей части. Домен регистрируем в Cloudflare, у регистратора, где покупали прописываем кастомные DNS сервера, которые выдаст CF, включаем ему gRPC (в СF кабинет настройки домена, закладка Network), отключаем ECH, который запрещен в РФ.
На 3Х-UI сервере запускаем меню командой x-ui и выбираем там Cloudflare SSL Certificate. Нужно ввести свой имейл аккаунта CF, Global API Key (настройки домена в CF кабинете, вкладка Overview, внизу справа) и имя домена. Он создаст автоматом родной сертификат CloudFlare на 15 лет и импортирует его в панель. В вкладке SSL/TLS Encryption для домена в кабинете CF выбираем режим Full (Strict). Теперь вход только по CF сертификату.
В панеле 3Х-UI создаем новый инбаунд. Назовем, чтобы не запутаться Remark: Vision-Reality. Порт 443. Дальше именно щас важно в Fallback в поле Dest вписать порт 2023, на котором нас будет слушать следующий инбаунд. Transmission TCP. Дальше выбираем Security: Reality. Fallback исчезает, не пугайтесь, его настройки в JSON конфиге сохранятся. В Dest (Target) прописываем порт 7443, на котором будет слушать Nginx. Xver = 1, общаются они через Proxy Protocol. В SNI указываем наш cdn-domain.com. Возвращаемся в раздел Client и ставим Flow: xtls-rprx-vision. Возвращаемся в настройки Reality. Генерируем ключи. Жмем Create. Готово.
Создаем второй инбаунд. Remark: XHTTP. Listen 127.0.0.1. Port 2023. Transmission: XHTTP. Path: xhttp-path (такой же как в конфиге Nginx). Security: TLS. SNI: cdn-domain.com - ваш домен. Жмем Set Cert from Panel, он подставит сгенерированные ранее сертификаты CloudFlare. Create. Готово.
Код для сервера Nginx.
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name cdn-domain.com www.cdn-domain.com; // Укажите свой домен на CloudFlare
location / {
try_files $uri $uri/ =404;
}
listen 127.0.0.1:7443 ssl http2 proxy_protocol;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
ssl_certificate /root/cert-CF/cdn-domain.com/fullchain.pem; // Путь к сертификатам CloudFlare
ssl_certificate_key /root/cert-CF/cdn-domain.com/privkey.pem; // Путь к сертификатам CloudFlare
location /xhttp-path {
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:2023;
proxy_redirect off;
proxy_request_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
listen [::]:80;
server_name cdn-domain.com www.cdn-domain.com; // Укажите свой домен на CloudFlare
return 302 https://$server_name$request_uri;
}
Дальше нужно клиентскую часть загнать в V2RayN (единственный на сегодня клиент, который умеет в XHTTP). Здесь придется поколдовать руками, два наших соединения надо сшить в одного хитрого Франкенштейна. Экспортируем ключик от Vision-Reality в V2RayN. Он как есть работать не будет! Экспортируем его оттуда в буфер и допиливаем секцию “outbounds” в блокноте. Если у вас нет второго, “прямого” домена, вместо direct-domain.com просто вбиваем IP вашего Xray сервера.
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "cdn-domain.com", // Ваш домен CloudFlare
"port": 443,
"users": [
{
"id": "6cc4e521-e0db-4c7d-a4c6-453f5d8c64e8", // поменять на ID инбаунда XHTTP
"email": "t@t.tt",
"security": "auto",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "xhttp", //поменять на "xhttp"
// добавить объект "xhttpSettings"
"xhttpSettings": {
"mode": "auto",
"path": "/xhttp-path", // Path из инбаунда XHTTP
"extra": {
"downloadSettings": {
"address": "direct-domain.com", // прямой домен или IP Xray сервера
"port": 443,
"network": "xhttp",
"xhttpSettings": {
"mode": "auto",
"path": "/xhttp-path" // Path из инбаунда XHTTP
}
}
}
},
"security": "reality",
"realitySettings": {
"serverName": "direct-domain.com", // меняем на прямой домен или IP Xray сервера
"fingerprint": "chrome",
"show": false,
"publicKey": "ob_ZLNraBpBrEi5YuedCt_eg69IfXWBWANy86-lVKg0", // Публичный ключ инбаунда Vision-Reality, оставить как есть
"shortId": "4ef078", // Short ID инбаунда Vision-Reality, оставить как есть
"spiderX": "/"
}
},
"mux": {
"enabled": false,
"concurrency": -1
}
}
Импортируем снова в V2RayN. Запускаем, работаем!
Плюсы. Гиперпаранойность. Все запросы идут в восходящем потоке через CloudFlare, цензор не видит IP вашего VPS, вы обращаетесь к IP CDN. Нисходящий поток идет к вам с VPS, тут его IP видно, но связать домен с IP цензор не может. Детектировать такую схему намного сложнее.
Минусы. Сложность в настройке. Вырастут задержки из-за того, что у нас еще CDN появляется в цепочке. Также из-за того, что XHTTP шинкует трафик, снижается полезная полоса, т.е. несколько снизится скорость загрузок.
Гипотетически, если использовать VLESS+TLS со своим доменом с Ngnix на 80 и 443 порту для сайта-заглушки, то пока нет смысла прятать IP VPS?
Пока все работает. Это сильно паранойный сценарий на гипотетическое северокорейское будущее. Но и тут прибегут другие параноики, которые скажут, да этот ваш CloudFlare забанят к чертям. Нельзя исключать и такие варианты. Но как по мне, тут уже не настройки надо будет искать, а чемодан паковать.
По какой причине не сможет ?
Сама сеть выглядит подозрительно когда исходящие запросы идут в цдн и тут же возвращаются с какого-то непонятного айпишника, который на проверку окажется ещё и в пуле хост провайдера, тут же очевидно наш прокси хитрюля спрятался.
Не понятны такие телодвиженя, они рассчитаны на то что роскомнадзор будет честно себя вести ?
Тут как раз все безобидно выглядит. Я отправляю какие-то запросы на CDN, т.е. как будто члены семьи посещают какие-то сайты с котиками, за этим CDN сидящие. А параллельно с одного IP качаю файло, например, и на этом IP легальный файлообменник к тому же. Как цензор может это вскрыть и увязать, что это одна сессия? Как от свяжет моит параллельные запросы к эсктремисткому фейсбуку и к легальному новостному сайту, сидящими за одним CDN? Никак. За CDN он не видит, куда я хожу. На этом CDN и строят свою безопасность. На этом и китайский трюк строится. Как раз когда вы сидите постоянно в одном туннеле, этот трафик, хотя и тоже нельзя вскрыть, и посмотреть куда вы идете, но его можно хотя бы статистически анализировать. А тут что с чем коррелирует? Как это по пакетам вынюхивать? Тут головоломка на порядок сложнее.
и возвращаются оттуда же…
NowAndThen выше пишет что не оттуда, кто из вас прав ?
Мне казалось что в этом и смысл возни с Xhhtp - гонять трафик через цднку и маскировать айпи своего сервера.
цитата? я ничего не понял
Еще глюк обнаружился у этого сетапа. Хитрый юзерский ручной конфиг не стартует у меня при запуске V2RayN, нужно сначала выбрать какой-то другой конфиг, а потом переключиться на этот раздельный XHTTP. Т.е. в автозагрузке он не работает. И на Андроиде в V2RayNG запустить этот конфиг вообще не удалось. Вобщем, юзабельность этой технологии пока сильно в бета стадии.
Приветствую. Извиняюсь если подобный вопрос был, я не нашёл ответов.
Ловлю следующую ошибку:
[Info] transport/internet/splithttp: invalid x_padding length:0
Версии софта:
nginx/1.26.2Xray 24.12.31
Кто-нибудь сталкивался с подобным? Ниже приведу свои конфигурации nginx’а и xray’я как для сервера, так и для клиента.
На всякий случай сообщу что использую path поверх уже существующей конфигурации nginx’а под приложение. Однако, хочу заверить что схема с vless-nginx через websocket работала и работает, проблемы возникли при пробе XHTTP.
Некоторые переменные заменил, даю им здесь определение:
myhost- алиас сервера, не особо важно, просто строка для всяких директорийmy.host.com- домен для доступа к серверу через HTTP (ex: https://my.host.com/)mypath- путь в nginx’е перенаправляющий наxrayинстансmyuuid- мой uuid
Конфигурация nginx:
upstream myhost {
server unix:/srv/.venvs/myhost/run/gunicorn.sock fail_timeout=0;
}
server {
server_name my.host.com;
listen 80;
return 301 https://my.host.com$request_uri;
}
server {
server_name my.host.com;
listen 443 ssl;
listen 443 quic reuseport ipv6only=off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_certificate /etc/letsencrypt/live/my.host.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.host.com/privkey.pem;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GC M-SHA384;
client_header_timeout 5m;
keepalive_timeout 5m;
client_max_body_size 15M;
access_log /var/log/myhost/nginx/access/access.log;
error_log /var/log/myhost/nginx/error/error.log;
location /mypath {
client_max_body_size 0;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_body_timeout 5m;
grpc_read_timeout 315;
grpc_send_timeout 5m;
grpc_pass unix:/dev/shm/xrxh.socket;
}
location /static/ {
alias /srv/myhost/static/;
}
location / {
proxy_pass http://myhost/;
proxy_http_version 1.1;
proxy_connect_timeout 1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Конфигурация для xray server:
{
"log": {
"loglevel": "debug",
"access": "/var/log/xray/access.log",
"error": "/var/log/xray/error.log",
"dnsLog": false
},
"inbounds": [
{
"listen": "/dev/shm/xrxh.socket,0666",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "myuuid"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "xhttp",
"xhttpSettings": {
"mode": "stream-up",
"path": "/mypath"
}
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "blocked",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "blocked"
},
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
}
]
}
}
Конфигурация для xray client:
{
"log": {},
"inbounds": [
{
"port": "1080",
"listen": "127.0.0.1",
"protocol": "socks",
"settings": {
"udp": true
}
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "my.host.com",
"port": 443,
"users": [
{
"id": "myuuid",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "xhttp",
"xhttpSettings": {
"path": "/mypath",
"mode": "stream-up",
"#xmux": {
"maxConcurrency": 128,
"hMaxRequestTimes": 1000,
"hMaxReusableSecs": 3600
},
"#downloadSettings": {
"address": "my.host.com",
"port": 443,
"network": "xhttp",
"xhttpSettings": {
"path": "/mypath",
"#xmux": {
"maxConcurrency": 128,
"hMaxRequestTimes": 1000,
"hMaxReusableSecs": 3600
}
},
"security": "tls"
}
},
"security": "tls",
"tlsSettings": {
"alpn": [
"h3"
]
}
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "blocked",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
}
]
}
}
Попробуйте в xhttpSettings добавить такие параметры, это панель 3X-UI ставит по умолчанию, там, я смотрел, автор тупо рекомендуемые параметры из документации по умолчанию подставляет.
"scMaxBufferedPosts": 30,
"scMaxEachPostBytes": "1000000",
"xPaddingBytes": "100-1000"
Спасибо за ответ и приношу извинения за глупый вопрос, оказывается invalid x_padding length:0 не актуальная ошибка.
С моего клиента не приходили запросы на мой сервер, я решил попробовать пингануть path через curl, а в дальнейшем принял логи с curl’а как за те, что пришли с клиента. Спутал их. Очевидно что с курла будет ошибка авторизации и вообще там не был отправлен padding.
Настоящая проблема в том что запросы с клиента не доходят по какой-то причине, по всей видимости слишком криворукая конфигурация клиента/nginx’а. Попробую потом как-то решить.
2025/01/04 01:37:17 [Debug] [2049168422] transport/internet: dialing to udp:my.host.com:443
2025/01/04 01:37:17 [Info] [2049168422] transport/internet/splithttp: failed to POST https://my.host.com/mypath/7300f7be-ced5-411d-b209-ba16096ac392?x_padding=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 > Post "https://my.host.com/mypath/7300f7be-ced5-411d-b209-ba16096ac392?x_padding=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": lookup my.host.com: no such host
2025/01/04 01:37:17 [Info] [2049168422] proxy/vless/outbound: tunneling request to tcp:130.255.77.28:443 via my.host.com:443
2025/01/04 01:37:18 [Info] [2049168422] app/proxyman/inbound: connection ends > proxy/socks: connection ends > context canceled
2025/01/04 01:37:18 [Info] [1788824348] proxy/socks: TCP Connect request to tcp:130.255.77.28:443
2025/01/04 01:37:18 [Info] [1788824348] app/dispatcher: default route for tcp:130.255.77.28:443
2025/01/04 01:37:18 [Info] [1788824348] transport/internet/splithttp: XHTTP is dialing to udp:my.host.com:443, mode stream-up, HTTP version 3, host my.host.com
2025/01/04 01:37:18 [Debug] [1788824348] transport/internet: dialing to udp:my.host.com:443
2025/01/04 01:37:18 from tcp:127.0.0.1:65297 accepted tcp:130.255.77.28:443
2025/01/04 01:37:18 [Info] [1788824348] transport/internet/splithttp: failed to GET https://my.host.com/mypath/c6edd6a5-bf19-4a60-9c8a-681ea555b57e?x_padding=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 > Get "https://my.host.com/mypath/c6edd6a5-bf19-4a60-9c8a-681ea555b57e?x_padding=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": lookup my.host.com: no such host
2025/01/04 01:37:18 [Debug] [1788824348] transport/internet: dialing to udp:my.host.com:443
2025/01/04 01:37:18 [Info] [1788824348] transport/internet/splithttp: failed to POST https://my.host.com/mypath/c6edd6a5-bf19-4a60-9c8a-681ea555b57e?x_padding=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 > Post "https://my.host.com/mypath/c6edd6a5-bf19-4a60-9c8a-681ea555b57e?x_padding=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": lookup my.host.com: no such host
2025/01/04 01:37:18 [Info] [1788824348] proxy/vless/outbound: tunneling request to tcp:130.255.77.28:443 via my.host.com:443
2025/01/04 01:37:19 [Info] [1788824348] app/proxyman/inbound: connection ends > proxy/socks: connection ends > context canceled
2025/01/04 01:37:22 [Debug] app/log: Logger closing