NAT, SIP и Asterisk

Трансляция сетевых адресов (NAT) является обычной практикой в сети и нередко мешает прохождению голосовых пакетов (нет звука) и инициализации соединений (нет соединения). Решение этой проблемы требует понимания принципов работы NAT и VoIP. В этой статье рассматривается протокол SIP и Asterisk, но проблемы и решения применимы и к большинству других приложений и протоколов.

NAT используется, чтобы скрыть многочисленные локальные адреса, за каким-то внешним узлом, обеспечивая безопасность и структуризацию сети.
Когда пакет проходит шлюз (gateway), IP-адрес локального источника заменяется на внешний IP-адрес. При ответе шлюз направляет пакет на исходный локальный адрес. Также шлюз блокирует внешние запросы не имеющие явных внутренних источников, но возможно пробросить пакеты пришедшие на определенные порты, на заранее заданные IP адреса внутри сети.

Если у вас нет звука, нет звука в одну сторону, нет слышимости, прочтите внимательно эту инструкцию.

Первый абонент запрашивает соединение у второго , сообщая свой IP адрес. Второй отвечает, сообщая свой IP. Голосовые пакеты направляются напрямую абонентам, минуя SIP сервер. Передача голосовых пакетов напрямую абонентам, минуя Asterisk, называется RE-INVITE или Native Bridge.

NAT может вызвать проблемы в нескольких местах.

  • Если одна из АТС находится за NAT, другая АТС не сможет связаться с ней, без проброса портов.
  • Если телефон находится за NAT, голосовые пакеты могут быть направлены на немаршрутизируемый адрес в сети, что приведет к потере звука.

В простейшей ситуации SIP клиент находясь за NAT, обращается к внешнему интерфейсу Asterisk. SIP клиент при регистрации на сервере создает запись в таблице трансляций, которая сохраняется, пока проходит хотя бы один пакет в минуту. В файле sip.conf требуется определить параметры сети и свойства удаленного пира.


[general]
localnet=192.168.0.0/255.255.255.0 ; локальная сеть
externip=x.x.x.x                   ; внешний ip адрес

[sip_phone]             
nat=yes
qualify=300                    ; проверять соединение каждые 300 мс.

Начиная с версии Asterisk 11: 'nat=yes' устарело, используйте 'nat=force_rport,comedia'
nat=force_rport,comedia

nat=force_rport,comedia
directmedia=nonat

При такой конфигурации Asterisk использует внешний IP адрес externip для вызовов клиентов с параметром nat=yes . Дополнительно параметр qualify=yes поддерживает соединение, не позволяя удалять запись из таблицы трансляций.

Все усложняется если и Asterisk, и клиенты, находятся за NAT. Клиенты с внешней стороны не смогут получать SIP сообщения и принимать звонки. Или в SIP сообщении будет указан локальный IP адрес телефона, что приведет к потере звука.

Чтобы избежать потери звука запретите re-invite в файле sip.conf

[general]
canreinvite => no

Опция canreinvite устарела. Используйте 'directmedia'.

  • directmedia=yes
  • directmedia=nonat
  • directmedia=update
  • directmedia=outgoing

Но клиенты находящиеся за NAT, все равно не смогут инициировать соединение с Asterisk и направить голосовые пакеты RTP на требуемый екстеншен. Для того чтобы это работало, надо пробросить требуемые порты через брандмауер на Asterisk. Диапазон RTP портов используемых Asterisk, назначается в файле rtp.conf.

[general]
rtpstart=10000 
rtpend=10100                  

По умолчанию задан диапазон от 10000 до 20000. Измените диапазон в соответсвии с вашими потребностями (3 порта на каждый конкурирующий вызов).

Для нормальной работы за NAT, потребуется пробросить диапазон RTP портов в соответсвии с настройками в файле rtp.conf и порт SIP(обычно 5060). В iptables это будет выглядеть так:

iptables -t nat -A PREROUTING -i eth0 -p udp \
-m udp --dport 10000:10100 -j DNAT \
--to-destination 192.168.1.10
iptables -t nat -A PREROUTING -i eth0 -p udp \
-m udp --dport 5060 -j DNAT \
--to-destination 192.168.1.10

Где eth0 - внешний интерфейс, а 192.168.1.10 - IP адрес Asterisk.

sip.conf

Поддержка NAT в Asterisk 12

localnet

параметр 'localnet' список сетевых адресов, которые считаются «внутренними».

 localnet=192.168.0.0/255.255.0.0 - RFC 1918 адреса
 localnet=10.0.0.0/255.0.0.0      - Также RFC1918
 localnet=172.16.0.0/12           - Другое RFC1918 с CIDR обозначением
 localnet=169.254.0.0/255.255.0.0 - Zeroconf локальная сеть
externaddr

Внешний адрес щлюза (маршрутизатора) во внешнюю сеть. «externaddr = hostname[:port]» указывает статический адрес[:port] который будет использован в SIP и SDP сообщениях. Имя хоста (hostname) поднимается каждый раз, когда [пере]загружается sip.conf. Если порт не назначен, используется значение указанное в параметре «udpbindaddr». примеры:

 externaddr = 123.34.56.78:         - использовать этот адрес.
 externaddr = 123.34.56.78:9900     - использовать этот адрес и порт.
 externtcpport = 9900    - отображаемый наружу tcp порт
 externtlsport = 12600   - отображаемый наружу tcp порт;  'externtlsport' по рекомендации RFC назначенный порт 5061.	
externhost

«externhost = hostname[:port]» то же что и «externaddr» только это 'hostname' обновляемое через «externrefresh» секунд (по умолчанию 10сек.).

 externhost=foo.dyndns.net       - обновлять периодически
 externrefresh=180               - задать интервал обновления

В дополнение к вышесказанному Asterisk имеет дополнительный параметр «NAT» для разрешения вопросов, связанных со входящими SIP или медиа сессиями. В частности, в зависимости от настроек 'NAT =' как описано ниже, Asterisk может переопределить адрес / порт информацию, указанную в SIP / SDP сообщениях.

 nat = no                - без NAT RFC3581
 nat = force_rport       - использовать rport, даже если его нет 
 nat = comedia           - отправить медиа поток на порт ASterisk, независимо от указаний SDP.
 nat = auto_force_rport  - установить 'force_rport' параметр если  Asterisk обнаружил NAT (по умолчанию)
 nat = auto_comedia      - установить  'comedia' параметр если Asterisk обнаружил NAT

настройки могут совмещаться:

nat=force_rport,comedia

RFC 3581 определяет что 'rport' позволяет клиенту запросить, чтобы Asterisk отправлял SIP ответы на него через исходный IP и порт, с которого был направлен запрос, вместо адреса / порта из самого верхнего Via заголовка.

Установка force_rport принуждает Asterisk всегда передавать ответы обратно на адрес / порт, с которых он получил запросы, даже если другая сторона не поддерживает добавления параметра 'rport'.

media_address

IP адрес используемый для медиа (аудио, видео и текста) в SDP может быть переназначен параметром 'media_address'. Данный параметр может быть использован только в секции [general].

 media_address = 172.16.42.1
icesupport

ICE/STUN/TURN использование может быть включено глобально или для конкретного пира с помощью 'icesupport' опции.

 icesupport = yes
directmedia

Для отключения прямых RTP потоков (peer-to-peer) используйте опцию:

 directmedia=nonat

устаревшие настройки sip.conf

port= Порт используемый SIP протоколом для сигнализации (default=5060)

bindaddr= IP адрес Asterisk, если указано 0.0.0.0, то любой адрес.

externip= Этот параметр задается в секции [general] файла sip.conf и указывает внешний IP адрес, или имя хоста на вашем устройстве NAT.

externip=123.123.123.123

Этот адрес будет использован для общения с устройствами с установленным параметром nat=force_rport.

localnet= Этот параметр задается в секции [general] файла sip.conf и указывает на локальную сеть и используется для обращения к устройствам с параметром nat=no.

localnet=192.168.0.0/255.255.255.0
NAT

Возможные значения:

NAT= yes, no, never, route

NAT=route

Начиная с версии Asterisk 11: nat=yes is deprecated, use nat=force_rport,comedia instead

  • nat = no - без NAT RFC3581
  • nat = force_rport - использовать rport, даже если его нет
  • nat = comedia - отправить медиа поток на порт Asterisk, независимо от указаний SDP.
  • nat = auto_force_rport - установить 'force_rport' параметр если Asterisk обнаружил NAT (по умолчанию)
  • nat = auto_comedia - установить 'comedia' параметр если Asterisk обнаружил NAT

Asterisk будет отправлять голосовые пакеты на порт и IP адрес с которого их получает а не указанные в SIP и SDP сообщениях.

Это будет работать только, если телефоны за NAT будут использовать для одинаковый порт для голосовых пакетов RTP и одинаковый (но отличный от голосового) для сигнализации RTCP.

directmedia
  • directmedia=yes
  • directmedia=nonat
  • directmedia=update
  • directmedia=outgoing

qualify= Эта опция имеет два назначения.Первое - поддерживать запись в таблице трансляций NAT и контролировать регистрацию телефона.

Возможные значения:

qualify=yes 

Этот параметр задает проверку по умолчанию каждые 2 секунды.

qualify=no

Это выключает проверку.

qualify=300

Включает проверку через заданное время в 300 ms.

rtp.conf

 rtpstart=10000

Задает первый порт диапазона для приема и оправки голосовых пакетов RTP.

 rtpend=10100

Задает последний порт диапазона для приема и оправки голосовых пакетов RTP.

 stunaddr=sip.stun.tld

В Asterisk начиная с версии 11 появилась поддержка stun. icesupport должно быть включено.



Настройка res_pjsip для работы через NAT

В данной статье приведены примеры рабочей конфигурации драйвера канала PjSIP, когда Asterisk находится за NAT (Network Address Translation). Asterisk подключается через NAT к провайдеру IP телефонии (ITCP).
Этот пример подходит для большинства простых сценариев NAT при следующих условиях: Asterisk и телефоны находятся в частной сети. Маршрутизатор имеет локальный и публичный интерфейсы. Маршрутизатор реализует функции Трансляции Сетевых Адресов (NAT) и файерволла. На маршрутизаторе настроен проброс SIP и RTP портов на локальный IP адрес сервера Asterisk. В данном примере проброшены порты 5060 TCP/UDP и UDP 10000-10100 на LAN 10.10.2.10.

Устройства используемые в примере:

УстройствоIP адрес в примере
VOIP телефон(7777)10.10.2.77
PC/Asterisk10.10.2.10
МаршрутизаторLAN: 10.10.2.1
WAN: 123.123.123.123
ITSP SIP шлюз203.0.113.1(gw1.example.com)
203.0.113.2(gw2.example.com)

Для наглядности, в примере использованы фальшивые детали:

ITSP номер аккаунта : 123456789 и DID номер входящий от провайдера IP телефонии (ITSP): 3216111

pjsip.conf конфигурация

Подразумевается, что вы ознакомились со статьей о конфигурации Asterisk pjsip.conf и имеете основные представления о работе Asterisk. Для этого примера, важно отметить опции - local_net, external_media_address и external_signaling_address в transport секции и direct_media в endpoint секции. Остальные параметры могут зависеть от конкретной конфигурации, модели телефона, сетевых настроек, специфики провайдера IP телефонии и т.д.

local_net

Диапазон адресов локальной сети.

external_media_address

Внешний IP адрес используемый для обработки RTP трафика. Когда запрос или ответ на запрос отправляется из Asterisk и IP адрес назначение находится за пределами сетей указанных в параметре 'local_net', а медиа адрес в SDP сообщении из локальной сети, тогда медиа адрес из SDP сообщения перезаписывается значением назначенным в параметре 'external_media_address'.

external_signaling_address

Это тоже самое что и 'external_media_address', только для SIP сигнализации, вместо RTP медиа трафика. Этим двум опциям внешних адресов, должен быть назначен один и тот же IP адрес, если вы, конечно, не хотите разделить сигнальный и медиа трафик и направить на разные IP адреса или сервера.

direct_media

Управляет медиа потоком, направляя RTP трафик непосредственно между конечными точками, или через Asterisk. (вспомните canreinvite из sip.conf) Вместе, использование этих опций, обеспечивает правильное прохождение SIP и RTP пакетами сетевых узлов, а 'direct_media=no' указывает, что именно Asterisk должен обрабатывать медиа трафик. Это важно, т.к. наша система Asterisk имеет локальный IP адрес и провайдер IP телефонии (ITCP) не может маршрутизировать трафик напрямую к нему, поэтому мыдолжны убедится что SIP и RTP трафик возвращается на WAN публичный интернет адрес нашего роутера. В секциях имена которых начинаются с «sip_provider_*», настраиваются входящие и исходящие подключения SIP транка, а в секциях [7777] VoIP телефон.

[transport-udp-nat]
type=transport
protocol=udp
bind=0.0.0.0
local_net=10.10.2.0/24
local_net=127.0.0.1/32
external_media_address=123.123.123.123
external_signaling_address=123.123.123.123

[sip_provider_reg]
type=registration
transport=transport-udp-nat
outbound_auth=sip_provider_auth
server_uri=sip:gw1.example.com
client_uri=sip:123456789@gw1.example.com
contact_user=3216111
retry_interval=60

[sip_provider_auth]
type=auth
auth_type=userpass
password=************
username=123456789
realm=gw1.example.com

[sip_provider_endpoint]
type=endpoint
transport=transport-udp-nat
section=from-trunk
disallow=all
allow=ulaw
outbound_auth=sip_provider_auth
aors=sip_provider_aor
direct_media=no
from_domain=gw1.example.com

[sip_provider_aor]
type=aor
contact=sip:gw1.example.com
contact=sip:gw2.example.com

[sip_provider_identify]
type=identify
endpoint=sip_provider_endpoint
match=203.0.113.1
match=203.0.113.2
[7777]
type=endpoint
section=from-internal
disallow=all
allow=ulaw
transport=transport-udp-nat
auth=7777
aors=7777
direct_media=no
 
[7777]
type=auth
auth_type=userpass
password=*********
username=7777

[7777]
type=aor
max_contacts=2

Удаленные телефоны за NAT

Выше приведенный пример подразумевает, что телефон находится в локальной сети, так же как и сервер Asterisk.
Но может так статься, что Asterisk расположен на внешнем IP адресе, а удаленные телефоны находятся за NAT, или же и Asterisk, и телефоны расположены за NAT, т.е. имеет место двойной NAT? В этих случаях пригодятся следующие настройки оконечных точек (ENDPOINTS)

media_address

IP адрес используемый SDP для обработки медиа трафика.

В момент создания SDP сообщения, IP адрес назначенный здесь(media_address=1.2.3.4), используется как медиа адрес для потока SDP. At the time of SDP creation, the IP address defined here will be used as the media address for individual streams in the SDP. Помните также , что опция 'external_media_address', заданная в секции transport , установит окончательный адрес для возврата медиа трафика.

rtp_symmetric

Обязательный симметричный RTP. Отправлять RTP назад на тот же адрес/порт с которого он был получен.

force_rport

Поведение обязательно совместимое с RFC 3581, т.е., если rport не указан, отправлять SIP ответы на тот же порт с которого были получены запросы.

direct_media

Управляет медиа потоком, направляя RTP трафик, непосредственно, между конечными точками, или через Asterisk.

Поддержка ICE,STUN,TURN

Interactive Connectivity Establishment (ICE) в Asterisk

Настройка Asterisk

2016/11/26

FreePBX за NAT

  • artikle/nat.txt
  • Последние изменения: 2018/09/24