Виртуальная АТС. Часть 3: Переводим Asterisk на PjSIP без лишних телодвижений

от автора

В первой и второй частях цикла статей мы разобрались с установкой IP-АТС (IP-PBX) на работающий под управлением Ubuntu VPS от RuVDS и настройкой основных функций с использованием канального драйвера chan_sip. Этот подход считается устаревшим, и в будущих версиях Asterisk поддержка chan_sip будет прекращена. Вместо него лучше использовать открытую мультимедийную библиотеку PjSIP. Несмотря на кардинальные различия в файлах конфигурации, переход не так сложен, как может показаться на первый взгляд.

Что такое PjSIP?

Важно понимать, что PjSIP — не какой-то новый протокол, а целая библиотека для работы со стеком обеспечивающих голосовую связь протоколов: SIP, RTP, SDP, STUN и т.д. Она представляет собой целую кучу модулей, что нашло отражение в конфигурационном файле pjsip.conf (он заменяет традиционный sip.conf). Файл разделен на секции, а работает с ним преимущественно модуль res_pjsip, при этом каждая секция определяет конфигурацию некоторого объекта. Имена секций традиционно заключаются в квадратные скобки, а в секции обязательно присутствует определяющая ее тип конструкция «type =».

Типы секций могут быть следующими:

ENDPOINT — аналог пира в sip.conf, который определяет опции протокола SIP и взаимодействие с AOR, AUTH и TRANSPORT. Обязательно связана хотя бы с одной секцией AOR;
AOR — здесь описано, как связаться с ENDPOINT;
TRANSPORT — в этой секции описываются настройки протоколов транспортного уровня, веб-сокеты и методы шифрования (наподобие general в sip.conf). Может быть одной для разных ENDPOINT или уникальной для некоторой точки;
REGISTRATION — отвечает за исходящие регистрации, например, транки к провайдерам;
AUTH — содержит опции и полномочия для входящих и исходящих регистраций. С ней ассоциируются ENDPOINT и REGISTRATIONS;
IDENTIFY — здесь можно задать IP источника для ENDPOINT;
ACL — используется res_pjsip для контроля входящих соединений, не привязан к ENDPOINT;
DOMAIN_ALIAS — псевдонимы домена;
CONTACT — нужна, чтобы явно не указывать SIP URI в Dialplan;
System — системные опции;
Global — глобальные опции;

Имена секций в большинстве случаев могут быть произвольными, но, к примеру, ENDPOINT и AOR должны именоваться идентично с заголовком SIP URI.

Нашу справку трудно назвать исчерпывающей, поскольку за кадром осталось много интересных фишек, вроде PjSIP Configuration Wizard: пока речь идет о миграции на новую библиотеку малой кровью. С нюансами и тонкостями можно разобраться позднее.

Конвертируем sip.conf в pjsip.conf

Из-за модульности структура конфигурационного файла pjsip.conf размазана тонким слоем по множеству секций — она гораздо сложнее, чем у старого-доброго sip.conf. Разработчики Asterisk подумали о простых админах и создали сценарий для конвертации. Написан он на Python, и если вы собираете ПО из исходников, уже есть в дистрибутиве: в каталоге contrib/scripts/sip_to_pjsip/. Мы ставили Asterisk из входящего в репозиторий Ubuntu бинарного пакета, поэтому скрипты пришлось скачать с GitHub.

Хотя формат конфигурационных файлов для разных версий IP-PBX особо не менялся, лучше выбрать скрипты из установленной у вас версии Asterisk вместо последней по умолчанию — в нашем случае 16.2.

Версию Asterisk можно посмотреть в консоли IP-PBX с помощью команды core show version

Вам понадобятся все файлы на Python из каталога contrib/scripts/sip_to_pjsip/ в репозитории на GitHub. Их нужно сложить в локальный каталог, перейти в каталог с конфигами Asterisk (обычно /etc/asterisk) и запустить скрипт sip_to_pjsip.py с привилегиями суперпользователя. Основная его задача, прочитать входной файл sip.conf и сделать новый pjsip.conf (подробности доступны в wiki Asterisk).

Сценарий сделает pjsip.conf, а дальше вас ждет его ручная полировка. Если вы устанавливали Asterisk по нашим статьям, придется еще настроить загрузку модулей в /etc/asterisk/modules.conf и изменить в Dialplan (/etc/asterisk/extensions.conf) вызов приложения Dial.

Сделанный конвертером файл /etc/asterisk/pjsip.conf на практике оказался нерабочим:

pjsip.conf

;-- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Non mapped elements start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  [general] allowoverlap = no  [office] call-limit = 2  [sipnet] remotesecret = пароль  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Non mapped elements end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --;   [transport-udp] type = transport protocol = udp bind = 0.0.0.0  [sipnet] type = aor contact = sip:логин@sipnet.ru  [sipnet] type = identify endpoint = sipnet match = sipnet.ru  [sipnet] type = endpoint context = sipnet-trunk dtmf_mode = rfc4733 disallow = all allow = alaw,ulaw direct_media = no from_user = логин from_domain = sipnet.ru aors = sipnet  [1001] type = aor max_contacts = 1  [1001] type = auth username = 1001 password = пароль  [1001] type = endpoint context = homeoffice dtmf_mode = rfc4733 disallow = all allow = ulaw allow = alaw allow = g729 allow = g723 allow = g726 allow = h261 allow = h263 allow = h264 allow = h263p callerid = Директор <1001> auth = 1001 outbound_auth = 1001 aors = 1001  [acl] type = acl permit = XXX.XXX.XXX.XXX deny = 0.0.0.0/0.0.0.0  [1002] type = aor max_contacts = 1  [1002] type = auth username = 1002 password = пароль  [1002] type = endpoint context = homeoffice dtmf_mode = rfc4733 disallow = all allow = ulaw allow = alaw allow = g729 allow = g723 allow = g726 allow = h261 allow = h263 allow = h264 allow = h263p callerid = Секретарь <1002> auth = 1002 outbound_auth = 1002 aors = 1002 

Синтаксис его понятен, подробности можно найти в wiki Asterisk. Чтобы довести конфигурационный файл до ума, потребуется ручная правка.

Исправленный /etc/asterisk/pjsip.conf (как и в sip.conf, в нем можно использовать шаблоны):

Исправленный /etc/asterisk/pjsip.conf

;===============TRANSPORT  [transport-udp] type = transport protocol = udp bind = 0.0.0.0  ;===============ACL  [acl] type = acl deny = 0.0.0.0/0.0.0.0 permit = XXX.XXX.XXX.XXX  ;===============SIPNET TRUNK  [sipnet] type = registration transport = transport-udp outbound_auth = sipnet server_uri = sip:sipnet.ru client_uri = sip:логин@sipnet.ru retry_interval = 60  [sipnet] type = auth auth_type = userpass password = пароль username = логин  [sipnet] type = aor contact = sip:логин@sipnet.ru  [sipnet] type = endpoint transport = transport-udp ; Контекст должен быть прописан в Dialplan context = sipnet-trunk dtmf_mode = rfc4733 disallow = all allow = alaw,ulaw direct_media = no from_user = логин from_domain = sipnet.ru outbound_auth=sipnet aors = sipnet   [sipnet] type = identify endpoint = sipnet match = sipnet.ru  ;===============USER TEMPLATES   [endpoint-template](!) type = endpoint transport = transport-udp context = homeoffice dtmf_mode = rfc4733 disallow = all allow = ulaw allow = alaw allow = g729 allow = g723 allow = g726 allow = h261 allow = h263 allow = h264 allow = h263p   [auth-template-userpass](!) type = auth auth_type = userpass   [aor-template-single-reg](!) type = aor ; PjSIP допускает и множественные регистрации с одного аккаунта max_contacts = 1  ;===============User 1001  [1001](endpoint-template) auth = auth1001 aors = 1001 callerid = Директор <1001>  [auth1001](auth-template-userpass) username = 1001 password = пароль   [1001](aor-template-single-reg)  ;===============User 1002  [1002](endpoint-template) auth = auth1002 aors= 1002 callerid = Секретарь <1002>  [auth1002](auth-template-userpass) username = 1002 password = пароль   [1002](aor-template-single-reg) 

С шаблонами писанины стало меньше, но есть и более интересный способ упростить админу жизнь — Configuration Wizard. Пожалуй, это одна из самых удобных фишек PjSIP, с которой мы разберемся в следующей статье.

Переписываем Dialplan

Самая простая часть: достаточно заменить SIP на PJSIP в вызове приложения Dial. Пока мы немного изменили простейший тестовый Dialplan из предыдущей статьи, более сложными вещами займемся позднее.

Конфигурационный файл /etc/asterisk/extensions.conf

[general] static=yes writeprotect=no priorityjumping=no autofallthrough=yes clearglobalvars=no  ; Контекст по умолчанию принято закрывать ради удобства и безопасности [default] exten => _X.,1,NoOp() same => n,Busy() same => n,HangUp()  ; Определяем контекст homeoffice [homeoffice] ; разрешаем внутренние звонки exten => _1XXX,1,Dial(PJSIP/${EXTEN}) ; звонки по России производим через SIPNET exten => _.7XXXXXXXXXX,1,Dial(PJSIP/${EXTEN:1}@sipnet)  ; Определяем контекст sipnet-trunk, разрешаем входящие звонки через SIPNET [sipnet-trunk] ; входящие звонки рассмотрим в следующей статье 

Переход с chan_sip на PjSIP оказался делом не особенно сложным, но требующим изрядной доли ручной работы. Автоматически конвертировать конфигурацию у нас не получилось: сценарий выдал неработоспособный вариант, который пришлось переписать вручную. В следующей статье мы разберем работу с Configuration Wizard и наконец расширим dialplan для приема входящих вызовов, организации конференций и решения других задач маршрутизации звонков.

ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/527578/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *