[Из песочницы] Freeswitch: по пути наименьшего сопротивления
Немного лирики
Сколько помню себя в кресле системного администратора (а общий стаж приближается уже годам к 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 в продакшн!
Хватит лирики
Исходные данные:
Оборудование коммутационной первого этажа:
- Коммутатор в собственности МТС, на котором нам выделена группа портов. С него мы забираем инет и будем забирать SIP-телефонию. Трафик тегирован vlan4
- Коммутатор наш, у него выделена группа портов, которым назначены vlan. В эти порты приходит инет от МТС (порт 2 — vlan2), инет от Miralogic (порт 3 — vlan3), SIP от МТС (порт 4 — vlan4). Так же выделен порт 1 под trunk, кабель уходит в серверную четвертого этажа.
Оборудование серверной на четвертом этаже:
- Коммутатор, принимающий trunk с первого этажа. Порт 1 — trunk входящий (с первого этажа. Порт 2 — trunk исходящий (к серверу).
- Сервер, на нем 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 загружается, видим, что появился еще один интерфейс.
Настраиваем.
/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
/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
/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
Характерным признаком того, что требуется авторизация, является ошибка 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.: Написание сего текста было продиктовано ужасом от того, что я так и не смог найти внятный мануал слитным текстом, где решалась бы такая же задача: максимально просто, максимально быстро поднять телефонию с авторизацией точка-точка. Обилие документации почему-то не сопровождается обилием обсуждений и живых примеров. Или просто так получилось, что я допетрил до всего быстрее, чем нагуглил «тот самый пример», который бы сработал у меня. Так или иначе, пусть это будет шпаргалкой для меня и коллег на будущее.