Проблемы в работе ПО использующего WebRTC

Доброго времени суток.

В работе наших некоммерческих проектов мы используем голосовую систему, написанную на основе открытого медиа-сервера mediasoup, использующее в свою очередь WebRTC и SFU-подход к подключению пиров, используем только для голосового чата. Как и положено, имеем self-hosted TURN сервера (используем coturn) для перенаправления траффика в случае проблем с прямым подключением.

Данное решение мы используем с 2018 года и все работало более, чем отлично. Массовые тревожные звонки о сбоях в работе начали получать 13 марта. Впервые человек пожаловался с похожей проблемой 9 марта. Причем как с нашего проекта, так и с проектов наших партнеров. У большого процента людей начали возникать перебои в связи: они могли слышать других клиентов, но их при этом никто не слышал, такое ощущение, что траффик даже не доходил до наших серверов. В любой нормальной ситуации, я бы подумал, что это проблема с оборудованием или какие-то атаки, но после тестирования с несколькими “жертвами” данной проблемы, мы обнаружили, что использование VPN в 100% случаях решает эти проблемы. Попросив массово использовать какие-либо VPN сервисы для дальнешей диагностики, тенденция подтвердилась - наличие VPN подключения в 100% случаях решает проблемы.

К сожалению, просить людей использовать VPN не очень удобное решение. Проведя небольшой анализ, мы обнаружили, что, скорее всего, проблемы идут с траффиком где-то на уровне TURN сервера, который должен через себя прогонять весь траффик пиров, которые не смогли подключиться напрямую (без NAT’а). К сожалению, найти конкретную причину мы так и не смогли.

Немного дополнительной информации, возможно бесполезной: медиа-сервера и TURN-сервера при этом хостились в разных датацентрах и в том числе в разных странах (Selectel, OVH, DataPro). Пользователи испытывали проблемы по всей России. Никаких обходных костылей не использовалось - прямые подключения без проксей. Сертификаты для WSS подключений к медиа-серверу генерировались через Let’s Encrypt. Доменные адреса в регионе .ru. Мы так же обнаружили что как минимум у нескольких людей с подобной проблемой наш TURN сервер даже не определялся через Trickle ICE (возвращал “not reachable?” при полной работоспособности). Как временное решение попробовали голосовое решение на основе Mumble - работало отлично, т.к. по всей видимости проблемы именно с WebRTC.

Есть какие-то идеи как это можно анализировать и потенциально решить? По моему субъективно-непрофессиональному мнению все признаки на какую-то очень кривую блокировку. Буду рад услышать мнения и предложения.

On 2021-12-01, there was blocking by TSPU of WebRTC (specifically DTLS) with a certain fingerprint: OONI reports of Tor blocking in certain ISPs since 2021-12-01 - #3 by ValdikSS. This blocking was evidently targeted at Snowflake. After fixing the DTLS fingerprint (Make Snowflake's DTLS fingerprint more similar to popular WebRTC implementations (#40014) · Issues · The Tor Project / Anti-censorship / Pluggable Transports / Snowflake · GitLab), Snowflake began working again, and it has worked since.

One possibly important difference is that Snowflake does not use TURN servers. Unlike a chat application, the Snowflake client does not care which proxy it has a WebRTC connection with, so a central server matches clients with proxies according to NAT type so that a TURN server is not needed.

О проблемах с WebRTC уже писали:

Наиболее вероятно, это попытка заблокировать Tor Snowflake, как сказал @tango выше.

Вы обращались в Роскомнадзор и к провайдеру? Если обращались, что они ответили?
Сейчас проблема всё ещё наблюдается?

В качестве решения, можете попробовать настроить TCP или TCP+TLS (TURNS) на coturn, но точно не уверен, поддерживают ли его все браузеры.

О проблемах с WebRTC уже писали:

Извиняюсь, искал “webrtc” здесь по темам, но не по сообщениям.

Вы обращались в Роскомнадзор и к провайдеру? Если обращались, что они ответили?
Сейчас проблема всё ещё наблюдается?

Лично я не обращался, т.к. у меня проблем нет. Пользователей не просил, у всех разные провайдеры, у кого-то, как у меня, Ростелеком, и у него ничего не работает, у кого-то Ростелеком на дальнем востоке и все работает. Думаете это имеет смысл?

В качестве решения, можете попробовать настроить TCP или TCP+TLS (TURNS) на coturn, но точно не уверен, поддерживают ли его все браузеры.

Думали над этим, хорошее предложение, попробуем реализовать. Насчет работоспособности браузеров мы не переживаем т.к. приложение использует CEF ± последних версий.

Я проблему решил поднятием TURN на тех же серверах.
Причем при поднятии TURN на других, схема не работала. У нас медиа-сервер судя по всему не сильно гибок в сетевом плане и не мог поднять соединения с удаленным TURN.

У нас стоят и на тех же серверах, что и медиасервер, тоже. Пробовали с другими серверами в т.ч. в других странах.

Использование TCP/TCP+TLS с coturn не помогло в нашем случае.

Убедитесь, что действительно используется TLS для передачи данных. Снимите трафик соединения хотя бы у одного пользователя, у кого наблюдается проблема.

Добрый день! Подскажите, вы решили проблему? Тоже используем медиасуп и столкнулись с аналогичными проблемами. Установка TURN сервера COTURN на один сервер с mediasoup не помогла. Настройки coturn следующие:

listening-port=3478
tls-listening-port=5349
fingerprint
verbose
lt-cred-mech
user=USER:PASSWORD
realm=turn.example.ru
cert=/etc/letsencrypt/live/turn.example.ru/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.ru/privkey.pem
dh2066
no-tlsv1
no-tlsv1_1
syslog
cipher-list="ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384"

Запишите PCAP, чтобы понять, в чём может быть проблема. Либо выдайте мне доступ и проинструктируйте, как воспроизвести проблему.

Спасибо, что откликнулись. Можете связаться в скайпе со мной?
скайп - iluha90

Насколько понимаю, блокировка так или иначе затрагивает только библиотеку Pion, в частности supported_groups, который он отправляет.
Если у кого-то есть другие данные, или если кто-то может предоставить дамп трафика неработающей конфигурации, прошу написать мне или выложить дамп сюда.

У нас таже самая проблема, получается так, что от клиента трафик уходит, но другим уже не доходит. VPN решает проблему. Пробовали европейские сервера, снгшные и Российские - не работают. Сервера на территории США - работают для этих же российских клиентов.

Интересно. Мы с @diwenx обнаруживали, что ТСПУ исключает некоторые фильтры для трафика внутри России, но для США такого не видели. Можете назвать AS или хостера, где работает?

И кто-нибудь, запишите уже pcap’ы или дайте мне доступ к вашим системам, чтобы я их записал самостоятельно, или пришлите ссылку на какой-то публичный инстанс, где это развёрнуто.

AWS, регион N. Virginia

Нам пишут:

Наконец-то мем был обнаружен, проблема появляется у некоторых людей и оказывается, что актуальна только на старых версиях chromium. У нас стоит 91 и на ней ничего не работает. Пробовали заходить с 95 версии хрома, уже работает отлично

echo 16FEFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D00170018 | xxd -ps -r > chromium-clienthello-maybe.bin
00000000  16 fe ff 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 1d 00 17 00 18  |................|
00000070

supported_groups начинается с 0x6a.

chromium-maybe-91-clienthello-tspu-filtered.pcapng (680 Bytes)

As of 1 June 2022, the following WebRTC DTLS packets are getting filtered.

The filter is applied for both DTLS v1.0 in record (16 fe ff), which is used by both Chrome and Firefox in ClientHello, and DTLS v1.2 in record (16 fe fd), which is used at least by Jitsi Meet, all at offset 0. Then, 00 1D 00 17 00 18 at 0x6e offset or 0x59 offset or 0x6a offset is checked.

Old pattern and old offset 0x59, but with additional check for DTLS version:
16 FE [FD or FF] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1D 00 17 00 18 00

Old pattern and new offset 0x6e (used in the first ClientHello DTLS packet in Snowflake, the one without Cookie and with message sequence = 0), with additional check for DTLS version:
16 FE [FD or FF] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1D 00 17 00 18 00

Old pattern and new offset 0x6a, presumably Chromium <= 91:
16 FE [FF or FD] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1D 00 17 00 18

Обнаружил дополнительные смещения supported_groups, которые подвергаются блокировке.
Всего 7 штук. Номер в имени файла означает количество нулей после 16 FE FD/FF и до supported_groups.
webrtc-filtered.zip (1.3 KB)

I got a private message saying that all these offsets are filtered: 0x50, 0x54, 0x59, 0x6a, 0x6e, 0x7e, 0x82.

I guess the question is, is there a commonly used offset that is not filtered?

Your 7 discovered offsets match the report exactly.

$ unzip -l webrtc-filtered.zip 
Archive:  webrtc-filtered.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      112  2022-06-01 00:30   webrtc-filtered-103.bin
      116  2022-06-01 00:30   webrtc-filtered-107.bin
      132  2022-06-01 00:30   webrtc-filtered-123.bin
      136  2022-06-01 00:30   webrtc-filtered-127.bin
       86  2022-06-01 00:30   webrtc-filtered-77.bin
       90  2022-06-01 00:30   webrtc-filtered-81.bin
       95  2022-06-01 00:30   webrtc-filtered-86.bin
---------                     -------
      767                     7 files
>>> print(", ".join(sorted([hex(x+3) for x in (103, 107, 123, 127, 77, 81, 86)])))
0x50, 0x54, 0x59, 0x6a, 0x6e, 0x7e, 0x82