[Из песочницы] Freeswitch: по пути наименьшего сопротивления

habr.png

Немного лирики


Сколько помню себя в кресле системного администратора (а общий стаж приближается уже годам к 15), столько вопросы офисной телефонии воспринимались мной строчкой из Californication калифорнийских же RHCP: hard core soft porn. Телефония всегда казалась параллельным измерением, в администрирование ее, настройку, я старался не лезть. Точнее, вообще обходить все эти телефоновопросы по широкой дуге, скидывая все подобные задачи на «специально обученных людей».

Однако, как часто бывает, сколько веревочке не виться, а конец один… После трудоустройства в новой организации я стал «счастливым» администратором прекрасной связки из цифро-аналоговой АТС Ericsson и «маршрутизатора с интегрированными сервисами» Cisco 2911. Более сотни аналоговых телефонов, три десятка цифровых Ericsson’ов и два-три десятка IP-телефонов Cisco и Ericsson. Все это великолепие некогда было настроено теми самими спецами по hard core soft porn, и как оно работает, я и по сей день представляю лишь в общих чертах. Однако, как бы то ни было, что такое extension, как организовывается условная и безусловная переадресация, как устроен IVR, что такое DID и прочее, узнать мне все же пришлось. И я не был в восторге от обретенных знаний (да-да, не все полезное интересно и приятно). Лишь циска, после усвоения мною логики ее настройки, стала более или менее приятной железякой.

В какой-то момент пришло смирение, что телефония все же неотъемлемая часть хозяйства системного администратора.

И грянул гром


Организация, в которой я работаю, переезжает в другое здание. Разумеется, все аналоговое и цифровое хозяйство остается по месту вечной прописки. Цисковский VoIP в приготовлении 2911 обеспечивает 50 линий, да и ценник на телефонные аппараты циско совершенно негуманный. И то ли благодаря уже пришедшему смирению, то ли благодаря врожденной тяге к знанию, то ли благодаря сочетанию этих двух факторов я решил, что на новом месте телефонию я подниму сам.

Требования были простые: дешево, а лучше бесплатно, а, в идеале, чтобы нам доплачивали, обеспечить базовый функционал (прямые городские номера у сотрудников, IVR, переадресация, конференции, перевод вызова), от 150 линий и выше. Первое слово, пришедшее в голову, было «SIP», второе «Asterisk», третье «Гугл».

Был скачан и развернут AsteriskNOW. Ошалело потыкался в веб-интерфейсе. Оценил в который раз hardcornsoftporn’овскую логику телефонистов и снова отправился гуглить. И случайно натолкнулся на слово «FreeSWITCH». Новое слово, новые поисковые запросы. Хвалебные оды устойчивости, легкости настройки (всюду XML), нетребовательности к ресурсам, плюс работа «из коробки», плюс «у людей» без нареканий работает в виртуальном окружении с сотнями и даже тысячами линий без искажений голоса (хотя разработчики и не рекомендуют виртуальное окружение в связи с отсутствием доступа к CPU в реальном режиме времени). Ок. Пробуем.
Поднимаем виртуальную машину под рекомендованным Debian 8×64, 1 ядро 2ГГц, 2 гига оперативки, 16 гиг диск. Выполняем установку в соответствии с инструкцией (тыц). Настраиваем софтфон (мне понравился 3CX’овский тыц).

Софтфон зарегистрировался. Тестовые звонки пошли. Ляпота. Ericsson Dialog 4422 тоже зарегистрировался, звонит, голос слышен в обе стороны. Ляпота. Аппарату Cisco 7945 была поставлена прививка прошивкой с поддержкой SIP, и, после относительно непродолжительных танцев с настройкой SCCP, аппарат так же зарегистрировался и звонки пошли без нареканий. Ляпота. FreeSWITCH в продакшн!

Хватит лирики


Исходные данные:

Оборудование коммутационной первого этажа:

  1. Коммутатор в собственности МТС, на котором нам выделена группа портов. С него мы забираем инет и будем забирать SIP-телефонию. Трафик тегирован vlan4
  2. Коммутатор наш, у него выделена группа портов, которым назначены vlan. В эти порты приходит инет от МТС (порт 2 — vlan2), инет от Miralogic (порт 3 — vlan3), SIP от МТС (порт 4 — vlan4). Так же выделен порт 1 под trunk, кабель уходит в серверную четвертого этажа.


Оборудование серверной на четвертом этаже:

  1. Коммутатор, принимающий trunk с первого этажа. Порт 1 — trunk входящий (с первого этажа. Порт 2 — trunk исходящий (к серверу).
  2. Сервер, на нем VMware vSphere 6. На этом хосте гостевая машина с Mikrotik RouterOS, выполняющая роль шлюза и файервола. Так же на этом хосте гостевая машина с FreeSWITCH. На хосте настроен vSwitch и добавлены порты с соответствующим тегированием трафика: vlan2, vlan3, vlan4.


Телефонию по E1 нам предоставляет МТС. От МТС же был предоставлен на тест SIP-транк.
Вот такие настройки были присланы мне инженерами МТС:

Добрый день!
Реквизиты SIP транка
Порт на коммутаторе 9
Номер 5555555
ip-адрес: 172.16.160.154
маска: 255.255.255.252
шлюз: 172.16.160.153
соединение без регистрации, точка - точка
sip-сервер: 172.16.253.3, port: 5060 UDP
media-сервер: 172.16.253.4, port: 10000 - 30000 UDP
кодеки: G711a/u
протокол передачи DTMF: rfc-2833


Машина с FreeSWITCH имеет один сетевой интерфейс, сетевые настройки:

IP: 172.18.253.1
Netmask: 255.255.0.0
GW: 172.18.1.254


Полетели, Mikrotik


Гасим гостевую машину с Mikrotik’ом и добавляем еще один сетевой интерфейс, назначаем ему vlan4. Включаем гостевую машину, Mikrotik загружается, видим, что появился еще один интерфейс.

Настраиваем.

Настройка интерфейса в Mikrotik
Выводим список имеющихся интерфейсов:

/interface ethernet print

Видим, что свежедобавленный интерфейс это интерфейс с именем ether6
Переименовываем его в if-sip:

/interface ethernet set [ find default-name=ether6 ] name=if-sip

Настраиваем адрес:
/ip address add address=172.16.160.154/30 comment=mts-sip interface=if-sip network=172.16.160.152


Настраиваем маршрутизацию в Mikrotik
Настраиваем mangle (чтобы трафик маркировался как мы захотим, и чтобы трафик ходил только через нужный там интерфейс на основе этих меток):

/ip firewall mangle add action=mark-routing chain=prerouting comment="mark sip traffic" new-routing-mark=sip src-address=172.18.253.1

Настраиваем маршрутизацию:

/ip route add comment=mts-sip distance=1 dst-address=172.16.0.0/16 gateway=172.16.160.153 routing-mark=sip


Настраиваем файервол и NAT в Mikrotik
Настраиваем отсутствие фильтрации файерволом (на этом этапе я не боюсь злых хакеров из SIP-транка с PAN-адресов МТС):
/ip firewall filter
add chain=forward comment="allow any to mts-sip" dst-address=172.16.0.0/16 in-interface=if-local out-interface=if-sip src-address=172.18.253.1
add chain=forward comment="allow any from mts-sip" dst-address=172.18.253.1 in-interface=if-sip out-interface=if-local src-address=172.16.0.0/16

Убедитесь, что эти два разрешающих правила расположены в самом верху списка правил. Это снизит нагрузку на файервол.

Для себя я решил, что мой SIP-шлюз будет находиться в локальной сети, чтобы:

  • Не иметь трахомудии с нежеланием отдельных телефонных аппаратов работать со шлюзом, находящимся за NAT.
  • Внутренний трафик в десятки раз превышает исходящий и входящий вместе взятые,
    ни к чему его гонять через Mikrotik.
  • И вообще, настроить один раз шлюз будет дальновидней, чем в дальнейшем воевать с множеством телефонных аппаратов (сотни) с разными прошивками, а то и разных производителей.

По этой причине настраиваем 1:1 NAT.
/ip firewall nat
add action=netmap chain=srcnat comment="source NAT for sip" src-address=172.18.253.1 to-addresses=172.16.160.154
add action=netmap chain=dstnat comment="destination NAT for sip" dst-address=172.16.160.154 to-addresses=172.18.253.1

Если отключали сервисные порты, включаем sip обратно:

/ip firewall service-port set sip ports=5060,5061,5080,5081 disabled=no


Пингуем шлюз (172.16.160.153), пингуем SIP-шлюз (172.16.253.3), пингуем Media-шлюз (172.16.253.4). Пинги ходят. Прекрасно.

На этом легкая и понятная часть закончилась.

Полетели, FreeSWITCH


Для «выхода в свет» нам потребуется сделать следующие вещи, названия которых чужды уху айтишника, не сталкивавшегося с телефонией:

  • Указать, какие IP-адреса и где использовать FreeSWITCH’у для установления соединений.
  • Указать код региона, выделенный оператором абонентский номер.
  • Создать extension — абонентский номер. Из коробки FreeSWITCH имеет преднастроенные 30 абонентских номеров. Мы создадим еще один.
  • Создать шлюз. Это не то, что вы подумали. Шлюз — это именованный набор настроек, необходимый для соединения с предоставленным SIP-транком. Мы же этого делать не будем,
    мы изменим настройки дефолтового шлюза
  • Настроить dialplan. В транслитерации ужасно звучащее слово. В правильном произношении звучащее еще хуже. Мне не нравится. В устоявшемся написании и произношении «диалплан». Означает набор сценариев. Из этого набора в зависимости от сработавшего условия FreeSWITCH выполняет то или иное действие. Диалпланы создаются для исходящих и входящих вызовов.
  • Настроить ACL для сетей и доменов, откуда разрешены звонки.


Disclaimer: предполагается, что FreeSWITCH установлен в папку по умолчанию: /etc/freeswitch


Самое первое, что делаем, меняем дефолтный пароль. Но опять не потому, почему вы подумали. Хотя и поэтому тоже. Пароль проверяется диалпланом, и если пароль совпадает с дефолтным, то перед соединением вставляется пауза 10 сек. Поэтому сначала меняем пароль.

Файл: /etc/freeswitch/vars.xml


Как вариант, если вам так уж нравится пароль »1234», то можете убрать паузу из диалплана, просто отредактировав соответствующий блок.

Файл: /etc/freeswitch/dialplan/default.xml


  
  
  


Настройки IP-адресов

Файл: /etc/freeswitch/sip_profiles/external.xml



Региональные настройки

Файл: /etc/freeswitch/vars.xml





Реквизиты от оператора

Файл: /etc/freeswitch/vars.xml







Ремарка самым внимательным
Вы, наверное, только что заметили, что значение параметра default_provider_register немного не вяжется с теми настройками, что выдал оператор (соединение без регистрации, точка — точка). Однако, в случае с МТС, регистрация все же понадобилась, без нее не проходили вызовы извне внутрь. При том, что без регистрации вполне можно было звонить изнутри наружу. Эта особенность выпила мне немало крови, прежде, чем я врубился и отловил ее.

Характерным признаком того, что требуется авторизация, является ошибка 407 Proxy Authentication Required.

Отлавливается эта ошибка включением SIP-трассировки:

sofia global siptrace on

Выключается трассировка, соответственно:

sofia global siptrace off


Добавляем абонентский номер (extension)

Создаем xml-файл с любым именем в папке /etc/freeswitch/directory/default. Я создал файл с именем, совпадающим с номером.

Файл: /etc/freeswitch/directory/default/4545.xml


 
   
    
    
   
   
    
    
    
    
    
    
    
    
   
 


Создаем шлюз
Скорее всего, после того, как вы выполнили настройки IP-адресов и заполнили поля в vars.xml реквизитами, выданными оператором, регистрация на шлюзе оператора состоится без проблем.

У меня же «без проблем» не получилось, поскольку МТС реквизиты выслал, а абонентский номер (extension) 3435555555 не завел. Прежде, чем я заподозрил оператора в подставе, я успел перебрать миллион вариантов настройки шлюза. Однако в итоге оператор у себя на SIP-шлюзе абонентский номер создал, и все завелось если и не с дефолтными настройками, то с близкими. Привожу листинг файла mts.xml, который был получен путем переименования файла external.xml.

Файл: /etc/freeswitch/directory/default/mts.xml



  
   
    
    
    
    
    
    
    
    
    
   
  
 
  
 
 


Теперь добавляем разрешения на домен и на сети, чтобы наш FreeSWITCH не блокировал попытки установить соединения из домена и из сетей оператора. И да, на данном этапе я так же просто разрешаю все. Моя задача — позвонить уже наконец за пределы организации.

Файл: /etc/freeswitch/autoload_configs/acl.conf.xml


 
 


 
 
 
 


Обратите внимание! Это не файервол. Фильтрации трафика не происходит. Это списки доступа к сервисам FreeSWITCH’а.


Поздравляю! Можно посмотреть, что у нас неполучилось.
Запускаем консоль FreeSWITCH’а:

fs_cli -rRS

Перезагружаем xml’ки:
reloadxml или жмакаем F6
Перезагружаем модуль Sofia, отвечающий за телефонные соединения:
reload mod_sofia
Смотрим, что у нас с соединениями со шлюзами.

freeswitch@phone> sofia status
Name Type Data State
=================================================================================================
external profile sip:mod_sofia@172.16.160.154:5080 RUNNING (0)
external::172.16.253.3 gateway sip:3435555555@172.16.253.3 REGED
172.18.253.1 alias internal ALIASED
internal profile sip:mod_sofia@172.18.253.1:5060 RUNNING (0)
=================================================================================================
2 profiles 1 alias


Славно. Регистрация на шлюзе оператора прошла успешно.
Смотрим подробности:

sofia status gateway 172.16.253.3

freeswitch@phone> sofia status gateway 172.16.253.3
==============================================================
Name 172.16.253.3
Profile external
Scheme Digest
Realm 172.16.253.3
Username 3432788299
Password yes
From
Contact
Exten 73435555555
To sip:3435555555@172.16.253.3
Proxy sip:172.16.253.3
Context public
Expires 600
Freq 600
Ping 0
PingFreq 0
PingTime 0.00
PingState 0/0/0
State REGED
Status UP
Uptime 3932s
CallsIN 1
CallsOUT 1
FailedCallsIN 0
FailedCallsOUT 0
==============================================================


Дело встало за малым.

Диалпланы

Для звонков наружу создаем файл mts.xml с нуля, все остальные файлы в папке /etc/freeswitch/dialplan/default можно переименовать со сменой расширения/перенести в другое место/грохнуть.

Файл: /etc/freeswitch/dialplan/default/mts.xml


 
 
  
  
  
 


 
 
  
  
  
 


 
 
  
  
  
 


Для звонков снаружи внутрь создаем файл mts_inbound.xml в папке /etc/freeswitch/dialplan/public. Остальное в этой папке по аналогии выше можно переименовать в *.bck или в *.noload

Файл: /etc/freeswitch/dialplan/public/mts_inbound.xml


 
  
   
    
   
  


Ну что. Скрестили пальцы, проверяем.

Снова запускаем консоль FreeSWITCH’а:
fs_cli -rRS
Перезагружаем xml’ки:
reloadxml или жмакаем F6
Перезагружаем модуль dialplan, отвечающий за телефонные соединения:
reload mod_dialplan_xml
Пробуем дозвон изнутри наружу. Пробуем дозвон снаружи внутрь. Радостно повторяем тестовое «раз-раз, два-два», убеждаемся, что звук ходит в обе стороны. Проверяем прохождение сигналов отбоя в обе стороны.

Радуемся, что приобщились к soft porn.

P.S.: Я сознательно избегал расшифровки значения тех или иных правок. Отчасти, потому что имена параметров и системных переменных очень уж хорошо говорят за себя. Отчасти, чтобы не превращать турбо-запуск телефонии в нудятину с оправданиями каждого пука.

P.S.: Написание сего текста было продиктовано ужасом от того, что я так и не смог найти внятный мануал слитным текстом, где решалась бы такая же задача: максимально просто, максимально быстро поднять телефонию с авторизацией точка-точка. Обилие документации почему-то не сопровождается обилием обсуждений и живых примеров. Или просто так получилось, что я допетрил до всего быстрее, чем нагуглил «тот самый пример», который бы сработал у меня. Так или иначе, пусть это будет шпаргалкой для меня и коллег на будущее.

© Habrahabr.ru