При настройке Asterisk и удаленных SIP клиентов очень часто возникают проблемы c прохождением звука, как в одну, так и в две стороны. Часто это получается, когда RTP поток по своим портам не соответствует информации содержащейся в пакете SDP. Недавно мы наблюдали такую ситуацию, когда при переадресации входящего вызова на мобильный телефон звук не ходил в обе стороны. Проблема была в операторе связи, который игнорировал данные в пакетах SDP, а оправлял трафик на уже существующий порт сессии RTP.
Для объяснения сложившейся ситуации мы решили написать данную статью. Примеры будут как для старых версий Asterisk, так и для последней 13-ой.
Рассмотрим случай, когда SIP клиент сидит за NAT
Когда SIP клиент совершает исходящий вызов, т.е. инициирует новую SIP сессию в сторону АТС (Asterisk), в теле SIP и SDP сообщений он указывает свой IP адрес и порт устройства (теорию можно прочитать здесь). Получив SIP сообщение AТС анализирует его, пытаясь понять на какой IP адрес и порт ответить SIP клиенту. Т.к. SIP устройство сидит за NAT, то IP адрес устройства, в сообщении SIP и SDP будет «серым», например, 172.17.0.15. Чтобы связь работала корректно, нам необходимо сделать так, чтобы Asterisk игнорировал IP адрес и порт из сообщений SIP и SDP, а брал информацию из пакетов стека TCP/IP. Рассмотрим какие настройки Asterisk отвечают за корректную работу. Все параметры указываются в файле sip.conf.
nat=force_rport - форсировать работу через rport, даже если его в пакетах нет nat=comedia - отправляет RTP пакеты обратно на IP адрес и порт, с которого они были получены, игнорируя информацию из сообщения SDP nat=auto_force_rport - Asterisk сам устанавливает значение параметра nat в force_rport, если определяет, что SIP пользователь находится за NAT. Данная опция по умолчанию включена в Asterisk nat=auto_comedia - Asterisk сам устанавливает значение параметра nat в comedia, если определяет, что SIP пользователь находится за NAT nat=force_rport,comedia - опция заменяющая nat=yes в более новых версия Asterisk. nat=no - не предпринимать никаких дополнительных действия для преодоления NAT, кроме рекомендаций RFC 3581. Начиная с версии Asterisk 11: nat=yes более не используется.
Для того чтобы роутер или файрвол не закрывал порты (сессии) идущие через NAT, в Asterisk есть параметр qualify. Устанавливая значение qualify=yes, Asterisk будет отправлять пакеты OPTIONS каждые 2000 миллисекунд (2 секунды), в сторону роутера, не давая закрыть сессию NAT. Также можно указать свое время в миллисекундах:
qualifyfreq=60 - частота проверки доступности клиента, т.е. после не полученного ответа от SIP клиента, Asterisk пометит клиента как Unreachable, указывается значение в секундах qualify=5000 - отправлять пакеты OPTIONS каждые 5 секунд (используется для указания не стандартного значения qualify) qualify=yes - включает отправку пакетов OPTIONS каждые 2 секунды
Рассмотрим вариант, когда и Asterisk и SIP клиенты сидят за NAT
Asterisk может указывать в пакетах SIP и SDP как IP адрес, так и имя хоста. Если порт не указан, то используется значение указанное в параметре «udpbindaddr».
externaddr = 8.8.8.8 - использовать указанный IP адрес в сообщениях SIP и SDP externaddr = 8.8.8.8:5070 - использовать указанный IP адрес и порт в сообщениях SIP и SDP externhost=voip.voipnotes.ru:5070 - использовать FQDN и порт в сообщениях SIP и SDP externrefresh=260 - интервал обновления имени FQDN
Параметр ‘localnet’ указывает список локальных IP адресов, согласно RFC1918, т.е. при общении с указанными подсетями Asterisk будет подставлять в сообщения SIP и SDP свой локальный IP адрес. Пример смотрите ниже.
localnet=192.168.0.0/255.255.0.0 - "серые" IP адреса согласно RFC 1918 localnet=10.0.0.0/255.0.0.0 - "серые" IP адреса согласно RFC 1918 localnet=172.16.0.0/24 - "серые" IP адреса согласно RFC 1918 localnet=169.254.0.0/255.255.0.0 - "серые" IP адреса согласно RFC 3927
Обработка RTP медиа потоков
Для того чтобы проксировать через Asterisk медиа трафик достаточно указать параметр directmedia=no, это поможет избежать проблем с прохождением трафика между конечными точками. Ниже представлены другие значения параметра directmedia.
directmedia=yes - разрешает пускать трафик между двумя оконечными точками, используется механизм re-INVITE directmedia=nonat - разрешает пускать трафик между двумя оконечными точками, если оконечное оборудование не за NAT directmedia=update - разрешает пускать трафик между двумя оконечными точками, используется механизм UPDATE directmedia=outgoing - разрешает отправлять только directmedia re-INVITE на исходящие вызовы directmedia=nonat,update - работает идентично параметру directmedia=yes directmediadeny=0.0.0.0/0 - указывает Access Control List доступа к directmedia directmediapermit=192.168.0.0/24 - разрешает использовать directmedia в указанной подсети (удобно для локальных сетей) directmediaacl=acl_example - использует указаный Access Control List из acl.conf
IP адрес в пакетах SDP может быть изменен параметром media_address. Данный параметр указывается в секции [general]..
media_address = 8.8.8.8
Для использования технологий ICE/STUN/TURN необходимо указать (как глобально, так и для конкретного пира) опцию icesupport, по умолчанию эта опция выключена.
icesupport=yes
Задать диапазон используемых RTP портов можно файле в rtp.conf:
rtpstart=10000rtpend=10300