6.3 KiB
Executable File
sdm-xray: stealth transport — спецификация для интеграции
Версия: v0.2.1 (черновик). Статус: работает (клиент/сервер — форк Xray-core).
1. Что это
stealth — кастомный сетевой транспорт для Xray-core (поле network: "stealth" в
streamSettings). Каждая туннельная сессия = один долгоживущий HTTP/2 POST-стрим
(ALPN h2): тело запроса несёт кадры клиент→сервер, тело ответа — кадры сервер→клиент
(двунаправленно, как gRPC/стриминговые загрузки). Снаружи выглядит как обычный HTTPS
к API-эндпоинту реального сайта.
Цель — анти-DPI: ротация путей на каждое соединение, браузерный TLS (uTLS chrome), padding/pacing, ретрай со сменой identity, зеркало реального сайта для зондов.
2. Конфигурация (streamSettings)
{
"network": "stealth",
"stealthSettings": {
"key": "<общий секрет, клиент и сервер совпадают>",
"padMax": 2048,
"padProb": 50,
"paceMs": 0,
"paceJitterMs": 0,
"path": "/", // один путь (fallback)
"paths": ["/api/t04d12b46/", "/api/v2/telemetry/", "/collect/", "/ingest/"],
"ports": [443], // опция: ротация портов
"bps": 0, // опция: rate-limit, 0 = выкл
"target": "https://www.iana.org", // опция: зеркало (сервер)
"decoy": false, // опция: фоновый трафик
"decoyEverySecs": 60,
"decoyTarget": "https://www.cloudflare.com/cdn-cgi/trace",
"padProfile": "browser", // "browser" | "uniform"
"retries": 3
},
"security": "tls", // или "reality"
"tlsSettings": {"serverName": "...", "fingerprint": "chrome"}
}
Клиент и сервер должны иметь одинаковые key, paths (список путей). Порты — только
на клиенте (сервер слушает каждый порт отдельным inbound).
3. Wire-протокол (поверх TLS+HTTP/2)
3.1 Установка сессии
- Клиент: TLS 1.3 (uTLS, fingerprint chrome, ALPN h2) к серверу:443.
- HTTP/2: клиент открывает один POST на один из
paths. - Тело запроса (клиент→сервер) — поток кадров. Первый кадр = AUTH:
[len][0xFE][key]. - Сервер читает AUTH:
- ключ верный → отвечает
200(заголовки + flush), дальше тело ответа — поток кадров сервер→клиент; - ключ неверный/нет →
404+ закрытие.
- ключ верный → отвечает
- После 200 обе стороны обмениваются кадрами DATA/PAD двунаправленно.
3.2 Формат кадра
[4 байта, big-endian длина = 1 + len(payload)] [1 байт type] [payload]
Типы:
| type | значение | смысл |
|---|---|---|
| DATA | 0x01 | данные туннеля (VLESS-поток) |
| PAD | 0x02 | padding (читатель пропускает) |
| AUTH | 0xFE | первый кадр тела запроса, payload = ключ |
| CLOSE | 0xFF | закрытие |
| Лимит кадра: 64 КБ. Поток байтов в DATA-кадрах сохраняет порядок (VLESS видит обычный | ||
| поток); PAD-кадры прозрачны для читателя. |
3.3 Сервер: зеркало для зондов
Не-туннельные запросы (GET/HEAD к любым путям) сервер реверсивно проксирует на
target (реальный сайт): переписывает Location, HTML href/src/content,
CSS url(...) на свой домен. POST на туннельные пути без валидного AUTH → 404.
Пустой target → встроенная страница-заглушка.
4. Клиент: ротация и ретрай
- Клиент на каждое соединение выбирает случайный путь из
paths. - При неудаче — ретрай со свежим путём/портом (
retries). - Padding: после каждого DATA-кадра с вероятностью
padProbидёт PAD-кадр размера доpadMax(профильbrowser— перекос к мелким). - Pacing:
paceMs+paceJitterMs(мин. интервал между кадрами). - Мультиплекс: несколько сессий идут по одному TLS+HTTP/2 каналу (несколько POST-стримов).
5. Требования к сборке
- Go 1.26, golang.org/x/net/http2, golang.org/x/time/rate, refraction-networking/utls.
config.proto→config.pb.goгенерится:protoc -I. --go_out=. --go_opt=paths=source_relative transport/internet/stealth/config.proto.- Бинарь:
go build ./main(клиент и сервер — один бинарь).
6. Файлы, которые нужно добавить/изменить в Xray-core
Новые (пакет транспорта):
transport/internet/stealth/config.proto(+ сгенерированныйconfig.pb.go)transport/internet/stealth/config.go— регистрация конфигаtransport/internet/stealth/framing.go— кадрыtransport/internet/stealth/conn.go— h2Conn (net.Conn поверх POST-стрима)transport/internet/stealth/dialer.go— клиент (TLS/REALITY, ротация, ретрай)transport/internet/stealth/hub.go— сервер (http.Server, зеркало, AUTH)
Изменённые (в infra/conf):
infra/conf/transport_internet.go—case "stealth", полеStealthSettings, ветка сборки, разрешение stealth в REALITY-проверкеinfra/conf/transport_method.go— structStealthConfig+Build()
Полный исходник и изменения — в репозитории (публичном): https://git.my-handbook.ru/ded_ikar/sdm-xray