При настройке 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