setup.md

July 26, 2026 · View on GitHub

Как это работает

Приложение получает IP адрес и порт TURN relay из URL звонка VK (или берет эту информацию непосредственно из настроек). Звонок необходимо создать вручную (или найти ссылку через поиск) и скопировать ссылку в настройки приложения.

Затем, с точки зрения iOS, приложение строит туннель к серверу TURN relay. С точки зрения самого TURN relay, приложение создает набор аллокаций (соединений) от клиентского устройства до него и указывает ему IP адрес и порт сервера, к которому уже строит аллокации (соединения) TURN relay.

Чтобы принять эти соединения на сервере должно работать vk-turn-proxy приложение, которое реализует тот же протокол, что и клиентское приложение. В зависимости от выбранного режима работы сетевые пакеты оборачиваются различными дополнительными уровнями шифрования и имитации сетевых протоколов (но во всех режимах работы присутствует WireGuard слой) и отправляются к TURN relay поверх созданных соединений, который перекидывает их на сервер.

Сервер снимает эти дополнительные уровни (кроме WireGuard) и отдает пакеты WireGuard серверу, который в общем случае должен быть запущен рядом на том же сервере. В клиентском приложении WireGuard часть встроена внутри, дополнительно запускать WireGuard на клиентском устройстве не надо.

Обратное движение пакетов аналогичное - на сервере WireGuard отдает пакеты серверному приложению vk-turn-proxy, оно оборачивает пакеты дополнительными уровнями и отправляет TURN relay, тот отправляет клиентскому приложению.

Что необходимо для работы

  • URL (или несколько) VK звонка.

  • выделенный или VPS сервер, на котором будет работать серверное приложение vk-turn-proxy. К нему будет подключаться TURN relay, поэтому сервер должен иметь публичный IP адрес, достижимый из Интернет и на firewall (если он есть) должен быть открыт доступ к паре IP:порт.

  • на сервере должен быть установлен, настроен и запущен WireGuard сервер (или какая-то другая реализация WireGuard протокола).

  • в общем случае, на сервере должна быть настроена маршрутизация между интерфейсами (например, net.ipv4.ip_forward=1 в linux или net.inet.ip.forwarding=1 в FreeBSD).

  • в общем случае, на сервере должен быть настроен NAT, который должен применяться к IP адресам клиентов WireGuard. другой вариант - когда пакеты клиентов WireGuard отправляются дальше в какой-то другой туннель.

Режимы работы

Клиентское приложение поддерживает 5 режимов работы:

image

Legacy

режим совместимости с оригинальным сервером. В настоящее время хотя и продолжает работать, но дает очень низкую скорость из-за шейпинга на стороне VK (если используется VK TURN relay).

SRTP

режим по умолчанию для данного iOS приложения. Требует использования сервера, который понимает данный протокол.

Для запуска серверной части необходимо скачать бинарный файл под нужную операционную систему и процессорную архитектуру из раздела Releases. Дать права на исполнение. Запускать с ключами:

./server-linux-amd64 -listen XXX.XXX.XXX.XXX:56000 \
                     -connect YYY.YYY.YYY.YYY:51820 \
                     -srtp -logfile /var/log/srtp.server.log

здесь:

  • XXX.XXX.XXX.XXX: IP адрес сервера (в общем случае это его публичный адрес)

  • 56000: порт, на котором будет слушать серверное приложение (при наличии firewall, необходимо разрешить доступ к этим IP:port)

  • YYY.YYY.YYY.YYY:51820 - адрес и порт, на котором должен слушать WireGuard сервер (IP обычно используется локальный адрес 127.0.0.1)

SRTP-WRAP

режим совместимости с серверами других авторов:

https://github.com/Moroka8/vk-turn-proxy/releases

https://github.com/samosvalishe/vk-turn-proxy/releases

SRTP-WRAP-A

режим совместимости с сервером WDTT. В этом сервере WireGuard встроен внутрь серверного приложения, поэтому отдельно запускать и настраивать его на сервере не надо.

SRTP-WRAP-S

режим совместимости с сервером FreeTurn.

Настройки клиентского приложения

Начальный экран настроек выглядит так:

image

В поле VK Call Link необходимо добавить URL звонка из VK (https://vk.ru/call/join/xxxxxxxxxxxxxxxxxxxxxx). URL может быть несколько, каждый на отдельной строке.

Раздел Servers содержит список серверов, каждый из которых настраивается отдельно. Server1 создается автоматически с набором настроек по умолчанию (частично пустыми).

Переключатель VK Account Auth включает работу в неанонимном режиме. Использовать этот режим следует с осторожностью и в общем случае только тогда, когда VK не разрешает подключаться к звонкам анонимно.

При первом включении будет открыт WebView для ручной аутентификации на vk.ru. Если она будет успешна, то приложение сохранит cookies в Keychain и в дальнейшем будет их использовать для получения credentials. Приложение будет показывать дату, до которой действуют сохраненные cookies. Их можно удалить или перелогиниться:

image

В этом режиме каждый URL звонка дает возможность открыть 20 соединений/аллокаций. Если нужно больше 20, то нужно два URL, больше 40 - три URL (максимальное количество соединений в приложении ограничено 50, поэтому больше трех URL добавлять нет необходимости).

Legacy или SRTP режим

image

Имя сервера можно изменить.

В разделе Transport необходимо ввести следующие настройки:

  • в поле Proxy server - IP адрес и порт сервера, где запущена серверная часть vk-turn-proxy (то, что настроено в параметре -listen XXX.XXX.XXX.XXX:56000 на сервере)
  • опционально адрес и порт непосредственно TURN relay (в общем случае оставляем пустым)
  • выбрать режим подключения (server mode) SRTP (или Legacy)
  • опционально включить UDP в качестве транспорта (может быть несколько быстрее, чем TCP по умолчанию, но TCP значительно устойчивее)
  • можно изменить количество соединений, от этого параметра зависит общая скорость работы с Интернет (на 30 соедиениях в идеальных условиях можно получить 50+ Мбит/сек). Максимальное количество - 50.
  • можно изменить таймаут, который применяется между попытками при неудачном решении капчи
image

В разделе WreGuard необходимо ввести:

  • в поле Private Key приватный ключ клиента (на стороне WireGuard сервера в разделе [Peer] для этого клиента должен быть парный ему публичный ключ)
  • в поле Peer Public Key публичный ключ WireGuard сервера
  • опционально в поле Preshared Key общий ключ шифрования (должен быть равным PresharedKey на стороне WireGuard сервера в разделе [Peer] для этого клиента, в общем случае оставляем пустым)
  • в поле Tunnel Address - IP адрес и маску (должны соответствовать AllowedIPs на стороне WireGuard сервера в разделе [Peer] для этого клиента)
  • в поле DNS Servers IP адрес (или несколько через запятую) DNS сервера, который будет использоваться поверх туннеля

Далее можно создать новый сервер с настройками по умолчанию, скопировать настройки этого сервера в новый сервер или удалить сервер:

image

SRTP-WRAP режим

В этом режиме в разделе Transport появляется дополнительное обязательное поле для ввода WRAP ключа:

image

ключ должен совпадать с ключом заданным на сервере через параметр -wrap-key. Создать его можно вручную (32 байта hex, 64 символа) или сгенерировать на сервере через однократный запуск с ключом -gen-wrap-key

Раздел WireGuard аналогичен режиму SRTP.

SRTP-WRAP-S режим

В этом режиме в разделе Transport так же появляется дополнительное обязательное поле для ввода WRAP ключа и поле Client ID:

image
  • в поле WRAP key ключ должен совпадать с ключом заданным на сервере FreeTurn через параметр -obf-key. Создать его можно вручную (32 байта hex, 64 символа) или сгенерировать на сервере через однократный запуск с ключом -gen-obf-key

  • в поле Client ID идентификатор устройства, который передается серверу FreeTurn. Поле заполняется автоматически, но может быть изменено.

Кроме того, необходимо выбрать профайл обфускации, который должен соответствовать профайлу, заданному на сервере FreeTurn через параметр -obf-profile:

image

Раздел WireGuard аналогичен режиму SRTP.

SRTP-WRAP-A режим

В этом режиме в разделе Transport появляются дополнительные поля для ввода пароля WDTT и Device ID:

image
  • в поле Server Password пароль. то, что у WDTT называется "главный пароль туннеля".
  • в поле Device ID идентификатор устройства, который передается серверу WDTT. Поле заполняется автоматически, но может быть изменено.

Раздела WireGuard в этом режиме нет, так как WDTT сервер присылает эти настройки клиенту после установления соединения в автоматическом режиме.

Автоматические ссылки

Приложение регистрирует ссылки вида vkturnproxy:// на себя, то есть при нажатии на такую ссылку iOS должен передать ее в приложение vk-turn-proxy-ios. Альтернативно можно в самом приложении нажать Settings - Import from conection link.

Ссылка содержит в закодированном base64 виде настройки, позволяющие не вводить их вручную, а заполнить их автоматически.

Для создания ссылок прилагается скрипт на Python. Он может работать в трех режимах:

  • запуск без параметров. в этом случае все необходимые настройки должны быть заполнены в самом скрипте.
  • запуск с параметром имя файла. в этом случае предполагается, что это имя файла указывает на файл конфигурации json (либо файл бэкапа, см. следующий раздел). В этом режиме можно добавить параметр --server ServerName и тогда будет использована конфигурация этого конкретного сервера.
  • запуск с параметром -gen-peer-key. в этом случае скрипт создаст новую пару приватный/публичный ключ в формате, который использует WireGuard и напечатает не только ссылку vkturnproxy:// но и соответствующий раздел Peer в конфигурации WireGuard. После параметра -gen-peer-key можно дополнительно задать ipaddr/mask.

Пример запуска при добавлении нового клиента:

python3 quick_link.py -gen-peer-key 192.168.100.2/24

Результат:


vkturnproxy://import?data=eyJzZXR0aW5ncyI6eyJkbnNTZXJ2ZXJzIjoiMS4xLjEuMSIsIm51bUNvbm5lY3Rpb25zIjozMCwicGVlckFkZHJlc3MiOiIxMTEuMjIyLjExMS4yMjI6NTYwMDAiLCJwZWVyUHVibGljS2V5IjoiazJtWUswNVhCdlptQjMwRnM2ZitiZnVTUURwS0s1SmNETXh1MEcvbkkzST0iLCJwcmVzaGFyZWRLZXkiOiIiLCJwcml2YXRlS2V5IjoiMEJTZW42UXYySzRiNEo4Q3dxZi91Umd4SmNUR21WYkZqU0NOa3JGZEtVMD0iLCJ0dW5uZWxBZGRyZXNzIjoiMTkyLjE2OC4xMDAuMi8yNCIsInVzZURUTFMiOnRydWUsInVzZVNydHAiOnRydWUsInVzZVVEUCI6ZmFsc2UsInVzZVdyYXAiOmZhbHNlLCJ1c2VXcmFwQSI6ZmFsc2UsInZrTGluayI6Imh0dHBzOi8vdmsucnUvY2FsbC9qb2luL2RoZndqaWplZmpmZWllZmhmZWpoZHdoaWRodXdkIiwid3JhcEtleUhleCI6IiJ9LCJ0eXBlIjoiY29ubmVjdGlvbiIsInZlcnNpb24iOjF9

[Peer]
AllowedIPs = 192.168.100.2/32
PublicKey = M8UkE3Twc0wj72z8wgizMoBVneEd0cN4IDHBlGiRyyw=

Копируем ссылку клиенту. Раздел Peer добавляем в существующий конфиг WireGuard.

Дополнительно через Settings - Import from conection link можно импортировать ссылки из WDTT и FreeTurn.

Backup/restore

В приложении в разделе Settings есть кнопки "Export Full Backup" и "Import Full Backup".

Export сохраняет json файл, в котором содержатся все настройки и дополнительно добытые credentials от VK (их время действия 8 часов, устаревшие значения игнорируются).

Import заменяет существующие настройки на данные из json файла, в том числе и credentials от VK. Кнопка "Reset TURN cache" обнуляет эти credentials.

Капча

По умолчанию приложение использует путь получения VK credentials, который в настоящий момент не требует решения капчи.

В том случае, если он не срабатывает по какой-то причине, задействуется fallback на путь, который требует решения капчи и приложение пытается сделать это в автоматическом режиме.

Если и это не срабатывает, то есть fallback на WebView для того, чтобы пользователь решил капчу вручную. Однако, этот fallback доступен только в процессе установления соединения (затем при работе в фоне его уже не вызвать, там остается только автоматический подход).

Ответы на частые вопросы, решение проблем

  • Q: есть ли версия этого клиента под другие операционные системы (Android, Windows, Macos итд)?

  • A: нет, только iOS. про существование форков от других авторов мне тоже неизвестно.

  • Q: можно ли сделать раздельное (split) туннелирование по приложениям, IP адресам, доменам?

  • A: нет, нельзя из-за ограничений iOS.

  • Q: можно ли заменить WireGuard на vless/vmess/hysteria/итд?

  • A: вообще технически можно, но в текущей архитектуре приложения нельзя.

  • Q: подключение успешно установилось и выход в Интернет есть, но очень медленно

  • A: скорее всего, это означает, что подключение было выполнено в legacy режиме. из-за шейпинга на стороне VK в нем на 30 соединениях результирующая скорость 1.5-2мбит/с.

другой возможный вариант - маленькое количество соединений в настройках. теоретический максимум одного соединения (в режиме без шейпинга) - 2мбит/с, на практике меньше из-за накладных расходов, latency, потерь. 30 соединений в идеальном варианте дают 50+мбит/сек. в более менее реальном подключении на сотовой связи, скорее, 20-25мбит. меньше соединений - меньше результирующая скорость. но и увеличивать их до бесконечности нельзя.

  • Q: подключение успешно установилось, но выхода в Интернет нет
  • A: проверьте с помощью tcpdump на сервере/VPS общается ли серверная часть vk-turn-proxy с wireguard сервером. если серверная часть запущена с ключом -connect 127.0.0.1:51820, то tcpdump надо запускать так tcpdump -n -i lo port 51820 (или, возможно, другое имя интерфейса loopback в вашей операционной системе на сервере). если в результате вы видите пакеты только в сторону WireGuard, примерно так:
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo0, link-type NULL (BSD loopback), snapshot length 262144 bytes
16:17:00.635251 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635264 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635287 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635293 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635331 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635340 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635343 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635427 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 128
16:17:00.635449 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635478 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.635568 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 80

а пакетов от WireGuard нет, то это, скорее всего означает, что есть то или иное несоответствие между настройками WireGuard в iOS клиенте и на сервере (неправильный публичный ключ сервера, неправильный приватный ключ клиента, неправильный IP адрес на стороне клиента). другой возможнный вариант - это WireGuard не слушает на том IP:порт, на который вы настроили серверную часть vk-turn-proxy.

если же пакеты ходят в обе стороны, примерно так:

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo0, link-type NULL (BSD loopback), snapshot length 262144 bytes
16:17:00.657457 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 256
16:17:00.657462 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.657470 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 92
16:17:00.657489 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.657627 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 148
16:17:00.657663 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.657670 IP 127.0.0.1.40857 > 127.0.0.1.51820: UDP, length 96
16:17:00.683703 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96
16:17:00.683703 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96
16:17:00.683820 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96
16:17:00.683929 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96
16:17:00.684726 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96
16:17:00.684982 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96
16:17:00.684982 IP 127.0.0.1.51820 > 127.0.0.1.40857: UDP, length 96

а Интернета нет, то проблема лежит уже где-то дальше, например, в настройках NAT вашего сервера или firewall.