Files
sdm-xray/PROTOCOL.md
T

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 Установка сессии

  1. Клиент: TLS 1.3 (uTLS, fingerprint chrome, ALPN h2) к серверу:443.
  2. HTTP/2: клиент открывает один POST на один из paths.
  3. Тело запроса (клиент→сервер) — поток кадров. Первый кадр = AUTH: [len][0xFE][key].
  4. Сервер читает AUTH:
    • ключ верный → отвечает 200 (заголовки + flush), дальше тело ответа — поток кадров сервер→клиент;
    • ключ неверный/нет → 404 + закрытие.
  5. После 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 — struct StealthConfig + Build()

Полный исходник и изменения — в репозитории (публичном): https://git.my-handbook.ru/ded_ikar/sdm-xray