# Флаги ## Клиент | Флаг | По умолчанию | Описание | | --- | --- | --- | | `-listen` | `127.0.0.1:9000` | локальный адрес `ip:port`, куда подключается WireGuard (UDP) или Xray/sing-box (TCP) клиент | | `-peer` | **обязательный** | адрес сервера на VPS, `host:port` | | `-provider` | `vk` | источник TURN-creds: `vk` (см. `docs/providers.md`) | | `-link` | пусто | (устарел) одна ссылка VK Calls `https://vk.ru/call/join/...`; используйте `-links`. Игнорируется, если задан `-links` | | `-links` | **обязательный для `-provider vk`** (или `-link`) | ссылки VK Calls через запятую `https://vk.ru/call/join/A,https://vk.ru/call/join/B`; каждая даёт свой пул из `-n` стримов | | `-n` | `10` | параллельных TURN-потоков; в `-mode tcp` это число сессий пула, по которым round-robin раскладываются локальные TCP-соединения | | `-transport` | `tcp` | транспорт до TURN-реле: `tcp` (TCP/TLS) \| `udp` | | `-mode` | `udp` | режим туннеля: `udp` (UDP-релей для WireGuard) \| `tcp` (TCP-форвардер для Xray/sing-box) | | `-turn` | из creds | переопределить IP TURN-сервера | | `-port` | из creds | переопределить порт TURN-сервера | | `-obf-profile` | `none` | wire-профиль обфускации payload: `none` \| `rtpopus` (RTP/opus + ChaCha20-Poly1305 AEAD) \| `rtpopus2` (+ RTP header extension, ближе к WebRTC) \| `rtpopus3` (+ abs-send-time, VAD, имитация потерь, вариативный timestamp); должен совпадать с сервером | | `-obf-key` | пусто | общий ключ для `-obf-profile != none`, 32 байта hex (64 символа) | | `-obf-timing` | `0` | межпакетная задержка для RTP-мимикрии (напр. `20ms`); только с `-obf-profile != none`; `0` = выкл. В `-mode tcp` особенно уместна: KCP гонит бёрсты полноразмерных пакетов, без выравнивания профиль на Opus не похож | | `-gen-obf-key` | `false` | напечатать новый ключ и выйти | | `-manual-captcha` | `false` | сразу ручной режим captcha (только `-provider vk`) | | `-streams-per-cred` | `10` | потоков на один кеш VK-учёток (только `-provider vk`) | | `-platform` | `desktop` | класс устройства персоны VK-auth (мобильность UA/device/client hints): `desktop` \| `mobile` (только `-provider vk`) | | `-dns-mode` | `auto` | `plain` (UDP/53) \| `doh` \| `auto` | | `-dns-servers` | пусто | свои UDP/53 резолверы, `ip[:port][,ip[:port]...]` | | `-client-id` | авто | уникальный ID клиента (автогенерация если не задан) | | `-sub` | пусто | URL подписки (sub.md) для получения списка серверов | | `-debug` | `false` | debug-логи | ## KCP (только `-mode tcp`, клиент и сервер) Флаги настраивают ARQ-слой, который держит TCP-поток поверх датаграмм TURN. Задаются на каждой стороне отдельно; в `-mode udp` любое отличие от дефолта - ошибка запуска. В share-ссылке профиль едет полем `kcp`, так что гость получает тот же ARQ, что настроил владелец. | Флаг | По умолчанию | Описание | | --- | --- | --- | | `-kcp-nodelay` | `1` | `0` (обычный) \| `1` (быстрый режим) | | `-kcp-interval` | `20` | интервал внутреннего цикла KCP, мс; больше = меньше служебного трафика | | `-kcp-resend` | `2` | быстрая повторная отправка после N дубликатов ACK; `0` = выкл | | `-kcp-nc` | `1` | congestion control: `0` (вкл) \| `1` (выкл) | | `-kcp-sndwnd` | `512` | окно отправки в пакетах | | `-kcp-rcvwnd` | `512` | окно приёма в пакетах | | `-kcp-mtu` | `1200` | MTU сегмента KCP, байты; допустимо `300..1350` | | `-kcp-acknodelay` | `true` | отправлять ACK сразу: ниже задержка, выше служебный трафик | На мобильной сети дефолт заметно шумит; щадящий вариант - `-kcp-interval 40 -kcp-sndwnd 256 -kcp-rcvwnd 256 -kcp-acknodelay=false`. ## Сервер | Флаг | По умолчанию | Описание | | --- | --- | --- | | `-listen` | `0.0.0.0:56000` | адрес прослушивания `ip:port` | | `-connect` | **обязательный** | локальный backend `host:port` (WG `127.0.0.1:51820` / Xray `127.0.0.1:443`) | | `-mode` | `udp` | режим туннеля: `udp` \| `tcp`; должен совпадать с клиентом | | `-obf-profile` | `none` | wire-профиль обфускации payload: `none` \| `rtpopus` \| `rtpopus2` \| `rtpopus3`; должен совпадать с клиентом (описание профилей - в таблице клиента) | | `-obf-timing` | `0` | межпакетная задержка для RTP-мимикрии (напр. `10ms`); только с `-obf-profile != none`; `0` = выкл | | `-obf-key` | пусто | общий ключ для `-obf-profile != none`, 32 байта hex | | `-gen-obf-key` | `false` | напечатать новый ключ и выйти | | `-clients-file` | пусто | путь к JSON-файлу (`clients.json`) для включения авторизации по Client ID | | `-debug` | `false` | debug-логи | ## Управление Client ID (Команды Сервера) > [!NOTE] > **Про авторизацию:** клиент **всегда** отправляет свой Client ID первой записью после DTLS-handshake, сервер **всегда** его читает - wire-контракт симметричен. Флаг `-clients-file` на сервере включает **проверку** ID по allowlist (`clients.json`). Без `-clients-file` ID читается и игнорируется. Сервер содержит встроенные команды для управления файлом `clients.json` (горячая перезагрузка поддерживается автоматически, перезапускать сервер после изменений не нужно). ```bash # Добавить или обновить клиента ./server clients add ["Комментарий"] # Удалить клиента ./server clients remove # Вывести список всех клиентов ./server clients list ``` По умолчанию команды работают с файлом `clients.json` в текущей директории. Если вы используете другой путь, задайте его через переменную окружения `CLIENTS_FILE`: ```bash CLIENTS_FILE=/etc/free-turn-proxy/clients.json ./server clients list ``` ### Управление через Docker Если сервер запущен в Docker-контейнере (например, с именем `free-turn-proxy`), вы можете использовать команду `docker exec` для управления клиентами без необходимости заходить внутрь контейнера или редактировать файл вручную: ```bash # Добавить клиента docker exec -it free-turn-proxy /app/server clients add "my-client" "Комментарий" # Удалить клиента docker exec -it free-turn-proxy /app/server clients remove "my-client" # Посмотреть список docker exec -it free-turn-proxy /app/server clients list ``` > **Важно:** команды `docker exec` берут путь к файлу из переменной окружения `CLIENTS_FILE` контейнера. Это работает, только если контейнер запущен с включённой авторизацией (т.е. `CLIENTS_FILE` задан в `docker-compose.yml` и файл проброшен через `volumes`). Если авторизация выключена, `clients` пишет в эфемерный `clients.json` внутри контейнера, который сервер не читает. Путь должен совпадать с тем, что смонтирован и передан в `-clients-file`.