Как это обычно бывает, ты тратишь время на поиск истины в RFC, зарывшись в дампах трафика и исходников протокола, а кто-то за тебя это уже сделал. Ну что же, будет мне уроком. Все тоже самое, что тут, но на видео и с дополнительными картинками - https://www.youtube.com/watch?v=Anu6ZYg25yM
--------------------------------------------------------------------------------------------------------------------------
Пришло время расставить точки над И, и пояснить почему sip helper - это хорошо, и надо знать, когда его нужно отключать, а когда нет. А так же разобрать причины, по которым на MikroTik зависают сессии регистрации, в некоторых случаях падения канала связи.
Прежде всего давайте разберем основы SIP протокола и установки связи на примере Asterisk.
SIP - это транспортный протокол для SDP, и вот уже SDP определяет куда надо отвечать второму абоненту.
Давайте посмотрим на схему ниже:
На Asterisk NAT выключен, SIP Helper на микротике выключен. На микротике включен SRC-NAT masquerade, и DST-NAT TCP 5060, UDP 10000-20000 в сторону телефона.
SIP телефон успешно зарегистрировался на сервере, микротик создал трансляции ната, и держит соединения в connection tracking.
С номера 100 (192.168.1.100) совершают звонок на номер 200.
В SIP пакете, в поле Via будет стоять адрес 192.168.1.100 и порт 5060, а вот в IP - UDP/TCP заголовках благодаря SRC-NAT у нас будет стоять внешний IP адрес - 1.1.1.1, и порт к примеру 5066
Согласно спецификации SIP протокола, он должен послать ответ на адрес и порт, указанные в поле Via. Получается, что телефон с номером 200 пошлет ответ на 192.168.1.100 5060, и естественно звонок не состоится.
Варианты решения данной проблемы:
1. Включаем на телефоне с номером 100 rport (RFC 3581), теперь в поле Via будет стоять метка rport, это сообщает серверу, что следует отвечать на порт из UDP/TCP заголовков, а не на значение порта поля Via. Если на телефоне включить rport нельзя, то следует на сервере Asterisk установить значение nat=force_rport. Хорошо с портом разобрались, а как быть с адресом, он ведь по прежнему будет его брать из поля Via. Для этого на Asterisk включается nat=comedia, или nat=force_rport,comedia (если на телефоне rport включить нельзя) таким образом сервер будет брать адрес из заголовков UDP/TCP. Ну и разумеется нам надо настроить DST-NAT на микротике на порты 5060 для SIP и 10000-20000 для голоса.
2. Включаем SIP Helper на микротике. Теперь когда телефон с номером 100 решит позвонить на 200, sip helper изменит ip и порт в поле Via на значения из IP - UDP/TCP заголовков. Так же он изменит значения полей SDP протокола, а именно owner, connection information на значения из IP - UDP/TCP заголовков. И по необходимости порт для принятия медиа потока, если таковой занят в таблице nat трансляций. И все! Не надо DST-NAT, не надо трогать настройки nat в Asterisk.
Важный момент: SIP Helper работает только с SIP на порту 5060, он разумеется не сможет работать с SIP TLS, так как шифруется на оконечных устройствах. И он НИКАК не влияет на RTP!
SIP Helper + SIP Direct Media
Данная настройка позволит гонять напрямую медиа поток в следующей схеме:
При такой схеме и работающем SIP Helper мы получаем картину, при которой наш микротик получит пакеты, где адрес назначения будет одинаковый. Если включен SIP Direct Media - то он даст возможность телефонам напрямую общаться. Если выключен, то подобные пакеты будут просто дропаться.
Рассмотрим теперь проблему зависающих сессий.
Рассмотрим схему ниже:
Теперь у нас есть туннель между нашими роутерами. Классическая схема основной офис - филиал.
Телефон 200 регистрируется на сервере 192.168.1.10
Никакого NAT, SIP-HELPER.
И тут падает интернет канал.. Первым делом естественно падает туннель. И если оно проваляется минут 5, то TCP сессия оборвется по таймауту. Телефон начнет слать пакеты на регистрацию, и они улетают по маршруту по умолчанию, который смотрит в с интерфейс провайдера. Создается запись в connection-tracking. И как только туннель поднимается обратно у вас ничего не работает, потому что соединение уже есть. Да нерабочее, но есть.
И тут несколько вариантов решения:
1. (Плохой вариант) Чистим все соединения с портом 5060 при падении туннеля.
2. (Хороший вариант) Делаем blackhole маршрут до 192.168.1.0/24 с метрикой больше, чем у оригинального маршрута до 192.168.1.0/24. Таким образом, если туннель упадет, blackhole маршрут станет приоритетным для данной подсети, соединение не поднимется, так как роутер будет дропать пакеты по этому маршруту до того, как для них создастся запись NAT трансляции в connection tracking!
--------------------------------------------------------------------------------------------------------------------------
Пришло время расставить точки над И, и пояснить почему sip helper - это хорошо, и надо знать, когда его нужно отключать, а когда нет. А так же разобрать причины, по которым на MikroTik зависают сессии регистрации, в некоторых случаях падения канала связи.
Прежде всего давайте разберем основы SIP протокола и установки связи на примере Asterisk.
SIP - это транспортный протокол для SDP, и вот уже SDP определяет куда надо отвечать второму абоненту.
Давайте посмотрим на схему ниже:
На Asterisk NAT выключен, SIP Helper на микротике выключен. На микротике включен SRC-NAT masquerade, и DST-NAT TCP 5060, UDP 10000-20000 в сторону телефона.
SIP телефон успешно зарегистрировался на сервере, микротик создал трансляции ната, и держит соединения в connection tracking.
С номера 100 (192.168.1.100) совершают звонок на номер 200.
В SIP пакете, в поле Via будет стоять адрес 192.168.1.100 и порт 5060, а вот в IP - UDP/TCP заголовках благодаря SRC-NAT у нас будет стоять внешний IP адрес - 1.1.1.1, и порт к примеру 5066
Согласно спецификации SIP протокола, он должен послать ответ на адрес и порт, указанные в поле Via. Получается, что телефон с номером 200 пошлет ответ на 192.168.1.100 5060, и естественно звонок не состоится.
Варианты решения данной проблемы:
1. Включаем на телефоне с номером 100 rport (RFC 3581), теперь в поле Via будет стоять метка rport, это сообщает серверу, что следует отвечать на порт из UDP/TCP заголовков, а не на значение порта поля Via. Если на телефоне включить rport нельзя, то следует на сервере Asterisk установить значение nat=force_rport. Хорошо с портом разобрались, а как быть с адресом, он ведь по прежнему будет его брать из поля Via. Для этого на Asterisk включается nat=comedia, или nat=force_rport,comedia (если на телефоне rport включить нельзя) таким образом сервер будет брать адрес из заголовков UDP/TCP. Ну и разумеется нам надо настроить DST-NAT на микротике на порты 5060 для SIP и 10000-20000 для голоса.
2. Включаем SIP Helper на микротике. Теперь когда телефон с номером 100 решит позвонить на 200, sip helper изменит ip и порт в поле Via на значения из IP - UDP/TCP заголовков. Так же он изменит значения полей SDP протокола, а именно owner, connection information на значения из IP - UDP/TCP заголовков. И по необходимости порт для принятия медиа потока, если таковой занят в таблице nat трансляций. И все! Не надо DST-NAT, не надо трогать настройки nat в Asterisk.
Важный момент: SIP Helper работает только с SIP на порту 5060, он разумеется не сможет работать с SIP TLS, так как шифруется на оконечных устройствах. И он НИКАК не влияет на RTP!
SIP Helper + SIP Direct Media
Данная настройка позволит гонять напрямую медиа поток в следующей схеме:
При такой схеме и работающем SIP Helper мы получаем картину, при которой наш микротик получит пакеты, где адрес назначения будет одинаковый. Если включен SIP Direct Media - то он даст возможность телефонам напрямую общаться. Если выключен, то подобные пакеты будут просто дропаться.
Рассмотрим теперь проблему зависающих сессий.
Рассмотрим схему ниже:
Теперь у нас есть туннель между нашими роутерами. Классическая схема основной офис - филиал.
Телефон 200 регистрируется на сервере 192.168.1.10
Никакого NAT, SIP-HELPER.
И тут падает интернет канал.. Первым делом естественно падает туннель. И если оно проваляется минут 5, то TCP сессия оборвется по таймауту. Телефон начнет слать пакеты на регистрацию, и они улетают по маршруту по умолчанию, который смотрит в с интерфейс провайдера. Создается запись в connection-tracking. И как только туннель поднимается обратно у вас ничего не работает, потому что соединение уже есть. Да нерабочее, но есть.
И тут несколько вариантов решения:
1. (Плохой вариант) Чистим все соединения с портом 5060 при падении туннеля.
2. (Хороший вариант) Делаем blackhole маршрут до 192.168.1.0/24 с метрикой больше, чем у оригинального маршрута до 192.168.1.0/24. Таким образом, если туннель упадет, blackhole маршрут станет приоритетным для данной подсети, соединение не поднимется, так как роутер будет дропать пакеты по этому маршруту до того, как для них создастся запись NAT трансляции в connection tracking!