From dd9735d2390a2d56a785b7ee77732f338d46e085 Mon Sep 17 00:00:00 2001 From: alexmac6574 <215134852+alexmac6574@users.noreply.github.com> Date: Mon, 30 Mar 2026 13:32:13 +0300 Subject: [PATCH 1/3] chore: Update GitHub actions Co-Authored-By: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 7 +- .github/workflows/release.yml | 130 +++++++++++++++++++++++++++++++--- go.mod | 2 +- go.sum | 4 +- 4 files changed, 129 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecd517f..7e26950 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,13 @@ name: CI +permissions: + contents: read + on: push: - branches: [ "main", "master" ] + branches: [ "main" ] pull_request: - branches: [ "main", "master" ] + branches: [ "main" ] jobs: check: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de687d0..41bd16b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,12 @@ name: Release +permissions: + contents: read + on: push: - # Trigger on tag pushes. Adjust pattern as needed (e.g. 'v*.*.*') - tags: - - '**' + branches: + - main workflow_dispatch: jobs: @@ -25,7 +27,7 @@ jobs: cgo: 0 - goos: linux goarch: arm - goarm: '7' + goarm: "7" cgo: 0 - goos: darwin goarch: amd64 @@ -58,7 +60,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v6 with: - go-version: '1.25.5' + go-version: "1.25.5" # Install Android NDK only for android rows - name: Setup Android NDK @@ -114,7 +116,7 @@ jobs: go build -ldflags "-s -w -checklinkname=0" -trimpath \ -o "dist/client-${GOOS}-${GOARCH}${EXT}" \ ./client - + GOOS=$GOOS GOARCH=$GOARCH GOARM=$GOARM \ go build -ldflags "-s -w -checklinkname=0" -trimpath \ -o "dist/server-${GOOS}-${GOARCH}${EXT}" \ @@ -133,20 +135,130 @@ jobs: permissions: contents: write steps: + - name: Check out code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true + - name: Download build artifacts uses: actions/download-artifact@v7 with: path: dist + - name: Prepare release metadata + id: meta + run: | + LATEST_TAG="$(git tag -l | grep -E '^(v)?[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1 || true)" + PREFIX="" + BASE_VERSION="$LATEST_TAG" + + if [ -z "$LATEST_TAG" ]; then + BASE_VERSION="0.0.0" + elif [ "${LATEST_TAG#v}" != "$LATEST_TAG" ]; then + PREFIX="v" + BASE_VERSION="${LATEST_TAG#v}" + fi + + IFS=. read -r MAJOR MINOR PATCH <<< "$BASE_VERSION" + + if [ -n "$LATEST_TAG" ]; then + RANGE="$LATEST_TAG..HEAD" + else + RANGE="HEAD" + fi + + COMMITS="$(git log --no-merges --format='%s' "$RANGE")" + BUMP="" + + if printf '%s\n' "$COMMITS" | grep -Eiq '^break([(:! ]|$)'; then + BUMP="major" + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + elif printf '%s\n' "$COMMITS" | grep -Eiq '^feat([(:! ]|$)'; then + BUMP="minor" + MINOR=$((MINOR + 1)) + PATCH=0 + elif printf '%s\n' "$COMMITS" | grep -Eiq '^fix([(:! ]|$)'; then + BUMP="patch" + PATCH=$((PATCH + 1)) + fi + + NEXT_VERSION="${MAJOR}.${MINOR}.${PATCH}" + NEXT_TAG="${PREFIX}${NEXT_VERSION}" + + { + echo "previous_tag=$LATEST_TAG" + echo "range=$RANGE" + echo "bump=$BUMP" + echo "should_release=$([ -n "$BUMP" ] && echo true || echo false)" + echo "tag_name=$NEXT_TAG" + echo "release_name=$NEXT_TAG" + echo "body_path=release-notes.md" + } >> "$GITHUB_OUTPUT" + + - name: Generate release notes from commit messages + id: notes + if: steps.meta.outputs.should_release == 'true' + env: + PREVIOUS_TAG: ${{ steps.meta.outputs.previous_tag }} + NEXT_TAG: ${{ steps.meta.outputs.tag_name }} + BUMP: ${{ steps.meta.outputs.bump }} + RANGE: ${{ steps.meta.outputs.range }} + run: | + strip_prefix() { + sed -E 's/^(feat|fix|break)([(!:]|[[:space:]])+[[:space:]]*//I' + } + + FEATURES="$(git log --no-merges --format='%s (%h)' "$RANGE" | grep -Ei '^feat([(:! ]|$)' | strip_prefix | LC_ALL=C sort -f || true)" + FIXES="$(git log --no-merges --format='%s (%h)' "$RANGE" | grep -Ei '^fix([(:! ]|$)' | strip_prefix | LC_ALL=C sort -f || true)" + BREAKING="$(git log --no-merges --format='%s (%h)' "$RANGE" | grep -Ei '^break([(:! ]|$)' | strip_prefix | LC_ALL=C sort -f || true)" + + { + echo "body_path=release-notes.md" + } >> "$GITHUB_OUTPUT" + + { + if [ -n "$BREAKING" ]; then + echo "### Несовместимые изменения" + echo + printf '%s\n' "$BREAKING" | sed 's/^/- /' + echo + fi + + if [ -n "$FEATURES" ]; then + echo "### Новые функции" + echo + printf '%s\n' "$FEATURES" | sed 's/^/- /' + echo + fi + + if [ -n "$FIXES" ]; then + echo "### Исправление багов" + echo + printf '%s\n' "$FIXES" | sed 's/^/- /' + echo + fi + } > release-notes.md + - name: Create Release + if: steps.meta.outputs.should_release == 'true' uses: softprops/action-gh-release@v2 with: # upload every file in dist/ including nested files files: | dist/** - # make the release name/tag the pushed tag - tag_name: ${{ github.ref_name }} - name: ${{ github.ref_name }} + tag_name: ${{ steps.meta.outputs.tag_name }} + target_commitish: ${{ github.sha }} + name: ${{ steps.meta.outputs.release_name }} + body_path: ${{ steps.meta.outputs.body_path }} overwrite_files: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Skip release when no semantic commit is found + if: steps.meta.outputs.should_release != 'true' + run: | + echo "No new semantic release created." + echo "Add a commit starting with break, feat, or fix after the latest tag." diff --git a/go.mod b/go.mod index db0b818..63d5b25 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/cbeuw/connutil v1.0.1 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 - github.com/pion/dtls/v3 v3.0.10 + github.com/pion/dtls/v3 v3.0.11 github.com/pion/logging v0.2.4 github.com/pion/turn/v5 v5.0.2 ) diff --git a/go.sum b/go.sum index 71673ee..bbaf68e 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc= github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g= -github.com/pion/dtls/v3 v3.0.10 h1:k9ekkq1kaZoxnNEbyLKI8DI37j/Nbk1HWmMuywpQJgg= -github.com/pion/dtls/v3 v3.0.10/go.mod h1:YEmmBYIoBsY3jmG56dsziTv/Lca9y4Om83370CXfqJ8= +github.com/pion/dtls/v3 v3.0.11 h1:zqn8YhoAU7d9whsWLhNiQlbB8QdpJj8XQVSc5ImUons= +github.com/pion/dtls/v3 v3.0.11/go.mod h1:YEmmBYIoBsY3jmG56dsziTv/Lca9y4Om83370CXfqJ8= github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8= github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= From a274156c28572ae7d555d435a70958d6f49b62a6 Mon Sep 17 00:00:00 2001 From: alexmac6574 <215134852+alexmac6574@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:57:39 +0300 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D0=B0=20Doc?= =?UTF-8?q?ker=20=D0=B8=D0=B7=20GitHub=20Container=20Registry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24c5028..fcdd0b1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -137,6 +137,9 @@ jobs: name: Create GitHub Release needs: build runs-on: ubuntu-latest + outputs: + should_release: ${{ steps.meta.outputs.should_release }} + tag_name: ${{ steps.meta.outputs.tag_name }} permissions: contents: write steps: @@ -267,3 +270,54 @@ jobs: run: | echo "No new semantic release created." echo "Add a commit starting with break, feat, or fix after the latest tag." + + docker: + name: Publish Docker image + needs: release + if: needs.release.outputs.should_release == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Prepare image name + id: image + env: + REPOSITORY: ${{ github.repository }} + run: | + echo "name=ghcr.io/$(echo "$REPOSITORY" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ steps.image.outputs.name }} + tags: | + type=raw,value=latest + type=raw,value=${{ needs.release.outputs.tag_name }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 925cccfbef29d898aed2159de6f5203885269ca3 Mon Sep 17 00:00:00 2001 From: alexmac6574 <215134852+alexmac6574@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:58:42 +0300 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20README=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=81=D1=82=D1=8B=D1=85=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD=D0=B4=20=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B1=D0=B8=D0=BD=D0=B0=D1=80=D0=BD=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B8=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 244 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 155 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 4bc5e65..3f0268d 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,136 @@ # Good TURN + Проброс трафика WireGuard/Hysteria через TURN сервера VK звонков или Яндекс телемоста. Пакеты шифруются DTLS 1.2, затем параллельными потоками через TCP или UDP отправляются на TURN сервер по протоколу STUN ChannelData. Оттуда по UDP отправляются на ваш сервер, где расшифровываются и передаются в WireGuard. Логин/пароль от TURN генерируются из ссылки на звонок. Только для учебных целей! + ## Настройка + Нам понадобится: + 1. Ссылка на действующий ВК звонок: создаём свой (нужен аккаунт вк), или гуглим `"https://vk.com/call/join/"`. -Ссылка действительна вечно, если не нажимать "завершить звонок для всех" + Ссылка действительна вечно, если не нажимать "завершить звонок для всех" 2. Или ссыска на звонок Яндекс телемоста: `"https://telemost.yandex.ru/j/"`. Её лучше не гуглить, так как видно подключение к конференции 3. VPS с установленным WireGuard 4. Для андроида: скачать Termux из F-Droid + ### Сервер + +
Рекомендуется tmux + +На сервере запустить tmux: + +```bash +# Создание сессии tmux +tmux new -s vkturn ``` + +Внутри сессии tmux запустить команду сервера ниже. Далее нажать `Ctrl+B` `D`, чтобы свернуть сессию, не завершая её. Прокси процесс останется запущенным, сервер будет доступен для новых команд или безопасного выхода из него. + +```bash +# Войти в ранее созданную сессию tmux +tmux a -t vkturn +``` + +
+ +Скачать бинарник, в данном примере используется самый популярный сервер `server-linux-amd64`: + +```bash +# Скачать бинарник +curl -L -o server https://github.com/cacggghp/vk-turn-proxy/releases/latest/download/server-linux-amd64 && chmod +x server +``` + +```bash +# Запуск сервера ./server -listen 0.0.0.0:56000 -connect 127.0.0.1:<порт wg> ``` + #### Docker -Сборка образа: + +Образ Docker публикуется в GitHub Container Registry: + +``` +docker pull ghcr.io/cacggghp/vk-turn-proxy:latest +docker tag ghcr.io/cacggghp/vk-turn-proxy:latest vkt +``` + +Для Linux-сервера, где `xray` или WireGuard слушает локально, удобнее запускать через host network: + +``` +docker run --rm --network host -e CONNECT_ADDR=127.0.0.1:<порт wg> vkt +``` + +Если нужен bridge mode: + +``` +docker run --rm -p 56000:56000/udp -e CONNECT_ADDR=:<порт wg> vkt ``` + +Сборка образа вручную: + +``` +git clone https://github.com/cacggghp/vk-turn-proxy.git +cd vk-turn-proxy docker build -t vk-turn-proxy . ``` Переменная окружения **CONNECT_ADDR** — адрес WireGuard (обязательный), например `192.168.1.10:51820`. Пример запуска: + ``` docker run -p 56000:56000/udp -e CONNECT_ADDR=192.168.1.10:51820 vk-turn-proxy ``` ### Клиент + #### Android **Рекомендуемый способ:** Использовать нативное Android-приложение [vk-turn-proxy-android](https://github.com/MYSOREZ/vk-turn-proxy-android). + - В клиентском конфиге WireGuard меняем адрес сервера на `127.0.0.1:9000`, ставим MTU 1280 -- **Добавляем приложение в исключения WireGuard. Нажимаем "сохранить".** +- **Добавляем приложение в исключения WireGuard. Нажимаем "сохранить".** **Альтернативный способ (через Termux):** + - В клиентском конфиге WireGuard меняем адрес сервера на `127.0.0.1:9000`, ставим MTU 1280 -- **Добавляем Termux в исключения WireGuard. Нажимаем "сохранить".** -В Termux: +- **Добавляем Termux в исключения WireGuard. Нажимаем "сохранить".** + В Termux: + ``` termux-wake-lock ``` + Телефон не будет уходить в глубокий сон, так что на ночь ставьте на зарядку. Чтобы отключить: + ``` termux-wake-unlock ``` -Копируем бинарник в локальную папку, даём права на исполнение: -``` -cp /sdcard/Download/client-android ./ -chmod 777 ./client-android + +Скачиваем бинарник в локальную папку, даём права на исполнение, в команде указаана самая популярная архитектура `client-android-arm64`: + +```bash +curl -L -o client https://github.com/cacggghp/vk-turn-proxy/releases/latest/download/client-android-arm64 && chmod +x client ``` + Запускаем: + ``` -./client-android -peer :56000 -vk-link -listen 127.0.0.1:9000 +./client -listen 127.0.0.1:9000 -peer :56000 -vk-link ``` + Или + ``` -./client-android -udp -turn 5.255.211.241 -peer :56000 -yandex-link -listen 127.0.0.1:9000 +./client -udp -turn 5.255.211.241 -peer :56000 -yandex-link -listen 127.0.0.1:9000 ``` **Если после включения VPN в терминале вылезают ошибки DNS, попробуйте в Wireguard включить VPN только для нужных приложений.** + #### Linux + В клиентском конфиге WireGuard меняем адрес сервера на `127.0.0.1:9000`, ставим MTU 1280 Скрипт будет добавлять маршруты к нужным ip: @@ -74,7 +144,9 @@ chmod 777 ./client-android ``` Не включайте впн, пока программа не установит соединение! В отличие от андроида, здесь часть запросов будет идти через впн (dns и запрос подключения к turn) + #### Windows + В клиентском конфиге WireGuard меняем адрес сервера на `127.0.0.1:9000`, ставим MTU 1280 В PowerShell от Администратора (чтобы скрипт прописывал маршруты): @@ -88,7 +160,9 @@ chmod 777 ./client-android ``` Не включайте впн, пока программа не установит соединение! В отличие от андроида, здесь часть запросов будет идти через впн (dns и запрос подключения к turn) + ### Если не работает + С помощью опции `-turn` можно указать адрес TURN сервера вручную. Это должен быть сервер ВК, Макса или Одноклассников (ссылка вк) или Яндекса (ссылка яндекса). Возможно потом составлю список. Если не работает TCP, попробуйте добавить флаг `-udp`. @@ -96,6 +170,7 @@ chmod 777 ./client-android Добавьте флаг `-n 1` для более стабильного подключения в 1 поток (ограничение 5 Мбит/с для ВК) ## Яндекс телемост + **UPD. ТЕЛЕМОСТ ЗАКРЫЛИ** В отличие от ВК, сервера яндекса не ограничивают скорость, так что по умолчанию стоит `-n 1`. Увеличение этого числа может привести к временной блокировке по IP из-за переполнения конференции фейковыми участниками. @@ -103,19 +178,18 @@ chmod 777 ./client-android В режиме `-udp` скорость обычно больше Большинство диапазонов IP TURN серверов Яндекса не работают, указывайте вручную через `-turn` +
Рабочие IP - 5.255.211.241 5.255.211.242 5.255.211.243 5.255.211.245 5.255.211.246 -
Спасибо https://github.com/KillTheCensorship/Turnel за часть кода :) @@ -133,51 +207,45 @@ chmod 777 ./client-android ```json { - "inbounds": [ - { - "protocol": "socks", - "listen": "127.0.0.1", - "port": 1080, - "settings": { - "udp": true - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls" - ] - } - }, - { - "protocol": "http", - "listen": "127.0.0.1", - "port": 8080, - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls" - ] - } - } - ], - "outbounds": [ - { - "protocol": "wireguard", - "settings": { - "secretKey": "", - "peers": [ - { - "endpoint": "127.0.0.1:9000", - "publicKey": "" - } - ], - "domainStrategy": "ForceIPv4", - "mtu": 1280 - } - } - ] + "inbounds": [ + { + "protocol": "socks", + "listen": "127.0.0.1", + "port": 1080, + "settings": { + "udp": true + }, + "sniffing": { + "enabled": true, + "destOverride": ["http", "tls"] + } + }, + { + "protocol": "http", + "listen": "127.0.0.1", + "port": 8080, + "sniffing": { + "enabled": true, + "destOverride": ["http", "tls"] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "settings": { + "secretKey": "", + "peers": [ + { + "endpoint": "127.0.0.1:9000", + "publicKey": "" + } + ], + "domainStrategy": "ForceIPv4", + "mtu": 1280 + } + } + ] } ``` @@ -191,41 +259,39 @@ chmod 777 ./client-android ```json { - "inbounds": [ - { - "protocol": "wireguard", - "listen": "0.0.0.0", - "port": 51820, - "settings": { - "secretKey": "", - "peers": [ - { - "publicKey": "" - } - ], - "mtu": 1280 - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls" - ] - } - } - ], - "outbounds": [ - { - "protocol": "freedom", - "settings": { - "domainStrategy": "UseIPv4" - } - } - ] + "inbounds": [ + { + "protocol": "wireguard", + "listen": "0.0.0.0", + "port": 51820, + "settings": { + "secretKey": "", + "peers": [ + { + "publicKey": "" + } + ], + "mtu": 1280 + }, + "sniffing": { + "enabled": true, + "destOverride": ["http", "tls"] + } + } + ], + "outbounds": [ + { + "protocol": "freedom", + "settings": { + "domainStrategy": "UseIPv4" + } + } + ] } ``` ## Direct mode + С флагом `-no-dtls` можно отправлять пакеты без обфускации DTLS и подключаться к обычным серверам Wireguard. Может привести к бану от вк/яндекса.