STUN, TURN, ICE в Softphone.Pro
1. Что такое STUN и зачем он нужен?
Для совершения звонков по SIP протоколу стороны диалога (будем называть их Оператор и Клиент) должны "договориться", по каким адресам передавать друг другу голосовые данные. Если обе стороны диалога имеют свой IP адрес, который не меняется и не используется другими компьютерами или SIP телефонами, проблем нет. Оператор и Клиент сообщают друг другу свои адреса, устанавливают прямое соединение и обмениваются данными (голосовыми пакетами)
Если же между Оператором и Клиентом невозможно установить прямое соединение, ситуация усложняется. Например, Оператор и/или Клиент могут находиться в разных сетях, (например, в корпоративной сети или сети домашнего оператора Интернета), которые используют технологию NAT для доступа к сети множества клиентов с одним и тем же внешним IP адресом. В таком случае могут возникнуть различные неполадки, например:
- софтфон не сможет зарегистрироваться на АТС;
- при совершении звонков возникнет односторонняя слышимость (оператор не слышит клиента или наоборот);
- звонки сбрасываются в процессе разговора;
- оператору не поступают входящие звонки.
Это вызвано тем, что софтфон "не знает", что находится в сети, которая использует NAT, и сообщает другой стороне диалога свой локальный адрес, по которому нельзя направить информацию не из сети, в которой находится софтфон.
Решить данную проблему и призвана технология STUN. Она позволяет Оператору и Клиенту использовать сторонний сервер, чтобы корректно определить адреса друг друга для передачи голосовых данных. Далее в статье мы разберём, какие реализации STUN существуют, и как их настроить в Softphone.Pro.
2. STUN, TURN и ICE - одно и то же?
Ранее вы могли слышать такие слова как ICE и TURN в дополнение к упомянутой выше технологии STUN. Что же они означают?
Быстрый ответ на данный вопрос таков: STUN, TURN и ICE это протоколы, которые призваны решить одну и ту же проблему адресации устройств за межсетевыми экранами и NAT. В зависимости от конфигурации вашей сети, требований безопасности и других факторов имеет смысл использовать тот или иной протокол.
Остановимся на каждом из протоколов подробнее.
2.1. STUN
Подробно работа технологии STUN описана в RFC 3489, RFC 8489 и RFC 5780. Опишем основные принципы данной технологии.
STUN (Simple Traversal of UDP through NAT или Session Traversal Utilities for NAT) это клиент-серверный протокол, который позволяет приложениям обнаруживать наличие и тип межсетевых экранов и NAT. Для определения адреса STUN-клиенты (например, софтфон Оператора или АТС) отправляют запросы к STUN-серверу, и получают в ответ адрес, с которого запрос пришёл на STUN-сервер. Этот адрес отправляется другой стороне диалога для отправки голосовых пакетов.
Схема взаимодействия STUN-клиента (софтфона) и STUN-сервера:
STUN-сервер должен находиться за пределами сетей, в которых находятся софтфон Оператора и АТС, что не всегда может быть удобно или возможно в определённых конфигурациях сети (например, с усиленными требованиями к безопасности и контролем за внешними подключениями).
Обратите внимание, что протокол STUN не сработает, если одна или обе стороны диалога находятся за симметричным NAT. Такой тип NAT обычно применяют в целях безопасности, так как маршрутизатор будет принимать соединения и передавать данные только от узлов, к которым ранее подключался клиент. Для обхода симметричных NAT используется протокол TURN.
2.2. TURN
Протокол TURN (Traversal Using Relays around NAT) предназначен для работы с симметричным NAT. TURN-сервер является посредником между двумя устройствами, которые находятся за симметричным NAT. Таким образом, TURN является скорее дополнением к протоколу STUN, и часто STUN-серверы также являются TURN серверами.
Схема передачи голосовых пакетов через TURN-сервер:
Данный протокол решает один из недостатков STUN (позволяет работать за симметричным NAT), но не решает другой (требование подключения к внешнему серверу). Также добавляется ещё один недостаток - так как все данные (в нашем примере голосовые пакеты) идут не напрямую от одного клиента к другому, а передаются через сервер-"посредник", это добавляет накладных расходов в виде задержки.
Актуальное описание протокола TURN можно найти в RFC 8656.
2.3. ICE
Протокол ICE (Interactive Connectivity Establishment) - дополнение к протоколам STUN и TURN. Данный протокол пытается автоматически определить, какой способ подключения использовать:
- Сначала он пытается установить прямое подключение между устройствами.
- Если не удалось установить прямое соединение, осуществляется попытка установить соединение через STUN.
- Если и это невозможно, используется TURN.
К достоинствам ICE можно отнести простоту для конечного пользователя (ему не нужно задумываться, какой у него NAT и какую настройку лучше включить), а к недостаткам, унаследованным от STUN и TURN добавляется заметное время для установки соединения (так как клиенты перед установкой соединения проверяют все возможные способы подключения).
Протокол ICE описан в RFC 8445, а его применение в SIP протоколе - в RFC 5768.
3. Надо ли настраивать свой STUN-сервер для звонков через софтфон?
Существует множество STUN-серверов, которые можно использовать в софтфонах. Обычно выбор сервера обусловлен географическим положением сервера и требованиями безопасности в вашей сети.
Для работы Softphone.Pro использует наш сервер stun.softphone.pro
, который настроен в приложении по умолчанию. Если же ваши требования безопасности не позволяют использовать сторонние STUN-сервера, или вы хотите полностью контролировать всю инфраструктуру, которую использует софтфон, вы можете настроить и использовать свой STUN-сервер, и указать его в настройках приложения.
4. Как настроить STUN и ICE в Softphone.Pro
По умолчанию Softphone.Pro использует STUN в качестве протокола для обхода межсетевых экранов и NAT, с адресом нашего сервера stun.softphone.pro
. Также можно включить ICE или отключить обход файрвола (если софтфон сотрудника и АТС находятся в одной сети).
4.1. Настройка обхода файрвола в Softphone.Pro
В настройках приложения перейдите на вкладку настроек нужной SIP учётной записи, и измените значение настройки Способ обхода брандмауэра:
- STUN - использовать протокол STUN;
- ICE - использовать протокол ICE;
- Нет - не использовать обход файрвола.
4.2. Настройка обхода файрвола в Softphone.Pro Team
Используйте централизованную настройку софтфонов в Team и добавьте в файл конфигурации пользователя следующие строки:
[SipAccount1] FirewallTraversalMethod=STUN
Чтобы включить STUN;
[SipAccount1] FirewallTraversalMethod=ICE
Чтобы включить ICE, или
[SipAccount1] FirewallTraversalMethod=LOCAL
чтобы выключить обход файрвола.
5. Как настроить свой STUN-сервер на Linux
Если вы хотите использовать свой STUN-сервер (например в целях безопасности или увеличения надёжности), вам потребуется установить и настроить его. После проверки работы потребуется настроить DNS записи для сервера, и указать адрес сервера в настройках Softphone.Pro.
5.1. Установка и настройка своего STUN-сервера
Ниже кратко описана процедура установки и настройки STUN-сервера. Будем использовать пакет coturn для Linux (в примере Ubuntu Server 24.04 LTS). Больше информации вы можете найти на GitHub странице проекта coturn.
Вам понадобится Linux сервер с публичным IP адресом и доступ к нему с правами суперпользователя.
5.1.1. Установите сервер coturn из репозитория командой:
apt install coturn
5.1.2. Будет установлен и запущен сервис с именем coturn. Откройте файл настроек /etc/turnserver.conf
и задайте настройки сервера, раскомментируя или добавляя нужные строки:
listening-port
: задайте порт, по которому сервер будет принимать подключения по протоколам UDP и TCP (по умолчанию 3478). Этот порт вам понадобится для настройки DNS;tls-listening-port
: задайте порт, по которому сервер будет принимать подключения по протоколу TLS (по умолчанию 5349). Этот порт вам понадобится для настройки DNS;external-ip
: укажите публичный IP адрес вашего сервера;min-port
: укажите минимальное значение диапазона портов, которые открываются для UDP подключений (по умолчанию 49152);max-port
: укажите максимальное значение диапазона портов, которые открываются для UDP подключений (по умолчанию 56635);stun-only
: включите данный параметр, чтобы сервер работал только в режиме STUN-сервера.
5.1.3. Перезапустите сервер, чтобы применить новые настройки:
systemctl restart coturn
Сервер настроен и готов принимать запросы на порты, указанные в файле настроек. Для использования данного сервера в Softphone.Pro нужно настроить DNS зону и указать адрес сервера в Softphone.Pro.
5.2. Настройка DNS для STUN
Для увеличения стабильности и надёжности работы STUN-сервера обычно используют несколько серверов. Распределять запросы клиентов между несколькими серверами помогают A записи, AAAA записи и SRV записи в DNS.
A запись связывает домен с IP адресом сервера в формате IPv4. AAAA запись предназначена для связи домена с IP адресом формата IPv6.
SRV это особый вид DNS записи, который позволяет одному домену поддерживать работу сервисов (в данном примере STUN) на различных серверах, что позволяет гибко настраивать инфраструктуру, сохраняя при этом простоту настройки для клиента.
Пример настройки нескольких STUN-серверов:
- Предположим, что у нас есть два основных сервера с IP адресами 198.51.100.20 и 203.0.113.30 и резервный сервер с IP адресом 203.0.113.40.
- Добавляем в DNS A записи для основных серверов с адресами
stun1.example.com
иstun2.example.com
и резервного сервера с адресомstun-reserve.example.com
. - Добавляем A записи для адреса
stun.example.com
с IP адресами основных серверов (используется в качестве резервного механизма получения адреса). - Добавляем SRV записи для всех адресов сервисов.
Добавленные в DNS записи:
Все IP адреса приведены для примера.
stun1.example.com. 60 IN A 198.51.100.20 stun2.example.com. 60 IN A 203.0.113.30 stun-reserve.example.com. 60 IN A 203.0.113.40 stun.example.com. 60 IN A 198.51.100.20 stun.example.com. 60 IN A 203.0.113.30 _stuns._tcp.stun.example.com. 60 IN SRV 1 0 5347 stun1.example.com. _stuns._tcp.stun.example.com. 60 IN SRV 1 0 5347 stun2.example.com. _stuns._tcp.stun.example.com. 60 IN SRV 2 0 5347 stun-reserve.example.com. _stun._tcp.stun.example.com. 60 IN SRV 1 0 3477 stun1.example.com. _stun._tcp.stun.example.com. 60 IN SRV 1 0 3477 stun2.example.com. _stun._tcp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com. _stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun1.example.com. _stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun2.example.com. _stun._udp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com.
Описание столбцов SRV записи:
- Адрес сервиса: состоит из имени сервиса, протокола и доменного имени;
- Время жизни записи: задаётся в секундах;
- Класс: для SRV записей используется IN;
- Тип записи: SRV;
- Приоритет: сначала клиенты обрабатывают записи с меньшим приоритетом;
- Вес: порядок обработки записей с одинаковым приоритетом зависит от заданного веса;
- Порт: порт для подключения к серверу;
- Цель: доменное имя сервера назначения.
Порт в 7 столбце SRV записи:
- для сервиса
_stun._
- это порт из параметраlistening-port
- для сервиса
_stuns._
- это порт из параметраtls-listening-port
Проверить настроенные записи можно командой nslookup. Пример команды для проверки добавленной SRV записи _stun._udp.stun.example.com.
и A записи stun.example.com.
:
5.3. Настройка адреса STUN-сервера в Softphone.Pro
Настроить адрес STUN-сервера в Softphone.Pro можно в разделе SIP настройки, в поле STUN сервер:
Можно указать несколько серверов через пробел.
Для настройки своего адреса STUN-сервера в сервисе Softphone.Pro Team используйте централизованную настройку софтфонов в Team и добавьте в файл конфигурации пользователей следующие строки:
[AppSettings] StunServers=stun.example.com
Можно указать несколько серверов через пробел.
5.4. Работа STUN-клиента с DNS
Напомним, что мы настроили DNS зону, добавив в неё следующие записи:
stun1.example.com. 60 IN A 198.51.100.20 stun2.example.com. 60 IN A 203.0.113.30 stun-reserve.example.com. 60 IN A 203.0.113.40 stun.example.com. 60 IN A 198.51.100.20 stun.example.com. 60 IN A 203.0.113.30 _stuns._tcp.stun.example.com. 60 IN SRV 1 0 5347 stun1.example.com. _stuns._tcp.stun.example.com. 60 IN SRV 1 0 5347 stun2.example.com. _stuns._tcp.stun.example.com. 60 IN SRV 2 0 5347 stun-reserve.example.com. _stun._tcp.stun.example.com. 60 IN SRV 1 0 3477 stun1.example.com. _stun._tcp.stun.example.com. 60 IN SRV 1 0 3477 stun2.example.com. _stun._tcp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com. _stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun1.example.com. _stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun2.example.com. _stun._udp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com.
Опишем процесс, которому следует STUN-клиент (в нашем случае Softphone.Pro) при настроенном DNS с записями SRV.
- Клиент использует доменное имя STUN-сервера из настроек, и ищет в нем SRV запись вида:
_stun._udp.stun.example.com.
(если STUN работает через UDP);_stun.tcp.stun.example.com.
(если STUN работает через TCP);_stuns.tcp.stun.example.com.
(если STUN работает через TLS);
- Если найдены SRV записи, в ответ клиент получает приоритизированный список адресов (5 столбец SRV записи) для запрошенного сервиса (stun или stuns).
- Клиент начинает обрабатывать список в порядке увеличения приоритета:
- В примере клиент сначала пытается подключиться к адресам c приоритетом 1.
- Адрес выбирается случайным образом из записей с одинаковым весом (6 столбец SRV записи). Если веса отличаются, адрес выбирается по алгоритму описанному в RFC 2782.
- Адрес, выбранный для подключения, удаляется из списка для приоритета.
- Для выбранного адреса клиент делает запрос к DNS и получает A или AAAA запись с IP адресом сервера.
- Клиент пытается подключиться к полученному IP адресу по порту, указанному в SRV записи.
- Если клиенту не удалось подключиться к серверу, он пытается подключиться к следующему серверу из списка, пока список не становится пустым.
- Если есть SRV записи с разными приоритетами, клиент повторяет пункт 3 для следующего приоритета.
- Если SRV запись не найдена на сервере, клиент ищет A и AAAA записи указанного доменного адреса STUN-сервера, и пытается подключиться по найденным адресам с портами по умолчанию (3478 для TCP и UDP запросов, 5349 для подключения к STUN по TLS).
Пример записи из пункта 5.2 текущей инструкции будет обработан софтфоном следующим образом:
- Для примера возьмём подключение к STUN по UDP. В софтфоне настроен адрес STUN сервера stun.example.com
- Софтфон делает запрос к DNS на поиск записи _stun._udp.stun.example.com., и находит SRV запись со следующими списками адресов:
- Приоритет 1:
_stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun1.example.com. _stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun2.example.com.
- Приоритет 2:
_stun._udp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com.
- Приоритет 1:
- Так как у серверов из первого списка указан одинаковый вес 0, софтфон выбирает случайным образом сервер из списка и делает запрос к DNS на A запись. Для примера возьмём, что он выбрал сервер
stun1.example.com
, данный сервер удаляется из списка для приоритета 1. - Списки адресов для следующего подключения на данный момент выглядят так:
- Приоритет 1:
_stun._udp.stun.example.com. 60 IN SRV 1 0 3477 stun2.example.com.
- Приоритет 2:
_stun._udp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com.
- Приоритет 1:
- Софтфон получает IP адрес сервера
stun1.example.com
из A-записи в DNS:
stun1.example.com. 60 IN A 198.51.100.20
и пытается подключиться к STUN-серверу по указанному IP (198.51.100.20) и порту из SRV записи (3477) по адресу198.51.100.20:3477
; - Если не удалось установить соединение, софтфон берёт оставшийся в списке для приоритета 1 адрес
stun2.example.com
и удаляет его из списка для приоритета 1. - Списки адресов для следующего подключения на данный момент выглядят так:
- Приоритет 1: пустой список
- Приоритет 2:
_stun._udp.stun.example.com. 60 IN SRV 2 0 3477 stun-reserve.example.com.
- Софтфон получает IP адрес сервера
stun2.example.com
из A-записи в DNS:
stun2.example.com. 60 IN A 203.0.113.30
и пытается подключиться к STUN-серверу по адресу203.0.113.30:3477
- Если не удалось подключиться и ко второму адресу, софтфон переходит к списку адресов для приоритета 2, так как список для приоритета 1 пуст.
- Cофтфон берёт единственный адрес
stun-reserve.example.com
и удаляет его из списка для приоритета 2. - Списки адресов для следующего подключения на данный момент выглядят так:
- Приоритет 1: пустой список
- Приоритет 2: пустой список
- Софтфон получает IP адрес сервера
stun-reserve.example.com
из A-записи в DNS:
stun-reserve.example.com. 60 IN A 203.0.113.40
и пытается подключиться к STUN-серверу по адресу203.0.113.40:3477
. - Если подключение к STUN-серверу успешно, то софтфон использует его для получения своего внешнего IP адреса и дальнейшей работы.
Подробно работа SRV записей в DNS описана в RFC 2782, а обнаружение STUN-сервера в DNS описано в пункте 8 RFC 8489.