104 lines
6.3 KiB
Markdown
Executable File
104 lines
6.3 KiB
Markdown
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)
|
|
```json
|
|
{
|
|
"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
|