mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
docs: переместить route-скрипты в scripts/, исправить пайп с -debug 2>&1
- routes.{sh,ps1,macos.sh} → scripts/; старые файлы из корня удалены
- унифицирован парсинг: TURN server IP, relayed-address=, CIDR, plain IP
- исправлен баг доки: логи клиента идут в stderr, пайп требует -debug 2>&1
- quickstart.md переписан: секция маршрутов, команды трёх платформ
- troubleshooting.md: обновлены пути и примечание про -debug
This commit is contained in:
@@ -1,401 +1,24 @@
|
||||
# VK TURN Proxy
|
||||
<div align="center">
|
||||
|
||||
VK TURN Proxy - клиент и сервер для прокидывания локального UDP/TCP-трафика через TURN-реле, получаемые из ссылки на VK Calls. Типичный сценарий - поднять небольшой `server` на VPS рядом с WireGuard или Xray, а на клиентском устройстве запустить `client`, который слушает локальный адрес вроде `127.0.0.1:9000`.
|
||||
<img src="logo.webp" width="250" height="250">
|
||||
|
||||
> [!CAUTION]
|
||||
> Проект предназначен для обучения, исследований и администрирования собственных стендов. Используйте его только там, где у вас есть право запускать такой трафик и менять сетевую конфигурацию.
|
||||

|
||||

|
||||
</div>
|
||||
|
||||
## Содержание
|
||||
## О проекте
|
||||
|
||||
- [Как это работает](#как-это-работает)
|
||||
- [Возможности](#возможности)
|
||||
- [Что нужно](#что-нужно)
|
||||
- [Быстрый старт: WireGuard](#быстрый-старт-wireguard)
|
||||
- [Запуск сервера на VPS](#1-запустите-сервер-на-vps)
|
||||
- [Настройка WireGuard](#2-настройте-wireguard-на-клиенте)
|
||||
- [Запуск клиента](#3-запустите-клиент)
|
||||
- [Android через Termux](#android-через-termux)
|
||||
- [iOS через iSH](#ios-через-ish)
|
||||
- [systemd-сервис](#сервер-как-systemd-сервис)
|
||||
- [Docker](#docker)
|
||||
- [VLESS / Xray](#vless--xray)
|
||||
- [WRAP-режим](#wrap-режим)
|
||||
- [Яндекс Телемост](#яндекс-телемост)
|
||||
- [Флаги клиента](#флаги-клиента)
|
||||
- [Флаги сервера](#флаги-сервера)
|
||||
- [Captcha](#captcha)
|
||||
- [Сборка из исходников](#сборка-из-исходников)
|
||||
- [Решение проблем](#решение-проблем)
|
||||
- [Похожие проекты](#похожие-проекты)
|
||||
- [Лицензия](#лицензия)
|
||||
**btp** - туннель UDP/TCP через TURN-реле VK Calls. Клиент берёт временные TURN-учётки из ссылки на звонок и гонит ваш
|
||||
трафик (WireGuard, Xray/VLESS) до сервера на VPS поверх DTLS.
|
||||
|
||||
## Как Это Работает
|
||||
## Быстрый старт
|
||||
|
||||
Схема для WireGuard:
|
||||
|
||||
```text
|
||||
WireGuard client -> 127.0.0.1:9000 -> VK TURN Proxy client
|
||||
-> VK TURN relay -> VK TURN Proxy server на VPS
|
||||
-> 127.0.0.1:<порт WireGuard> -> WireGuard server
|
||||
```
|
||||
|
||||
Клиент берет временные TURN-учетные данные из ссылки VK Calls, открывает одно или несколько соединений к TURN-реле и отправляет через них трафик к вашему `server`. Между `client` и `server` используется DTLS. Для WireGuard сервер пересылает данные в UDP backend, для VLESS/Xray - в TCP backend через KCP и smux.
|
||||
<div align="center">
|
||||
|
||||
## Возможности
|
||||
---
|
||||
|
||||
- VK Calls как основной источник TURN-учетных данных.
|
||||
- TCP или UDP подключение клиента к TURN-реле.
|
||||
- Несколько параллельных TURN-потоков через `-n`.
|
||||
- WireGuard/Hysteria-подобный UDP backend.
|
||||
- VLESS/Xray TCP backend через `-vless`.
|
||||
- Bonding для VLESS через `-vless-bond`.
|
||||
- Дополнительная WRAP-обфускация DTLS-пакетов через `-wrap`.
|
||||
- Автоматическое и ручное прохождение VK captcha.
|
||||
- Docker-образ для серверной части.
|
||||
Telegram канал: [Free Turn](https://t.me/+5BdkU4q_CGQyNTdi)
|
||||
|
||||
## Что Нужно
|
||||
|
||||
- VPS с публичным IP.
|
||||
- На VPS уже должен слушать backend:
|
||||
- WireGuard: обычно `127.0.0.1:51820/udp`;
|
||||
- Xray/VLESS: обычно `127.0.0.1:443/tcp`.
|
||||
- Ссылка на активный VK Calls вида `https://vk.com/call/join/...`.
|
||||
- На клиенте: WireGuard, Xray или другой локальный клиент, который будет ходить в `127.0.0.1:9000`.
|
||||
|
||||
Ссылку VK Calls лучше создать самостоятельно. Не завершайте звонок для всех, если хотите использовать эту ссылку дальше.
|
||||
|
||||
## Быстрый Старт: WireGuard
|
||||
|
||||
### 1. Запустите Сервер На VPS
|
||||
|
||||
Скачайте бинарник для Linux amd64:
|
||||
|
||||
```bash
|
||||
curl -L -o server https://github.com/samosvalishe/btp/releases/latest/download/server-linux-amd64
|
||||
chmod +x server
|
||||
```
|
||||
|
||||
Запустите `server`, указав локальный адрес WireGuard:
|
||||
|
||||
```bash
|
||||
./server -listen 0.0.0.0:56000 -connect 127.0.0.1:51820
|
||||
```
|
||||
|
||||
Порт `56000/udp` должен быть доступен снаружи. Если WireGuard слушает другой порт, замените `51820`.
|
||||
|
||||
### 2. Настройте WireGuard На Клиенте
|
||||
|
||||
В клиентском конфиге WireGuard замените endpoint сервера на локальный адрес VK TURN Proxy:
|
||||
|
||||
```ini
|
||||
Endpoint = 127.0.0.1:9000
|
||||
MTU = 1280
|
||||
```
|
||||
|
||||
На Android добавьте Termux или приложение-клиент в исключения WireGuard. На Windows, Linux и macOS перед включением WireGuard нужно добавить маршрут до TURN-реле, иначе клиент может попытаться подключаться к TURN уже через сам VPN.
|
||||
|
||||
### 3. Запустите Клиент
|
||||
|
||||
Linux:
|
||||
|
||||
```bash
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-linux-amd64
|
||||
chmod +x client
|
||||
./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>" | ./routes.sh
|
||||
```
|
||||
|
||||
Windows PowerShell от администратора:
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest -Uri https://github.com/samosvalishe/btp/releases/latest/download/client-windows-amd64.exe -OutFile client.exe
|
||||
.\client.exe -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>" | .\routes.ps1
|
||||
```
|
||||
|
||||
macOS:
|
||||
|
||||
```bash
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-darwin-arm64
|
||||
chmod +x client
|
||||
./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>" | ./routes-macos.sh
|
||||
```
|
||||
|
||||
После появления соединения включите WireGuard.
|
||||
|
||||
Если вы скачали только бинарник, но не клонировали репозиторий, возьмите нужный route-скрипт из этого репозитория: `routes.sh`, `routes.ps1` или `routes-macos.sh`.
|
||||
|
||||
## Android Через Termux
|
||||
|
||||
1. Установите Termux из F-Droid.
|
||||
2. В WireGuard укажите `Endpoint = 127.0.0.1:9000` и `MTU = 1280`.
|
||||
3. Добавьте Termux в исключения WireGuard.
|
||||
4. Запустите в Termux:
|
||||
|
||||
```bash
|
||||
termux-wake-lock
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-android-arm64
|
||||
chmod +x client
|
||||
./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>"
|
||||
```
|
||||
|
||||
Чтобы снять wake lock:
|
||||
|
||||
```bash
|
||||
termux-wake-unlock
|
||||
```
|
||||
|
||||
## iOS Через iSH
|
||||
|
||||
Это запасной вариант, если нет нативного клиента.
|
||||
|
||||
```bash
|
||||
apk update
|
||||
apk add curl
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-linux-386
|
||||
chmod +x client
|
||||
GOMAXPROCS=1 GODEBUG=asyncpreemptoff=1 ./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>"
|
||||
```
|
||||
|
||||
Чтобы iSH дольше жил в фоне, можно в начале сессии выполнить:
|
||||
|
||||
```bash
|
||||
cat /dev/location > /dev/null &
|
||||
```
|
||||
|
||||
## Сервер Как systemd-Сервис
|
||||
|
||||
Пример `/etc/systemd/system/btp.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=VK TURN Proxy server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/btp/server -listen 0.0.0.0:56000 -connect 127.0.0.1:51820
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
User=nobody
|
||||
Group=nogroup
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Применить:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now btp.service
|
||||
sudo systemctl status btp.service
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
Образ публикуется в GitHub Container Registry:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/samosvalishe/btp:latest
|
||||
```
|
||||
|
||||
Если backend слушает на хосте, удобнее использовать host network:
|
||||
|
||||
```bash
|
||||
docker run --rm --network host \
|
||||
-e CONNECT_ADDR=127.0.0.1:51820 \
|
||||
ghcr.io/samosvalishe/btp:latest
|
||||
```
|
||||
|
||||
Bridge mode:
|
||||
|
||||
```bash
|
||||
docker run --rm -p 56000:56000/udp \
|
||||
-e CONNECT_ADDR=<host-ip>:51820 \
|
||||
ghcr.io/samosvalishe/btp:latest
|
||||
```
|
||||
|
||||
Переменные окружения:
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
| --- | --- | --- |
|
||||
| `CONNECT_ADDR` | обязательна | backend, куда сервер пересылает трафик |
|
||||
| `LISTEN_ADDR` | `0.0.0.0:56000` | адрес прослушивания сервера |
|
||||
| `VLESS_MODE` | `false` | включает `-vless` |
|
||||
| `VLESS_BOND` | `false` | включает `-vless-bond` |
|
||||
| `WRAP_MODE` | `false` | включает `-wrap` |
|
||||
| `WRAP_KEY` | пусто | ключ для `-wrap-key` |
|
||||
| `VK_TURN_KCP_PROFILE` | `balanced` | профиль KCP (`fast`, `balanced`, `slow`) |
|
||||
| `VK_TURN_KCP_MTU` | `1200` | переопределить MTU для KCP |
|
||||
|
||||
Сборка образа вручную:
|
||||
|
||||
```bash
|
||||
docker build -t btp .
|
||||
```
|
||||
|
||||
## VLESS / Xray
|
||||
|
||||
В режиме `-vless` VK TURN Proxy прокидывает TCP-соединения. На VPS `server` подключается к локальному TCP backend, например к Xray inbound на `127.0.0.1:443`. На клиенте `client` слушает локальный TCP адрес, на который должен смотреть ваш Xray/v2rayN/sing-box клиент.
|
||||
|
||||
Сервер:
|
||||
|
||||
```bash
|
||||
./server -listen 0.0.0.0:56000 -connect 127.0.0.1:443 -vless
|
||||
```
|
||||
|
||||
Клиент:
|
||||
|
||||
```bash
|
||||
./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>" -vless
|
||||
```
|
||||
|
||||
С bonding:
|
||||
|
||||
```bash
|
||||
./server -listen 0.0.0.0:56000 -connect 127.0.0.1:443 -vless
|
||||
./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>" -vless -vless-bond -n 4
|
||||
```
|
||||
|
||||
## WRAP-Режим
|
||||
|
||||
`-wrap` маскирует TURN-payload под SRTP: добавляет RTP/opus-заголовок и шифрует тело ChaCha20-Poly1305 AEAD. Это не защита (DTLS уже шифрует внутренний канал), а обфускация под голосовой трафик, чтобы content-filter VK не дропал пакеты. Ключ должен совпадать на клиенте и сервере.
|
||||
|
||||
Сгенерировать ключ:
|
||||
|
||||
```bash
|
||||
./server -gen-wrap-key
|
||||
```
|
||||
|
||||
Запуск:
|
||||
|
||||
```bash
|
||||
./server -listen 0.0.0.0:56000 -connect 127.0.0.1:51820 -wrap -wrap-key <64-hex-key>
|
||||
./client -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>" -wrap -wrap-key <64-hex-key>
|
||||
```
|
||||
|
||||
> **Breaking change (V2-0):** удалены клиентский `-no-dtls` и **серверный** `-vless-bond`.
|
||||
> Клиентский `-vless-bond` сохранён — это и есть переключатель bonding.
|
||||
> `-no-dtls` помечался DO NOT USE и в проде не работал (VK дропает пакеты без DTLS-handshake).
|
||||
> Серверный `-vless-bond` больше не нужен: сервер автоопределяет bond по magic-префиксу в каждом стриме.
|
||||
|
||||
## Настройка KCP (VLESS)
|
||||
|
||||
В режиме `-vless` для передачи данных поверх DTLS используется KCP. Его можно настроить через переменные окружения (работает и для клиента, и для сервера):
|
||||
|
||||
| Переменная | Профили / Значения | Описание |
|
||||
| --- | --- | --- |
|
||||
| `VK_TURN_KCP_PROFILE` | `fast`, `balanced`, `slow` | Предустановленные режимы работы KCP. |
|
||||
| `VK_TURN_KCP_MTU` | например, `1200` | Максимальный размер пакета. |
|
||||
|
||||
**Профили:**
|
||||
- `fast` (или `legacy`): Минимальные задержки, активная переотправка, MTU 1280.
|
||||
- `balanced` (или `cc`): Оптимальный баланс для большинства сетей, MTU 1200.
|
||||
- `slow` (или `conservative`): Для очень нестабильных каналов, MTU 1150.
|
||||
|
||||
Для более тонкой настройки доступны переменные: `VK_TURN_KCP_NODELAY`, `VK_TURN_KCP_INTERVAL`, `VK_TURN_KCP_RESEND`, `VK_TURN_KCP_NC`, `VK_TURN_KCP_SNDWND`, `VK_TURN_KCP_RCVWND`, `VK_TURN_KCP_ACK_NODELAY`.
|
||||
|
||||
**FEC (Reed-Solomon):** `VK_TURN_KCP_FEC=data:parity` (например, `10:3`) — упреждающая коррекция ошибок. На каждые `data` пакетов добавляется `parity` избыточных, потери до `parity` из `data+parity` восстанавливаются без ретрансмита. Overhead по полосе: `parity/data` (для `10:3` — 30%). Должно совпадать на клиенте и сервере. По умолчанию выключено (`0:0`). Включай только при случайных потерях; при шейпе по полосе FEC ухудшит goodput.
|
||||
|
||||
|
||||
## Флаги Клиента
|
||||
|
||||
| Флаг | По умолчанию | Описание |
|
||||
| --- | --- | --- |
|
||||
| `-listen` | `127.0.0.1:9000` | локальный адрес `ip:port`, куда подключается WireGuard или Xray клиент |
|
||||
| `-peer` | обязательный | адрес сервера VK TURN Proxy на VPS, `host:port` (например `<ip-vps>:56000`) |
|
||||
| `-vk-link` | обязательный | ссылка VK Calls вида `https://vk.com/call/join/...` |
|
||||
| `-n` | `10` | количество параллельных TURN-потоков (соединений к TURN-реле) |
|
||||
| `-udp` | `false` | подключаться к TURN-реле по UDP (по умолчанию TCP/TLS) |
|
||||
| `-turn` | из ссылки | переопределить IP TURN-сервера |
|
||||
| `-port` | из ссылки | переопределить порт TURN-сервера |
|
||||
| `-vless` | `false` | режим TCP-форвардера (VLESS/Xray) вместо UDP-релея для WireGuard |
|
||||
| `-vless-bond` | `false` | распределять одно VLESS TCP-соединение по всем активным smux-сессиям (только с `-vless`) |
|
||||
| `-wrap` | `false` | маскировать TURN-payload под SRTP (см. [WRAP-режим](#wrap-режим)); ключ должен совпадать с сервером |
|
||||
| `-wrap-key` | пусто | общий ключ для `-wrap`, 32 байта в hex (64 символа) |
|
||||
| `-gen-wrap-key` | `false` | напечатать новый ключ для `-wrap-key` и выйти |
|
||||
| `-manual-captcha` | `false` | пропустить авто-решение captcha и сразу открыть ручной режим в локальном браузере |
|
||||
| `-streams-per-cred` | `10` | сколько TURN-потоков делят один кеш VK-учёток |
|
||||
| `-dns` | `auto` | режим DNS-резолвинга: `udp` \| `doh` \| `auto` (UDP/53, sticky-fallback на DoH) |
|
||||
| `-dns-servers` | пусто | список UDP/53 DNS-серверов через запятую вместо встроенных, формат `ip[:port][,ip[:port]...]` |
|
||||
| `-debug` | `false` | включить подробные debug-логи |
|
||||
|
||||
## Флаги Сервера
|
||||
|
||||
| Флаг | По умолчанию | Описание |
|
||||
| --- | --- | --- |
|
||||
| `-listen` | `0.0.0.0:56000` | локальный адрес прослушивания `ip:port` |
|
||||
| `-connect` | обязательный | адрес локального бэкенда `host:port` (WireGuard `127.0.0.1:51820` или Xray `127.0.0.1:443`) |
|
||||
| `-vless` | `false` | режим TCP-форвардера (VLESS/Xray) вместо UDP-релея; bond определяется автоматически по magic-префиксу в стриме |
|
||||
| `-wrap` | `false` | маскировать TURN-payload под SRTP (см. [WRAP-режим](#wrap-режим)); ключ должен совпадать с клиентом |
|
||||
| `-wrap-key` | пусто | общий ключ для `-wrap`, 32 байта в hex (64 символа) |
|
||||
| `-gen-wrap-key` | `false` | напечатать новый ключ для `-wrap-key` и выйти |
|
||||
| `-debug` | `false` | включить подробные debug-логи |
|
||||
|
||||
## Captcha
|
||||
|
||||
Для VK Calls клиент умеет автоматически проходить captcha. Если автоматика не сработала, включается ручной сценарий через локальный браузер. Можно сразу запросить ручной режим:
|
||||
|
||||
```bash
|
||||
./client -manual-captcha -listen 127.0.0.1:9000 -peer <ip-vps>:56000 -vk-link "<vk-call-link>"
|
||||
```
|
||||
|
||||
Профиль браузера сохраняется в `vk_profile.json` рядом с бинарником и может помочь последующим запросам выглядеть последовательнее.
|
||||
|
||||
## Сборка Из Исходников
|
||||
|
||||
Нужен Go 1.25.x.
|
||||
|
||||
```bash
|
||||
go build -o client ./cmd/client
|
||||
go build -o server ./cmd/server
|
||||
go test ./...
|
||||
```
|
||||
|
||||
Кросс-сборка примера для Linux amd64:
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o server-linux-amd64 ./cmd/server
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o client-linux-amd64 ./cmd/client
|
||||
```
|
||||
|
||||
Android arm64 клиент как `.so` для упаковки в приложение (PowerShell):
|
||||
|
||||
```powershell
|
||||
$env:GOOS="android"; $env:GOARCH="arm64"; $env:CGO_ENABLED="0"; go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn.so .\cmd\client
|
||||
```
|
||||
|
||||
То же из bash:
|
||||
|
||||
```bash
|
||||
GOOS=android GOARCH=arm64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn.so ./cmd/client
|
||||
```
|
||||
|
||||
Linux arm64 клиент как `.so` (для упаковки в Android-приложение в обход NDK; ABI совпадает):
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn.so ./cmd/client
|
||||
```
|
||||
|
||||
Linux amd64 клиент/сервер как `.so`:
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn-client.so ./cmd/client
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn-server.so ./cmd/server
|
||||
```
|
||||
|
||||
Все `.so` выше — обычные ELF-бинари под `.so`-именем (`CGO_ENABLED=0`, не настоящий shared library). Если нужен настоящий `c-shared` — `CGO_ENABLED=1` + NDK toolchain (см. `.github/workflows/release.yml`).
|
||||
|
||||
## Решение Проблем
|
||||
|
||||
- Сначала запускайте VK TURN Proxy client, потом включайте WireGuard.
|
||||
- Если WireGuard забирает весь трафик, добавьте маршрут до IP TURN-реле через `routes.sh`, `routes.ps1` или `routes-macos.sh`.
|
||||
- Если TCP до TURN не работает, попробуйте `-udp`.
|
||||
- Если соединение нестабильное, попробуйте уменьшить `-n`, например `-n 1`.
|
||||
- Если VK просит captcha слишком часто, попробуйте `-manual-captcha`, затем повторите обычный запуск.
|
||||
- Если клиент зависает на получении TURN-данных, проверьте, что ссылка VK Calls живая и не была завершена для всех.
|
||||
- Если сервер запущен в Docker bridge mode, `CONNECT_ADDR=127.0.0.1:51820` укажет внутрь контейнера, а не на хост. Используйте host network или IP хоста.
|
||||
- Если включен `-wrap`, убедитесь, что и клиент, и сервер используют одинаковый `-wrap-key`.
|
||||
|
||||
## Лицензия
|
||||
|
||||
GPL-3.0. См. [LICENSE](LICENSE).
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
# Документация
|
||||
|
||||
- [Быстрый старт (WireGuard)](quickstart.md)
|
||||
- [Режимы: UDP / VLESS / WRAP / KCP](modes.md)
|
||||
- [Флаги клиента и сервера](flags.md)
|
||||
- [Развёртывание: systemd, Docker](deploy.md)
|
||||
- [Мобильные: Android (Termux), iOS (iSH)](mobile.md)
|
||||
- [Сборка из исходников](build.md)
|
||||
- [Решение проблем](troubleshooting.md)
|
||||
- [Глоссарий](GLOSSARY.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
# Сборка
|
||||
|
||||
Нужен Go 1.25.x.
|
||||
|
||||
```bash
|
||||
go build -o client ./cmd/client
|
||||
go build -o server ./cmd/server
|
||||
go test ./...
|
||||
```
|
||||
|
||||
## Кросс-Сборка
|
||||
|
||||
**Linux amd64:**
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o server-linux-amd64 ./cmd/server
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o client-linux-amd64 ./cmd/client
|
||||
```
|
||||
|
||||
**Android arm64 как `.so`** (упаковка в приложение, PowerShell):
|
||||
|
||||
```powershell
|
||||
$env:GOOS="android"; $env:GOARCH="arm64"; $env:CGO_ENABLED="0"
|
||||
go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn.so .\cmd\client
|
||||
```
|
||||
|
||||
Bash:
|
||||
|
||||
```bash
|
||||
GOOS=android GOARCH=arm64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn.so ./cmd/client
|
||||
```
|
||||
|
||||
**Linux arm64 как `.so`** (в обход NDK, ABI совпадает):
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn.so ./cmd/client
|
||||
```
|
||||
|
||||
**Linux amd64 как `.so`:**
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn-client.so ./cmd/client
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w -checklinkname=0" -trimpath -o libvkturn-server.so ./cmd/server
|
||||
```
|
||||
|
||||
> Все `.so` выше — обычные ELF под `.so`-именем (`CGO_ENABLED=0`, не настоящий shared library). Настоящий `c-shared` — `CGO_ENABLED=1` + NDK toolchain (см. `.github/workflows/release.yml`).
|
||||
@@ -0,0 +1,74 @@
|
||||
# Развёртывание
|
||||
|
||||
## systemd
|
||||
|
||||
`/etc/systemd/system/btp.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=VK TURN Proxy server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/btp/server -listen 0.0.0.0:56000 -connect 127.0.0.1:51820
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
User=nobody
|
||||
Group=nogroup
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now btp.service
|
||||
sudo systemctl status btp.service
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
Образ:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/samosvalishe/btp:latest
|
||||
```
|
||||
|
||||
**Host network** (backend на хосте):
|
||||
|
||||
```bash
|
||||
docker run --rm --network host \
|
||||
-e CONNECT_ADDR=127.0.0.1:51820 \
|
||||
ghcr.io/samosvalishe/btp:latest
|
||||
```
|
||||
|
||||
**Bridge mode:**
|
||||
|
||||
```bash
|
||||
docker run --rm -p 56000:56000/udp \
|
||||
-e CONNECT_ADDR=<host-ip>:51820 \
|
||||
ghcr.io/samosvalishe/btp:latest
|
||||
```
|
||||
|
||||
> В bridge `CONNECT_ADDR=127.0.0.1:...` указывает внутрь контейнера. Используйте host network или IP хоста.
|
||||
|
||||
**Переменные:**
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
| --- | --- | --- |
|
||||
| `CONNECT_ADDR` | **обязательна** | backend сервера |
|
||||
| `LISTEN_ADDR` | `0.0.0.0:56000` | адрес прослушивания |
|
||||
| `VLESS_MODE` | `false` | включает `-vless` |
|
||||
| `WRAP_MODE` | `false` | включает `-wrap` |
|
||||
| `WRAP_KEY` | пусто | значение `-wrap-key` |
|
||||
| `VK_TURN_KCP_PROFILE` | `balanced` | профиль KCP |
|
||||
| `VK_TURN_KCP_MTU` | `1200` | MTU для KCP |
|
||||
|
||||
> `VLESS_BOND` в `docker-entrypoint.sh` ещё передаёт `-vless-bond` серверу, но серверный флаг удалён в V2-0 (bond автоопределяется по magic-префиксу). Не устанавливайте `VLESS_BOND=true` — сервер не запустится.
|
||||
|
||||
Сборка образа:
|
||||
|
||||
```bash
|
||||
docker build -t btp .
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
# Флаги
|
||||
|
||||
## Клиент
|
||||
|
||||
| Флаг | По умолчанию | Описание |
|
||||
| --- | --- | --- |
|
||||
| `-listen` | `127.0.0.1:9000` | локальный адрес `ip:port`, куда подключается WireGuard или Xray клиент |
|
||||
| `-peer` | **обязательный** | адрес сервера на VPS, `host:port` |
|
||||
| `-vk-link` | **обязательный** | ссылка VK Calls `https://vk.com/call/join/...` |
|
||||
| `-n` | `10` | параллельных TURN-потоков |
|
||||
| `-udp` | `false` | TURN по UDP вместо TCP/TLS |
|
||||
| `-turn` | из ссылки | переопределить IP TURN-сервера |
|
||||
| `-port` | из ссылки | переопределить порт TURN-сервера |
|
||||
| `-vless` | `false` | TCP-форвардер (VLESS/Xray) вместо UDP-релея |
|
||||
| `-vless-bond` | `false` | распределять TCP-соединение по smux-сессиям (только с `-vless`) |
|
||||
| `-wrap` | `false` | SRTP-мимикрия payload |
|
||||
| `-wrap-key` | пусто | общий ключ, 32 байта hex (64 символа) |
|
||||
| `-gen-wrap-key` | `false` | напечатать новый ключ и выйти |
|
||||
| `-manual-captcha` | `false` | сразу ручной режим captcha |
|
||||
| `-streams-per-cred` | `10` | потоков на один кеш VK-учёток |
|
||||
| `-dns` | `auto` | `udp` \| `doh` \| `auto` |
|
||||
| `-dns-servers` | пусто | свои UDP/53 резолверы, `ip[:port][,ip[:port]...]` |
|
||||
| `-debug` | `false` | debug-логи |
|
||||
|
||||
## Сервер
|
||||
|
||||
| Флаг | По умолчанию | Описание |
|
||||
| --- | --- | --- |
|
||||
| `-listen` | `0.0.0.0:56000` | адрес прослушивания `ip:port` |
|
||||
| `-connect` | **обязательный** | локальный backend `host:port` (WG `127.0.0.1:51820` / Xray `127.0.0.1:443`) |
|
||||
| `-vless` | `false` | TCP-форвардер; bond автоопределяется |
|
||||
| `-wrap` | `false` | SRTP-мимикрия payload |
|
||||
| `-wrap-key` | пусто | общий ключ, 32 байта hex |
|
||||
| `-gen-wrap-key` | `false` | напечатать новый ключ и выйти |
|
||||
| `-debug` | `false` | debug-логи |
|
||||
|
||||
## Переменные Окружения (KCP)
|
||||
|
||||
См. [modes.md → KCP](modes.md#kcp-только-в--vless).
|
||||
@@ -0,0 +1,35 @@
|
||||
# Мобильные
|
||||
|
||||
## Android (Termux)
|
||||
|
||||
1. Termux из F-Droid.
|
||||
2. WireGuard: `Endpoint = 127.0.0.1:9000`, `MTU = 1280`.
|
||||
3. Termux в исключения WireGuard.
|
||||
4. В Termux:
|
||||
|
||||
```bash
|
||||
termux-wake-lock
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-android-arm64
|
||||
chmod +x client
|
||||
./client -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>"
|
||||
```
|
||||
|
||||
Снять wake lock: `termux-wake-unlock`.
|
||||
|
||||
## iOS (iSH)
|
||||
|
||||
Запасной вариант без нативного клиента.
|
||||
|
||||
```bash
|
||||
apk update
|
||||
apk add curl
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-linux-386
|
||||
chmod +x client
|
||||
GOMAXPROCS=1 GODEBUG=asyncpreemptoff=1 ./client -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>"
|
||||
```
|
||||
|
||||
Дольше в фоне:
|
||||
|
||||
```bash
|
||||
cat /dev/location > /dev/null &
|
||||
```
|
||||
@@ -0,0 +1,81 @@
|
||||
# Режимы
|
||||
|
||||
## UDP-Релей (WireGuard / Hysteria)
|
||||
|
||||
Дефолт. Клиент слушает локальный UDP, сервер форвардит UDP в backend (WG `127.0.0.1:51820`).
|
||||
|
||||
## VLESS / Xray (TCP)
|
||||
|
||||
Флаг `-vless` на обеих сторонах. Сервер коннектит локальный TCP backend (Xray inbound `127.0.0.1:443`). Клиент слушает локальный TCP, на него смотрит Xray/v2rayN/sing-box.
|
||||
|
||||
Поверх DTLS — KCP + smux.
|
||||
|
||||
```bash
|
||||
./server -listen 0.0.0.0:56000 -connect 127.0.0.1:443 -vless
|
||||
./client -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>" -vless
|
||||
```
|
||||
|
||||
**Bonding** — распределение одного TCP-соединения по всем активным smux-сессиям, флаг только клиентский:
|
||||
|
||||
```bash
|
||||
./client -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>" -vless -vless-bond -n 4
|
||||
```
|
||||
|
||||
> **Breaking (V2-0):** серверный `-vless-bond` удалён, сервер автоопределяет bond по magic-префиксу в стриме. Клиентский `-no-dtls` тоже удалён (VK дропает не-DTLS).
|
||||
|
||||
## WRAP (SRTP-Мимикрия)
|
||||
|
||||
`-wrap` маскирует TURN-payload под SRTP: RTP/opus-заголовок + ChaCha20-Poly1305 AEAD на теле. Не защита (DTLS уже шифрует), а обфускация под голос — иначе VK content-filter дропает. Ключ должен совпадать.
|
||||
|
||||
Сгенерировать ключ:
|
||||
|
||||
```bash
|
||||
./server -gen-wrap-key
|
||||
```
|
||||
|
||||
Запуск:
|
||||
|
||||
```bash
|
||||
./server ... -wrap -wrap-key <64-hex>
|
||||
./client ... -wrap -wrap-key <64-hex>
|
||||
```
|
||||
|
||||
## KCP (Только В `-vless`)
|
||||
|
||||
Переменные окружения (клиент и сервер):
|
||||
|
||||
| Переменная | Значения | Описание |
|
||||
| --- | --- | --- |
|
||||
| `VK_TURN_KCP_PROFILE` | `fast` \| `balanced` \| `slow` | Предустановка. |
|
||||
| `VK_TURN_KCP_MTU` | напр. `1200` | Размер пакета. |
|
||||
| `VK_TURN_KCP_FEC` | `data:parity`, напр. `10:3` | Reed-Solomon FEC. |
|
||||
|
||||
**Профили:**
|
||||
|
||||
- `fast` (`legacy`) — минимальные задержки, активная переотправка, MTU 1280.
|
||||
- `balanced` (`cc`) — баланс для большинства сетей, MTU 1200.
|
||||
- `slow` (`conservative`) — нестабильные каналы, MTU 1150.
|
||||
|
||||
Тонкая настройка: `VK_TURN_KCP_NODELAY`, `_INTERVAL`, `_RESEND`, `_NC`, `_SNDWND`, `_RCVWND`, `_ACK_NODELAY`.
|
||||
|
||||
**FEC:** на каждые `data` пакетов — `parity` избыточных. Потери до `parity` из `data+parity` восстанавливаются без ретрансмита. Overhead полосы: `parity/data` (для `10:3` — 30%). Включайте при случайных потерях; при шейпе по полосе FEC ухудшит goodput. По умолчанию `0:0`.
|
||||
|
||||
## Captcha
|
||||
|
||||
Клиент сам проходит VK captcha. Если автоматика не справилась — открывается локальный браузер. Принудительно ручной:
|
||||
|
||||
```bash
|
||||
./client -manual-captcha ...
|
||||
```
|
||||
|
||||
Профиль браузера: `vk_profile.json` рядом с бинарником.
|
||||
|
||||
## DNS
|
||||
|
||||
Флаг `-dns`:
|
||||
|
||||
- `udp` — только UDP/53;
|
||||
- `doh` — только DNS-over-HTTPS;
|
||||
- `auto` (дефолт) — сначала UDP/53, sticky-fallback на DoH при полном отказе.
|
||||
|
||||
Свои резолверы: `-dns-servers ip[:port][,ip[:port]...]`.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Быстрый Старт (WireGuard)
|
||||
|
||||
## Что Нужно
|
||||
|
||||
- VPS с публичным IP, WireGuard слушает `127.0.0.1:51820/udp`.
|
||||
- Активная ссылка VK Calls: `https://vk.com/call/join/...` — создайте сами, не завершайте звонок для всех.
|
||||
- WireGuard на клиенте: `Endpoint = 127.0.0.1:9000`, `MTU = 1280`.
|
||||
|
||||
## 1. Сервер На VPS
|
||||
|
||||
```bash
|
||||
curl -L -o server https://github.com/samosvalishe/btp/releases/latest/download/server-linux-amd64
|
||||
chmod +x server
|
||||
./server -listen 0.0.0.0:56000 -connect 127.0.0.1:51820
|
||||
```
|
||||
|
||||
Порт `56000/udp` открыт снаружи.
|
||||
|
||||
## 2. Маршруты (Split Tunneling)
|
||||
|
||||
WireGuard забирает весь трафик, включая трафик к TURN-реле — туннель замыкается сам на себя. Скрипт маршрутов добавляет исключение: трафик к TURN идёт напрямую через шлюз ISP.
|
||||
|
||||
Флаг `-debug` включает debug-логи, из которых скрипт читает IP TURN-сервера. `2>&1` перенаправляет их в пайп.
|
||||
|
||||
> **Android:** маршруты не нужны — добавьте Termux в исключения WireGuard.
|
||||
|
||||
## 3. Клиент
|
||||
|
||||
**Linux:**
|
||||
|
||||
```bash
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-linux-amd64
|
||||
chmod +x client
|
||||
./client -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>" -debug 2>&1 | ./scripts/routes.sh
|
||||
```
|
||||
|
||||
**Windows (PowerShell от администратора):**
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest -Uri https://github.com/samosvalishe/btp/releases/latest/download/client-windows-amd64.exe -OutFile client.exe
|
||||
.\client.exe -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>" -debug 2>&1 | .\scripts\routes.ps1
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
|
||||
```bash
|
||||
curl -L -o client https://github.com/samosvalishe/btp/releases/latest/download/client-darwin-arm64
|
||||
chmod +x client
|
||||
./client -listen 127.0.0.1:9000 -peer <vps>:56000 -vk-link "<vk-link>" -debug 2>&1 | ./scripts/routes-macos.sh
|
||||
```
|
||||
|
||||
Когда скрипт напечатает `Ensuring route to ...` — включайте WireGuard.
|
||||
|
||||
> Скачали только бинарник без репо? Возьмите скрипты отдельно:
|
||||
> [`scripts/routes.sh`](../scripts/routes.sh) · [`scripts/routes.ps1`](../scripts/routes.ps1) · [`scripts/routes-macos.sh`](../scripts/routes-macos.sh)
|
||||
@@ -0,0 +1,12 @@
|
||||
# Решение Проблем
|
||||
|
||||
- Сначала запускайте client, потом включайте WireGuard.
|
||||
- WireGuard забирает весь трафик → пайп с `-debug 2>&1` и скриптом маршрутов обязателен: `scripts/routes.sh` / `scripts/routes.ps1` / `scripts/routes-macos.sh`.
|
||||
- Маршруты не добавляются → убедитесь, что в команде есть `-debug 2>&1 |` перед скриптом.
|
||||
- TCP до TURN не работает → попробуйте `-udp`.
|
||||
- Соединение нестабильное → уменьшите `-n` (например, `-n 1`).
|
||||
- VK часто требует captcha → `-manual-captcha`, затем обычный запуск.
|
||||
- Клиент висит на получении TURN-данных → ссылка VK Calls умерла / звонок завершён для всех.
|
||||
- Docker bridge mode → `CONNECT_ADDR=127.0.0.1:...` указывает внутрь контейнера. Используйте `--network host` или IP хоста.
|
||||
- `-wrap` включён → ключ должен совпадать на клиенте и сервере.
|
||||
- `VLESS_BOND=true` в docker → не ставьте, серверный флаг удалён в V2-0.
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
gateway="$(ip -o -4 route show to default | awk '/via/ {print $3}' | head -1)"
|
||||
if [[ -z "${gateway}" ]]; then
|
||||
echo "Could not determine default gateway" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ip_cmd=(ip)
|
||||
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
||||
ip_cmd=(sudo ip)
|
||||
fi
|
||||
|
||||
while IFS= read -r remote; do
|
||||
remote="${remote%$'\r'}"
|
||||
[[ -z "$remote" ]] && continue
|
||||
|
||||
if [[ ! "$remote" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
echo "Skipping unexpected input: $remote" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Ensuring route to $remote via $gateway"
|
||||
"${ip_cmd[@]}" route replace "$remote" via "$gateway"
|
||||
done
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/zsh
|
||||
# Usage: ./client -debug ... 2>&1 | ./scripts/routes-macos.sh
|
||||
set -u
|
||||
|
||||
default_info="$(route -n get default 2>/dev/null || true)"
|
||||
@@ -18,11 +19,9 @@ fi
|
||||
while IFS= read -r line; do
|
||||
line="${line//$'\r'/}"
|
||||
|
||||
# Try to extract:
|
||||
# - plain IPv4
|
||||
# - IPv4/CIDR
|
||||
# - relayed-address=IPv4:port -> use only IPv4
|
||||
remote="$(printf '%s\n' "$line" | sed -nE '
|
||||
s/.*TURN server IP: (([0-9]{1,3}\.){3}[0-9]{1,3}).*/\1/p
|
||||
t done
|
||||
s/.*relayed-address=(([0-9]{1,3}\.){3}[0-9]{1,3}):[0-9]+.*/\1/p
|
||||
t done
|
||||
s/^(([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9]{1,2})$/\1/p
|
||||
@@ -1,42 +1,51 @@
|
||||
# Получаем default gateway (IPv4)
|
||||
# Usage: .\client.exe -debug ... 2>&1 | .\scripts\routes.ps1
|
||||
# Requires Administrator privileges.
|
||||
|
||||
$gateway = Get-NetRoute `
|
||||
-DestinationPrefix "0.0.0.0/0" `
|
||||
| Sort-Object RouteMetric `
|
||||
| Select-Object -First 1 -ExpandProperty NextHop
|
||||
|
||||
if (-not $gateway) {
|
||||
Write-Error "Не удалось определить default gateway"
|
||||
Write-Error "Could not determine default gateway"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Default gateway: $gateway"
|
||||
|
||||
# Читаем адреса из stdin
|
||||
$input | ForEach-Object {
|
||||
$addr = $_.Trim()
|
||||
if ($addr -eq "") { return }
|
||||
$line = $_.Trim()
|
||||
if ($line -eq "") { return }
|
||||
|
||||
if ($addr -notmatch '^\d{1,3}(\.\d{1,3}){3}$') {
|
||||
Write-Warning "Пропускаем неожиданный ввод: $addr"
|
||||
return
|
||||
$prefix = $null
|
||||
|
||||
if ($line -match 'TURN server IP: ((\d{1,3}\.){3}\d{1,3})') {
|
||||
$prefix = "$($Matches[1])/32"
|
||||
} elseif ($line -match 'relayed-address=((\d{1,3}\.){3}\d{1,3}):\d+') {
|
||||
$prefix = "$($Matches[1])/32"
|
||||
} elseif ($line -match '^((\d{1,3}\.){3}\d{1,3}/\d{1,2})$') {
|
||||
$prefix = $Matches[1]
|
||||
} elseif ($line -match '^((\d{1,3}\.){3}\d{1,3})$') {
|
||||
$prefix = "$line/32"
|
||||
}
|
||||
|
||||
$prefix = "$addr/32"
|
||||
if (-not $prefix) { return }
|
||||
|
||||
$existingRoutes = @(Get-NetRoute `
|
||||
-DestinationPrefix $prefix `
|
||||
-PolicyStore ActiveStore `
|
||||
-ErrorAction SilentlyContinue)
|
||||
|
||||
if ($existingRoutes | Where-Object { $_.NextHop -eq $gateway }) {
|
||||
Write-Host "Маршрут к $addr через $gateway уже существует"
|
||||
Write-Host "Route to $prefix via $gateway already exists"
|
||||
return
|
||||
}
|
||||
|
||||
if ($existingRoutes.Count -gt 0) {
|
||||
Write-Host "Обновляем маршрут к $addr через $gateway"
|
||||
Write-Host "Updating route to $prefix via $gateway"
|
||||
$existingRoutes | Remove-NetRoute -Confirm:$false -ErrorAction Stop
|
||||
} else {
|
||||
Write-Host "Добавляем маршрут к $addr через $gateway"
|
||||
Write-Host "Ensuring route to $prefix via $gateway"
|
||||
}
|
||||
|
||||
New-NetRoute `
|
||||
@@ -45,4 +54,3 @@ $input | ForEach-Object {
|
||||
-PolicyStore ActiveStore `
|
||||
-ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# Usage: ./client -debug ... 2>&1 | ./scripts/routes.sh
|
||||
set -euo pipefail
|
||||
|
||||
gateway="$(ip -o -4 route show to default | awk '/via/ {print $3}' | head -1)"
|
||||
if [[ -z "${gateway}" ]]; then
|
||||
echo "Could not determine default gateway" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ip_cmd=(ip)
|
||||
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
||||
ip_cmd=(sudo ip)
|
||||
fi
|
||||
|
||||
while IFS= read -r line; do
|
||||
line="${line%$'\r'}"
|
||||
|
||||
remote=""
|
||||
if [[ "$line" =~ TURN\ server\ IP:\ (([0-9]{1,3}\.){3}[0-9]{1,3}) ]]; then
|
||||
remote="${BASH_REMATCH[1]}"
|
||||
elif [[ "$line" =~ relayed-address=(([0-9]{1,3}\.){3}[0-9]{1,3}):[0-9]+ ]]; then
|
||||
remote="${BASH_REMATCH[1]}"
|
||||
elif [[ "$line" =~ ^(([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2})$ ]]; then
|
||||
remote="$line"
|
||||
elif [[ "$line" =~ ^(([0-9]{1,3}\.){3}[0-9]{1,3})$ ]]; then
|
||||
remote="$line"
|
||||
fi
|
||||
|
||||
[[ -z "$remote" ]] && continue
|
||||
|
||||
echo "Ensuring route to $remote via $gateway"
|
||||
"${ip_cmd[@]}" route replace "$remote" via "$gateway"
|
||||
done
|
||||
Reference in New Issue
Block a user