doc: add YAML configuration support

This commit is contained in:
zarazaex69
2026-05-13 23:10:23 +03:00
parent 1e8f378844
commit 25d0e98698
13 changed files with 794 additions and 544 deletions

View File

@@ -23,7 +23,7 @@
11. [Mobile / Android](#11-mobile--android)
12. [Python PoC скрипты](#12-python-poc-скрипты)
13. [Сборка и деплой](#13-сборка-и-деплой)
14. [CLI - все флаги](#14-cli--все-флаги)
14. [YAML конфигурация](#14-yaml-конфигурация)
15. [URI-формат и подписки](#15-uri-формат-и-подписки)
16. [Матрица совместимости](#16-матрица-совместимости)
17. [CI/CD](#17-cicd)
@@ -89,9 +89,9 @@
**2026-04-25..30** - tile кодек для videochannel с Reed-Solomon коррекцией ошибок, `vp8channel` поверх KCP для надёжной доставки, замена самописного мультиплексора на smux.
**2026-05-01..06** - `seichannel` (данные в H264 SEI NAL-юнитах), E2E тесты на реальных провайдерах, URI-формат и формат подписок, `-client-id` для привязки клиента к серверу, SOCKS5 аутентификация.
**2026-05-01..06** - `seichannel` (данные в H264 SEI NAL-юнитах), E2E тесты на реальных провайдерах, URI-формат и формат подписок, SOCKS5 аутентификация.
**2026-05-07..10** - финальная полировка: исправлен throughput bug в vp8channel (ограничение было в 32 раза ниже реального), документация, SEI конфигурация, `-socks-user`/`-socks-pass`.
**2026-05-07..10** - финальная полировка: исправлен throughput bug в vp8channel (ограничение было в 32 раза ниже реального), документация, SEI конфигурация, SOCKS5 аутентификация (username/password).
### Статья на Хабре
@@ -144,7 +144,7 @@
Проект разбит на чёткие слои. Каждый слой можно заменить независимо.
```
cmd/olcrtc/ CLI entrypoint, парсинг флагов
cmd/olcrtc/ CLI entrypoint, загрузка YAML конфига
internal/app/session/ конфигурация, валидация, роутинг в server/client
│ │
@@ -199,28 +199,28 @@ internal/e2e/ E2E тесты на реальных провайдер
| Файл | Что делает |
|---|---|
| `main.go` | Точка входа. Парсит флаги (`flag.FlagSet`), настраивает логирование, подавляет шум LiveKit/pion в не-debug режиме, запускает `session.Run` или `session.Gen`. Graceful shutdown по SIGTERM/SIGINT с 5-секундным таймаутом |
| `main_test.go` | Юнит-тесты CLI: валидация флагов, режимы, edge cases |
| `main.go` | Точка входа. Загружает YAML конфиг (`olcrtc config.yaml`), настраивает логирование, подавляет шум LiveKit/pion в не-debug режиме, запускает `session.Run` или `session.Gen`. Graceful shutdown по SIGTERM/SIGINT с 5-секундным таймаутом |
| `main_test.go` | Юнит-тесты CLI: валидация конфига, режимы, edge cases |
### `internal/app/session/`
| Файл | Что делает |
|---|---|
| `session.go` | Главная точка конфигурации. `RegisterDefaults()` регистрирует все carriers, links, transports. `Validate()` проверяет все флаги. `Run()` роутит в `server.Run` или `client.Run`. `Gen()` генерирует Room ID для jazz с ретраями (wbstream больше не поддерживает автогенерацию - руму нужно создавать вручную через stream.wb.ru). `buildRoomURL()` строит URL для каждого carrier |
| `session.go` | Главная точка конфигурации. `RegisterDefaults()` регистрирует все carriers, links, transports. `Validate()` проверяет все настройки. `Run()` роутит в `server.Run` или `client.Run`. `Gen()` генерирует Room ID для jazz с ретраями (wbstream больше не поддерживает автогенерацию - руму нужно создавать вручную через stream.wb.ru) |
| `session_test.go` | Тесты валидации конфига |
### `internal/server/`
| Файл | Что делает |
|---|---|
| `server.go` | Серверная сторона туннеля. Подключается к комнате как второй участник звонка. Создаёт `muxconn``smux.Session`. Для каждого входящего smux-стрима читает JSON `ConnectRequest` от клиента с адресом назначения, устанавливает TCP соединение и гоняет байты туда-обратно. Поддерживает SOCKS5 прокси для исходящего трафика. Умеет переподключаться при разрыве |
| `server.go` | Серверная сторона туннеля. Подключается к комнате как второй участник звонка. Создаёт `muxconn``smux.Session`. Первый smux-стрим — контрольный (handshake CLIENT_HELLO / SERVER_WELCOME). Для каждого последующего стрима читает JSON `ConnectRequest` от клиента, устанавливает TCP соединение и гоняет байты. Поддерживает хуки: `OnSessionOpen`, `OnSessionClose`, `OnTraffic`. Умеет переподключаться при разрыве |
| `server_test.go` | Тесты серверной логики |
### `internal/client/`
| Файл | Что делает |
|---|---|
| `client.go` | Клиентская сторона. Поднимает SOCKS5-сервер. Для каждого входящего подключения: SOCKS5 handshake (поддержка RFC 1929 username/password auth), создаёт smux-стрим, шлёт JSON `ConnectRequest` с адресом, гоняет байты. Переподключается при разрыве WebRTC сессии |
| `client.go` | Клиентская сторона. Поднимает SOCKS5-сервер. Для каждого входящего подключения: SOCKS5 handshake (поддержка RFC 1929 username/password auth), создаёт smux-стрим, шлёт JSON `ConnectRequest` с адресом, гоняет байты. Первый smux-стрим — контрольный (handshake). Переподключается при разрыве WebRTC сессии с retry loop |
| `client_test.go` | Тесты клиентской логики |
### `internal/muxconn/`
@@ -343,9 +343,9 @@ internal/e2e/ E2E тесты на реальных провайдер
| Файл | Что делает |
|---|---|
| `srv.sh` | Интерактивный скрипт запуска сервера через Podman. Задаёт вопросы про carrier/transport/room/key, собирает образ, запускает контейнер. Флаги: `--branch=<name>` (сменить ветку), `--no-cache` (очистить Go-кеш перед сборкой) |
| `srv.sh` | Интерактивный скрипт запуска сервера через Podman. Задаёт вопросы про carrier/transport/room/key, генерирует YAML конфиг, собирает образ, запускает контейнер. Флаги: `--branch=<name>` (сменить ветку), `--no-cache` (очистить Go-кеш перед сборкой) |
| `cnc.sh` | Интерактивный скрипт запуска клиента через Podman |
| `docker/olcrtc-entrypoint.sh` | Docker entrypoint: читает env переменные, формирует CLI флаги, запускает `olcrtc` |
| `script/docker/olcrtc-entrypoint.sh` | Docker entrypoint: читает env переменные, генерирует YAML конфиг, запускает `olcrtc` |
| `docker/olcrtc-healthcheck.sh` | Docker healthcheck: проверяет что процесс запущен |
### `data/`
@@ -361,8 +361,8 @@ internal/e2e/ E2E тесты на реальных провайдер
|---|---|
| `fast.md` | Быстрый старт через скрипты (Podman) |
| `manual.md` | Мануальная сборка: Go, mage, кросс-компиляция, все шаги |
| `settings.md` | Матрица совместимости carrier×transport, все CLI флаги с описанием, готовые команды |
| `uri.md` | URI формат для клиентских приложений: `olcrtc://<Carrier>?<Transport>@<RoomID>#<Key>%<ClientID>$<MIMO>` |
| `settings.md` | Матрица совместимости carrier×transport, описание всех YAML полей, готовые примеры конфигов |
| `uri.md` | URI формат для клиентских приложений: `olcrtc://<Carrier>?<Transport>@<RoomID>#<Key>$<MIMO>` |
| `sub.md` | Формат подписок: список серверов в одном файле с метаданными |
---
@@ -377,7 +377,7 @@ Carrier - это WebRTC сервис видеозвонков, через кот
- Не требует регистрации для участника (только организатор)
- DataChannel работает, но Jazz **банит IP** за паттерны трафика характерные для DataChannel туннеля
- VideoTrack работает стабильно
- Поддерживает автогенерацию Room ID (`-mode gen`)
- Поддерживает автогенерацию Room ID (`mode: gen`)
- Инициализация звонка изнутри автоматически реализована
### Yandex Telemost (`telemost`)
@@ -394,7 +394,7 @@ Carrier - это WebRTC сервис видеозвонков, через кот
- **Рекомендуется** - самый стабильный
- Минимальная прослойка, почти прямой relay
- Работает со всеми транспортами: datachannel, vp8channel, seichannel, videochannel
- Поддерживает автогенерацию Room ID (`-mode gen`)
- Поддерживает автогенерацию Room ID (`mode: gen`)
- Инициализация звонка автоматически
---
@@ -419,7 +419,7 @@ Transport определяет как именно данные упаковыв
- Работает везде где есть VideoTrack (jazz, telemost, wbstream)
- Большой пинг из-за батчинга фреймов
- KCP параметры: MTU 1400, окно 4096, conv ID `0xC0FFEE01`
- Рекомендуется: `-vp8-fps 60 -vp8-batch 64`
- Рекомендуется: `vp8.fps: 60`, `vp8.batch_size: 64`
### seichannel
@@ -429,7 +429,7 @@ Transport определяет как именно данные упаковыв
- UUID для SEI payload: `5dc03ba8-450f-4b55-9a77-1f916c5b0739`
- ACK timeout (по умолчанию 3с), фрагментация, ретрансмиссия до 4 попыток
- Не работает с telemost
- Рекомендуется: `-fps 60 -batch 64 -frag 900 -ack-ms 2000`
- Рекомендуется: `sei.fps: 60`, `sei.batch_size: 64`, `sei.fragment_size: 900`, `sei.ack_timeout_ms: 2000`
### videochannel
@@ -475,7 +475,7 @@ WebRTC сам по себе шифрует трафик через DTLS-SRTP, н
**Поддерживается:**
- SOCKS5 (RFC 1928) с командой CONNECT
- Аутентификация username/password (RFC 1929) через `-socks-user`/`-socks-pass`
- Аутентификация username/password (RFC 1929) через `socks.user`/`socks.pass` в YAML конфиге
- SOCKS5h (hostname resolution на стороне сервера) - DNS запросы идут через туннель
- Без аутентификации (по умолчанию)
@@ -488,7 +488,7 @@ export all_proxy=socks5h://127.0.0.1:8808
export all_proxy=socks5h://user:pass@127.0.0.1:8808 # с авторизацией
```
**Сервер** (`srv`) может сам ходить через SOCKS5 прокси для исходящего трафика (`-socks-proxy`, `-socks-proxy-port`).
**Сервер** (`srv`) может сам ходить через SOCKS5 прокси для исходящего трафика (`socks.proxy_addr`, `socks.proxy_port` в YAML конфиге).
---
@@ -501,7 +501,7 @@ export all_proxy=socks5h://user:pass@127.0.0.1:8808 # с авторизацие
Community Android клиент: [alananisimov/olcbox](https://github.com/alananisimov/olcbox)
**API:**
- `Start(carrier, roomID, clientID, keyHex string)` - запустить туннель
- `Start(carrier, roomID, keyHex string)` - запустить туннель
- `Stop()` - остановить
- `IsRunning() bool`
- `SetProtector(p SocketProtector)` - Android VPN bypass (VpnService.protect)
@@ -582,106 +582,109 @@ cd olcrtc
# генерация ключа
openssl rand -hex 32
# генерация room ID (для jazz/wbstream)
./olcrtc -mode gen -carrier wbstream -dns 1.1.1.1:53 -amount 1 -data data
# создать конфиг (пример: wbstream + datachannel)
cat > server.yaml <<EOF
mode: srv
link: direct
auth:
provider: wbstream
room:
id: "ROOM_ID_HERE"
crypto:
key: "REPLACE_WITH_64_HEX"
net:
transport: datachannel
dns: "1.1.1.1:53"
data: data
EOF
# сервер
./olcrtc -mode srv -carrier wbstream -transport datachannel \
-id ROOM_ID -client-id default -key HEX_KEY \
-link direct -dns 1.1.1.1:53 -data data
# запустить сервер
./olcrtc server.yaml
# клиент
./olcrtc -mode cnc -carrier wbstream -transport datachannel \
-id ROOM_ID -client-id default -key HEX_KEY \
-link direct -dns 1.1.1.1:53 -data data \
-socks-host 127.0.0.1 -socks-port 8808
# конфиг клиента
cat > client.yaml <<EOF
mode: cnc
link: direct
auth:
provider: wbstream
room:
id: "ROOM_ID_HERE"
crypto:
key: "REPLACE_WITH_64_HEX"
net:
transport: datachannel
dns: "1.1.1.1:53"
socks:
host: "127.0.0.1"
port: 8808
data: data
EOF
# запустить клиент
./olcrtc client.yaml
```
### Docker
```sh
docker run -e OLCRTC_CARRIER=wbstream \
-e OLCRTC_ROOM_ID=... \
-e OLCRTC_KEY=... \
olcrtc/server:local
# Mount your YAML config into the container:
docker run -v ./server.yaml:/etc/olcrtc/server.yaml \
olcrtc/server:local /etc/olcrtc/server.yaml
```
---
## 14. CLI - все флаги
## 14. YAML конфигурация
### Обязательные (для всех режимов)
olcrtc читает конфигурацию из единственного YAML-файла. CLI-флагов нет.
| Флаг | Описание |
```sh
olcrtc config.yaml
```
Полная схема описана в [configuration.md](configuration.md). Примеры:
- [server.example.yaml](server.example.yaml)
- [client.example.yaml](client.example.yaml)
### Основные поля
| YAML путь | Описание |
|---|---|
| `-mode` | `srv` - сервер, `cnc` - клиент, `gen` - генерация Room ID |
| `-carrier` | `telemost`, `jazz`, `wbstream` |
| `-transport` | `datachannel`, `vp8channel`, `seichannel`, `videochannel` |
| `-id` | Room ID |
| `-client-id` | Идентификатор клиента, должен совпадать на srv и cnc. Один client-id может держать бесконечное количество соединений, но SFU ограничивает полосу на участника — оптимально 1 client-id = 1 пользователь (не обязательно) |
| `-key` | Ключ шифрования hex 64 символа |
| `-link` | Всегда `direct` |
| `-data` | Всегда `data` |
| `-dns` | DNS сервер, например `1.1.1.1:53` |
| `mode` | `srv` - сервер, `cnc` - клиент, `gen` - генерация Room ID |
| `link` | Всегда `direct` |
| `auth.provider` | `telemost`, `jazz`, `wbstream` или `none` |
| `room.id` | Room ID |
| `crypto.key` | Ключ шифрования hex 64 символа |
| `net.transport` | `datachannel`, `vp8channel`, `seichannel`, `videochannel` |
| `net.dns` | DNS сервер, например `1.1.1.1:53` |
| `data` | Путь к директории данных |
| `debug` | Verbose логи |
### Необязательные
### Только клиент (`mode: cnc`)
| Флаг | Описание |
| YAML путь | Описание |
|---|---|
| `-debug` | Verbose логи |
| `socks.host` | Адрес SOCKS5 (по умолчанию `127.0.0.1`) |
| `socks.port` | Порт SOCKS5 (по умолчанию `8808`) |
| `socks.user` | Логин (опционально) |
| `socks.pass` | Пароль (опционально) |
### Только для клиента (`-mode cnc`)
### Только сервер (`mode: srv`)
| Флаг | По умолчанию | Описание |
|---|---|---|
| `-socks-host` | `127.0.0.1` | Адрес SOCKS5 |
| `-socks-port` | `1080` | Порт SOCKS5 |
| `-socks-user` | - | Логин (опционально) |
| `-socks-pass` | - | Пароль (опционально) |
### Только для сервера (`-mode srv`)
| Флаг | Описание |
| YAML путь | Описание |
|---|---|
| `-socks-proxy` | Адрес SOCKS5 прокси для исходящего трафика |
| `-socks-proxy-port` | Порт этого прокси |
| `socks.proxy_addr` | Адрес SOCKS5 прокси для исходящего трафика |
| `socks.proxy_port` | Порт этого прокси |
### Режим генерации (`-mode gen`)
### Генерация (`mode: gen`)
| Флаг | Описание |
| YAML путь | Описание |
|---|---|
| `-amount` | Количество комнат для генерации |
| `gen.amount` | Количество комнат для генерации |
### vp8channel
### Транспорты
| Флаг | Default | Описание |
|---|---|---|
| `-vp8-fps` | 25 | FPS VP8 потока |
| `-vp8-batch` | 1 | Кадров за тик |
### seichannel
| Флаг | Default | Описание |
|---|---|---|
| `-fps` | 20 | FPS H264 потока |
| `-batch` | 1 | Кадров за тик |
| `-frag` | 900 | Размер фрагмента в байтах |
| `-ack-ms` | 2000 | ACK timeout в мс |
### videochannel
| Флаг | Default | Описание |
|---|---|---|
| `-video-codec` | `qrcode` | `qrcode` или `tile` |
| `-video-w` | 1920 | Ширина |
| `-video-h` | 1080 | Высота |
| `-video-fps` | 30 | FPS |
| `-video-bitrate` | `2M` | Битрейт |
| `-video-hw` | `none` | `none` или `nvenc` |
| `-video-qr-recovery` | `low` | ECC: `low`/`medium`/`high`/`highest` |
| `-video-qr-size` | 0 (авто) | Размер фрагмента QR в байтах |
| `-video-tile-module` | 4 | Размер тайла в пикселях 1..270 |
| `-video-tile-rs` | 20 | Reed-Solomon паритет % 0..200 |
Настройки транспортов задаются в секциях `vp8`, `sei`, `video` YAML конфига. Подробнее в [configuration.md](configuration.md).
---
@@ -692,16 +695,16 @@ docker run -e OLCRTC_CARRIER=wbstream \
Соглашение для клиентских приложений. Сам `olcrtc` не парсит - используется в сторонних клиентах.
```
olcrtc://<Carrier>?<Transport><payload>@<RoomID>#<Key>%<ClientID>$<MIMO>
olcrtc://<Carrier>?<Transport><payload>@<RoomID>#<Key>$<MIMO>
```
Где `<payload>` - опциональный блок `<key=value&...>` с параметрами транспорта.
**Примеры:**
```
olcrtc://wbstream?datachannel@room-01#d823fa...%android-01$RU / olc free sub
olcrtc://wbstream?vp8channel<vp8-fps=60&vp8-batch=64>@room-01#d823fa...%android-01$RU
olcrtc://telemost?seichannel<fps=60&batch=64&frag=900&ack-ms=2000>@room-01#d823fa...%client$RU
olcrtc://wbstream?datachannel@room-01#d823fa...$RU / olc free sub
olcrtc://wbstream?vp8channel<vp8-fps=60&vp8-batch=64>@room-01#d823fa...$RU
olcrtc://telemost?seichannel<fps=60&batch=64&frag=900&ack-ms=2000>@room-01#d823fa...$RU
```
### Формат подписки (sub.md)
@@ -714,7 +717,7 @@ olcrtc://telemost?seichannel<fps=60&batch=64&frag=900&ack-ms=2000>@room-01#d823f
#refresh: 10m
#icon: 🇷🇺
olcrtc://wbstream?datachannel@room-01#key%client-id$RU / free
olcrtc://wbstream?datachannel@room-01#key$RU / free
##name: RU-1
##ip: 1.2.3.4
##comment: basic free node
@@ -801,7 +804,7 @@ WB Stream - текущий приоритет. Основа уже реализ
| Issue | Что было |
|---|---|
| #44 | Very high ping - исправлен throughput bug vp8channel |
| #40 | Подключение нескольких устройств - реализовано через client-id |
| #40 | Подключение нескольких устройств |
| #39 | Oracle VPS поддержка |
| #38 | Стандартный URI формат - реализован |
| #37 | Jitsi Meet - не планируется |
@@ -861,9 +864,10 @@ dial tcp: lookup stream.wb.ru: i/o timeout
77.88.8.8:53
```
При ручном запуске:
```sh
./olcrtc -mode cnc ... -dns 8.8.8.8:53
При ручном запуске — указать другой DNS в YAML конфиге:
```yaml
net:
dns: "8.8.8.8:53"
```
После смены DNS в логах должна появиться строка:
@@ -875,7 +879,7 @@ SOCKS5 server listening on 0.0.0.0:8808
**Симптомы:**
В логах сервера (`-mode srv`) появляются строки вида:
В логах сервера появляются строки вида:
```
sid=59 dial 157.240.205.60:443 failed (10.000774052s): dial failed: dial tcp4 157.240.205.60:443: i/o timeout
sid=69 dial 194.221.250.50:443 failed (10.002092858s): dial failed: dial tcp4 194.221.250.50:443: i/o timeout
@@ -901,9 +905,11 @@ curl -v --connect-timeout 5 https://149.154.167.41
**Решение:**
1. Сменить хостинг-провайдера или локацию на того, кто не блокирует исходящий трафик.
2. Использовать на сервере исходящий SOCKS5 прокси (`-socks-proxy`/`-socks-proxy-port`), который не заблокирован:
```sh
./olcrtc -mode srv ... -socks-proxy 1.2.3.4 -socks-proxy-port 1080
2. Использовать на сервере исходящий SOCKS5 прокси через YAML конфиг:
```yaml
socks:
proxy_addr: "1.2.3.4"
proxy_port: 1080
```
Это ошибка не на стороне olcRTC - он корректно логирует ошибки и продолжает работу. Соединения к незаблокированным адресам проходят без проблем. Проблема на стороне хостинга или фаервола.