
Tunelamento de dados sobre webrtc para contornar a censura
Tunela o tráfego de internet através de plataformas de chamadas de vídeo (VK Call, Yandex Telemost, WB Stream) para contornar a censura de whitelist governamental.
Guia de configuração passo a passo (em russo): docs/SETUP.md
Dois modos de túnel estão disponíveis: DC (DataChannel) e Video (codificação de dados VP8). A configuração recomendada é headless em ambas as pontas - Go puro (Pion) fala diretamente com o SFU da plataforma, sem navegador. Ofuscação ChaCha20, pacing VP8 configurável e o backend LiveKit/WB Stream são recursos exclusivos do modo headless.
Um caminho legado via navegador (joiner Android WebView contra um creator desktop Electron com hooks JS) ainda funciona para VK DC, mas é mais lento, não consegue ofuscar e está sendo descontinuado. Novas implantações devem usar headless.
O Pion abre um SCTP DataChannel no PC publicador e tunela TCP/UDP através dele. Os frames passam pelo SFU da plataforma como qualquer outro payload de DataChannel.
Joiner (censored, Android/iOS/Linux) Creator (free internet)
All apps
|
VpnService (captures all traffic)
|
tun2socks (IP -> TCP)
|
SOCKS5 proxy (Go, :1080)
|
Headless joiner (Pion) Headless creator (Pion)
| |
DataChannel <------- SFU -------> DataChannel
|
Relay bridge
|
Internet
Mesmo pipeline do modo DC, mas o túnel trafega em uma track de vídeo VP8 publicada em vez de um SCTP DataChannel. Útil quando o SFU limita a taxa de DataChannels mas permite RTP (por exemplo, Telemost), e obrigatório pela plataforma em alguns casos (a track do publicador do WB Stream é sempre vídeo). O enquadramento do túnel e a camada de multiplexação acima dele são os mesmos do modo DC.
O tráfego passa pelo SFU da plataforma, que está na whitelist governamental. Para o DPI, parece uma chamada de vídeo normal.
relay/ - Relay em Go compartilhado por ambas as pontas: proxy SOCKS5, encanamento tun2socks, túnel DC/VP8, ofuscador ChaCha20, multiplexador de conexões, bindings gomobile/iOSheadless/vk/ - Creator VK headless: cria ou entra em uma chamada via API HTTP do VK, túnel Pion DC/VP8, sem navegadorheadless/telemost/ - Creator Telemost (Yandex) headless com o mesmo modeloheadless/wbstream/ - Creator WB Stream headless (com backend LiveKit, tokens de convidado anônimos)headless/dion/ - Creator DION headless com o mesmo modeloheadless/bitrix/ - Creator Bitrix headless (DC/VP8 adaptativo, entrada como convidado)headless/wbstream-joiner/ - Joiner WB Stream para desktop (contraparte do creator, usado para testes e clientes Linux)headless/telemost-joiner/ - Joiner Telemost para desktop (contraparte do creator, usado para testes e clientes Linux)headless/dion-joiner/ - Joiner DION para desktop (contraparte do creator, usado para testes e clientes Linux)headless/bitrix-joiner/ - Joiner Bitrix para desktop (contraparte do creator, usado para testes e clientes Linux)Binários pré-compilados estão disponíveis em GitHub Releases.
Baixe e execute o app Electron em GitHub Releases. Ele inclui o relay Go automaticamente.
Importante: A chamada deve ser criada dentro do app Creator. Entrar em uma chamada existente a partir do app não funcionará - os hooks JS devem estar presentes desde o momento em que a chamada começa.
Três formas estão disponíveis; escolha a que se adequa ao dispositivo:
whitelist-bypass.apk em Releases. Permita o prompt de VPN na primeira inicialização. Cole o link de entrada e toque em GO; o tráfego de todo o sistema flui pela chamada.whitelist-bypass-proxy.ipa em Releases (sideload via AltStore / Sideloadly / sua conta de desenvolvedor). Expõe apenas um proxy SOCKS5 local - sem VPN de sistema. Para fazer proxy de todo o dispositivo, aponte qualquer app de VPN compatível com SOCKS5 (Shadowrocket, Streisand, ...) para o endpoint SOCKS5 que o app mostra; ou defina o proxy por app (o Telegram tem suporte integrado).--socks-user / --socks-pass habilitam autenticação de usuário/senha SOCKS5.
headless-wbstream-joiner --room <link> --socks-port 1080 [--socks-user u --socks-pass p]headless-telemost-joiner --tm-link <link> --socks-port 1080 [--socks-user u --socks-pass p]headless-dion-joiner --room <link> --socks-port 1080 [--socks-user u --socks-pass p]headless-bitrix-joiner --link <link> --socks-port 1080 [--socks-user u --socks-pass p]O passo a passo completo (em russo) cobre cada plataforma em detalhes: veja docs/SETUP.md.
go install golang.org/x/mobile/cmd/gomobile@latest)go install golang.org/x/mobile/cmd/gobind@latest)# Full release build (Android APK + Creator app + Headless creators + Linux joiners + VK bot + iOS IPA on macOS)
./make-release.sh
# Individual builds
./build-go.sh # Go .aar, relay binary, headless creators
./copy-hooks.sh # Copy JS hooks to android assets
./build-app.sh # Android APK
./build-headless.sh # Headless binaries only (current platform)
./build-cli.sh # Per-arch zips of headless creators + joiners + vk-bot
./build-creator.sh # Creator Electron app (all platforms)
./build-ios.sh proxy # iOS proxy app, xcframework + unsigned IPA
./build-ios.sh vpn # iOS VPN app, xcframework + unsigned IPA
Requer Xcode e macOS. build-ios.sh recebe um argumento, proxy ou vpn.
./build-ios.sh proxy # ios-proxy-app -> prebuilts/whitelist-bypass-proxy.ipa
./build-ios.sh vpn # ios-vpn-app -> prebuilts/whitelist-bypass-vpn.ipa
O script compila Mobile.xcframework no diretório do app, executa o strip-signing.sh do app para limpar a equipe de desenvolvedor do projeto, compila o app sem assinatura e grava um IPA não assinado em prebuilts/.
Para executar em um dispositivo, abra o .xcodeproj correspondente no Xcode, defina sua equipe e identificadores de bundle únicos em Signing & Capabilities, e compile. A variante vpn requer a capacidade Network Extension em seus identificadores de bundle.
Saída em prebuilts/:
Para compilar o projeto usando Docker, execute:
docker compose -f docker-build/docker-compose.yml up
Isso compilará todos os componentes (creator-app, headless, android app) na pasta prebuild (exceto o creator para macOS)
Creators em Go puro que criam chamadas via API sem navegador. Sem Electron, sem hooks JS - o Go Pion PeerConnection lida diretamente com o túnel DataChannel.
./build-headless.sh
Dez binários são produzidos - cinco creators, quatro joiners Linux e o bot VK:
./headless/vk/headless-vk-creator --cookies cookies-vk.json
./headless/telemost/headless-telemost-creator --cookies cookies-yandex.json
./headless/wbstream/headless-wbstream-creator --cookies cookies-wbstream.json
./headless/dion/headless-dion-creator --cookies cookies-dion.json
./headless/bitrix/headless-bitrix-creator --cookies cookies-bitrix.json
./headless/wbstream-joiner/headless-wbstream-joiner --room <link> --socks-port 1080
./headless/dion-joiner/headless-dion-joiner --room <link> --socks-port 1080
./headless/telemost-joiner/headless-telemost-joiner --tm-link <link> --socks-port 1080
./headless/bitrix-joiner/headless-bitrix-joiner --link <link> --socks-port 1080
./headless/vk-bot/headless-vk-bot --token <t> --group-id <g> --bins-dir <dir>
Todos os quatro creators precisam de cookies exportados do app creator desktop (botão Export Cookies) como JSON [{"name":"..","value":".."},...]. O DION também aceita {"email":"..","password":"..","cookies":[]} e então faz login por conta própria, veja docs/SETUP.md.
Por padrão, cada binário cria uma nova chamada. Para se conectar a uma existente (reinicializações do servidor sem invalidar o link, múltiplas sessões moldadas, ...):
Mutuamente exclusivo com as flags de criação de chamada (--peer-id para VK; os outros não têm flag de criação).
custom recorre aos padrões de unlimited para qualquer flag não definida, então substituições parciais funcionam:
./headless-vk-creator --cookies cookies-vk.json --vk-link https://vk.com/call/join/<token> \
--resources custom --read-buf 65536 --max-dc-buf 8388608 --mem-limit 268435456 \
--write-file /var/run/whitelist-bypass/call.txt
read-buf - tamanho do buffer de leitura TCP/DC. Menor = verificações de backpressure mais frequentes, memória menos explosivamax-dc-buf - pausa as leituras TCP quando a quantidade em buffer do DataChannel excede este valor; conectado apenas no VK (Pion BufferedAmountLowThreshold)mem-limit - limite de memória soft do runtime Go; torna o GC mais agressivo perto do limite0xd986b7576340d8d7b04f806dfd38a182b19edf50 - USDC (ERC20)TTEo4XXTB6CqhEiKpyoncfk3skEvoq3bCP - USDT (TRC20)UQCZge2JzLmwNtI56p-ZxLuN2f7ZMCPGqO0XTt3wJ-cy8JaE - USDT (TON)headless/vk-bot/ - Bot VK Long Poll autônomo que gera creators headless sob demanda e responde com o link de entrada (alternativa do lado do servidor ao bot Electron)headless/tests/ - Testes end-to-end ao vivo (creator + joiners sobre um SFU real); execute no mesmo host ou em um stand Dockerizado com netns, veja headless/tests/README.mdandroid-app/ - Joiner Android: VpnService + tun2socks + Pion headless (caminho principal); também mantém um fallback WebView para o fluxo legado via navegadorios-proxy-app/ - Joiner iOS: SOCKS5 + Pion headless via xcframework gomobilecreator-app/ - App creator desktop Electron: front-end GUI que pode executar tanto o caminho legado via navegador quanto gerar os binários Go headless; adequado tanto para uso interativo quanto para implantaçõeshooks/ - Hooks JavaScript para o caminho legado via navegador (modos DC e Video, VK e Telemost). O modo headless não usa hooks JS.| Arquivo | Plataforma |
|---|
WhitelistBypass Creator-*-arm64.dmg | macOS |
WhitelistBypass Creator-*-x64.exe | Windows x64 |
WhitelistBypass Creator-*-ia32.exe | Windows x86 |
WhitelistBypass Creator-*.AppImage | Linux x64 |
whitelist-bypass.apk | Android |
whitelist-bypass-proxy.ipa | iOS proxy app, unsigned |
whitelist-bypass-vpn.ipa | iOS VPN app, unsigned |
headless-vk-creator-linux-x64 | Linux x64 |
headless-vk-creator-linux-ia32 | Linux x86 |
headless-telemost-creator-linux-x64 | Linux x64 |
headless-telemost-creator-linux-ia32 | Linux x86 |
headless-wbstream-joiner-linux-x64 | Linux x64 |
headless-wbstream-joiner-linux-ia32 | Linux x86 |
headless-telemost-joiner-linux-x64 | Linux x64 |
headless-telemost-joiner-linux-ia32 | Linux x86 |
headless-vk-bot-linux-x64 | Linux x64 |
headless-vk-bot-linux-ia32 | Linux x86 |
| Flag | VK | TM | WB | Descrição |
|---|
--cookies <path> | sim | sim | sim | caminho para o JSON de cookies |
--cookie-string <str> | sim | sim | - | string de cookie bruta name=val; name=val |
--write-file <path> | sim | sim | sim | anexa o link de entrada ativo a este arquivo (um link por linha) |
--resources <mode> | sim | sim | sim | default / moderate / unlimited / custom (veja abaixo) |
--read-buf <bytes> | sim | sim | sim | buffer de leitura DC/RTP; consultado apenas com --resources custom |
--max-dc-buf <bytes> | sim | - | - | BufferedAmountLowThreshold do DataChannel; apenas com --resources custom |
--mem-limit <bytes> | sim | sim | sim | limite de memória soft do Go (debug.SetMemoryLimit); apenas com --resources custom |
| Creator | Flag | Valor |
|---|
| VK | --vk-link <link> | https://vk.com/call/join/<token> |
| Telemost | --tm-link <uri> | https://telemost.yandex.ru/j/<id> |
| WB Stream | --room <id> | wbstream://<uuid> ou apenas o UUID |
| DION | --room <id> | dion://<id> ou https://dion.vc/event/<id> |
| Modo | read-buf | max-dc-buf (VK) | mem-limit |
|---|
moderate | 16 KB | 1 MB | 64 MB |
default | 32 KB | 4 MB | 128 MB |
unlimited | 64 KB | 8 MB | 256 MB |
custom | de --read-buf | de --max-dc-buf | de --mem-limit |