Packet flow
127.0.0.1:9000 instead of the real VPS address. The proxy client accepts those UDP packets, wraps them in DTLS, and forwards them through one or more TURN channels to the proxy server on your VPS. The server decrypts the DTLS layer and hands the raw WireGuard packets to the local WireGuard daemon.
Startup sequence
Credential extraction
The client calls the provider API to obtain short-lived TURN credentials from the call link you supply.For VK:
- POST to
https://login.vk.ru/?act=get_anonym_tokento get an anonymous access token. - POST to
https://api.vk.ru/method/calls.getAnonymousTokenusing that token and the call link to get a call-scoped token. - POST to
https://calls.okcdn.ru/fb.do(auth.anonymLogin) to open a session. - POST to
https://calls.okcdn.ru/fb.do(vchat.joinConversationByLink) to join the call. The response containsturn_server.username,turn_server.credential, and the TURN address.
- GET
https://cloud-api.yandex.ru/telemost_front/v2/telemost/conferences/<encoded-link>/connectionto obtain a WebSocket URL, room ID, and credential. - Open a WebSocket to the media server URL and send a
hellomessage. - Parse the
serverHelloresponse to extract ICE server credentials (username, credential, TURN address).
TURN allocation
The client connects to the TURN server — over TCP (default) or UDP with
-udp — and allocates a relay socket using the STUN Allocate method. The TURN server assigns a relay address on its own network that the proxy server will send responses back to.DTLS handshake
The client generates a self-signed ECDSA certificate and performs a DTLS 1.2 client handshake with the proxy server through the TURN relay. The cipher suite is fixed to
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 with ExtendedMasterSecret required on both sides. Connection IDs are enabled (OnlySendCIDGenerator on the client, RandomCIDGenerator(8) on the server) so packets can be demultiplexed after NAT rebinding.Parallel channel setup
Once the first DTLS connection is established, the client opens additional TURN channels (up to
-n total — default 16 for VK, 1 for Yandex). Each channel is an independent DTLS session through a separate TURN allocation, giving the WireGuard tunnel more aggregate bandwidth. Data is sent using STUN ChannelData / ChannelBind messages rather than Send indications, which reduces per-packet overhead.Packet forwarding
The client listens on
127.0.0.1:9000 (UDP). Each incoming WireGuard packet is written to the DTLS connection, which encrypts it and sends it as ChannelData to the TURN server. The TURN server relays the UDP datagram to the proxy server’s public address. The server decrypts the DTLS frame and forwards the raw payload to the WireGuard daemon at the address given by -connect.Return traffic follows the reverse path: WireGuard server → proxy server → DTLS encrypt → TURN relay → DTLS decrypt on client → WireGuard app.DTLS configuration
Both the client and the server use pion/dtls v3 with the following settings:| Parameter | Value |
|---|---|
| Protocol version | DTLS 1.2 |
| Certificate | Self-signed, generated at startup |
| Cipher suite | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
| Extended master secret | Required |
| Connection ID (client) | OnlySendCIDGenerator |
| Connection ID (server) | RandomCIDGenerator(8) |
| Handshake timeout | 30 seconds |
InsecureSkipVerify is set on the client — the security property provided is traffic obfuscation, not mutual authentication.
Transport options
By default the client connects to the TURN server over TCP, which wraps STUN messages in a 2-byte length-prefixed framing layer (turn.NewSTUNConn). If TCP is throttled by your network you can switch to UDP with the -udp flag. UDP typically gives higher throughput at the cost of slightly more exposure to packet loss on the path to the TURN server.
Direct mode (no DTLS)
Passing-no-dtls disables the DTLS layer and sends raw WireGuard packets through TURN without obfuscation. This lets you connect to a standard WireGuard server without the proxy server binary, but the traffic pattern is no longer disguised as WebRTC and may result in a ban from the TURN provider.
Rate limits
- VK enforces a bandwidth cap of approximately 5 Mbit/s per TURN allocation. Opening 16 parallel connections (default) multiplies the effective cap. Use
-n 1for a more stable single-stream connection. - Yandex (now closed) did not enforce a per-allocation cap but treated excessive parallel participants as abuse. The default for Yandex was therefore
-n 1.