OpenSource :: замена телефонного сервера.

Posted: 2023-11-14 in IT, Software
Метки:,

Несколько лет назад я писал, какие лютые страдания может вызывать удолбанный на всю голову коммерческий продукт «еврогейского уровня качества», написанный под стек древних говно-технологий а-ля виндовс-2003 / IIS-web-server / адобе-Flash.
Хорошая новость там была всего одна — несмотря на торчащую на весь инет винду-2003 с кучей открытых портов, крупного взлома к счастью не случилось, да и железо смогло дожить до недавно свершившегося таки апгрейда. Кому интересно, как это было сделано — велкам в избу-читальню под кат.

Предистория.

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

Как я уже писал, наиболее опасным моментом является привязка лицензии софта к железу. То есть любой отказ оборудования — сдохшая материнка / проц / дисковый контроллер — и даже имея бэкап, вернуть систему к жизни без помощи вендора не получится. Эта же привязка делала невозможной виртуализацию.

Существует ещё вариант взломать программу, но тут есть два важных ньюанса:
— Сложно найти того гения реверсинга, который согласится копаться в таком говне даже за деньги
— всё остальное говно а-ля винда/IIS и самое поганое — окончательно окоченевший адобе-флеш никуда не девались.

Кроме того, после случившихся не очень-то и гуманных событий вендор-локнутый софт от европейского производителя перестал считаться доверенным от слова совсем (к чему сами эти производители тоже приложили усилия). Что касается поддержки, то и в гораздо более спокойные времена разработчики/саппорт войпсвитча оказывали даже оплаченные услуги только после долгих переписок и ругани в чате (это единственный на моей памяти случай, когда в корпоративной переписке встречался матерный рунглиш).

Так что морально к смене плафтормы все были готовы, вопрос был только в том — куда, в какие сроки и с какими издержками.
Пообщавшись с разными коллегами по цеху, было принято решение искать +/- готовое открытое решение, которое можно поставить самому и которое будет более доступно для кастомизации, если такая потребность возникнет. Чек-листы на предмет неадекватной ангажированности тоже проверялись.

Magnus Billing 7

В итоге выбор остановили на открытой системе Magnus Billing 7. У них есть аккаунт на гитхабе, внятная открытая документация в собственной вики и даже канал на ютубе и в телеграме. Это разительно отличается от платной тикетницы в мёртворождённой флеш-морде и вечно недоступной польской техподдержки продукта с пятизначным евроценником.

В самых общих чертах план миграции VoipSwitch —> Magnus Billing 7 был такой:
1) Поднимаем тестовую ВМ с системой.
2) заводим тестовых юзеров / тарифы / транки, подключаем как клиента в существующую сеть
3) готовим сценарии для one-shot переноса, всё тестим
4) Поднимается с нуля ещё один инстанс системы под продакшен,
конфигурируется всё, кроме данных клиентов — тарифы, транки, админ-пароли, кофниг файервола, бэкапник.
5) в назначенный час делается миграция пользовательских данных, старому серверу гасится порт на свитче, новой под-виртуалке даётся старый IP сервера.

Идея — подменить боевой сервер на том же IP-адресе / домене с минимально возможным простоем. Если что — остается возможность отката в две секунды — гасим ВМ, включаем порт старого сервера.

Краткий обзор системы со скриншотами интерфейса есть вот тут:

Обзор VoIP-системы MagnusBilling

я же больше акцентирую внимание на интересных мне моментах администрирования такой системы.

Установка и план миграции данных
Разработчики рекомендуют в качестве ОС использовать либо центось-7, либо дебиан-11.
Второй вариант мне гораздо больше нравится в силу более свежих версий, и я ставил именно на дебиан. Скажу разу — обновляться до 12-го дебиан напрямую нельзя, это уложит систему, тогда как в рамках 11-го дебиана системные обновления ставятся как обычно.

Какое же это счастье — иметь нормальный тестовый экземпляр системы и не вспоминать более про кошмары тестов на продакшене !

Также было интересно, как оно будет жить внутри Unprivileged LXC на Proxmox. Как оказалось — никаких проблем вообще, внутри unpriv-LXC система замечательно живёт, так что никаких полновесных KVM-виртуалок и связанных с этим накладных расходов.

Файловые системы я сделал вот такого размера:
root@magnus:~# df -h -t ext4
Filesystem Size Used Avail Use% Mounted on
/dev/loop2 3.9G 3.4G 305M 92% /
/dev/loop3 3.9G 446M 3.3G 12% /var/lib/mysql
/dev/loop4 7.8G 1.4M 7.4G 1% /var/spool/asterisk/monitor
/dev/loop5 7.8G 2.0G 5.5G 27% /Backups

В нашем случае LXC-контейнера на проксмоксе их можно очень легко расширить, ничего не останавливая. Установку самой системы я расписывать не буду — она есть в обзоре.

Создаём контейнер LXC из шаблона debian-11, апдейтим, ставим туда iptables / openssh-server / mc / htop / screen / tcpdump / ещё- какие удобства и далее ставим скриптом.

В подготовительном этапе надо сразу настроить пароли админов, транки и конфиг файервола.
ОЧЕНЬ важно не забыть создать в файерволе правила не только для порта 5060, но и для остального UDP-траффика (обязательно открыть диапазон портов 10000:20000). Без этого вы получите ситуацию, когда вызов проходит, но в трубке тишина — сигнализация есть, а медиа-потоки файерволом отрезало.

Пароли админов веб-системы — максимально крепкие, ssh оставить с доверенных сетей и только по ключам.

Поскольку мы запускались не с нуля, а переносили данные с уже существующей старой системы, то бы выбран путь создания генератора нового дампа. Суть в чём — пишется скрипт, который лезет в БД старой системы и генерит сразу SQL-дамп для БД новой системы, с учётом её структуры, переназначения имён полей и прочего.

Всякие готовые десктопные софтины а-ля «Super-puper-database-migrator» из прошлого века — сразу лесом, они никогда не смогут дать такой гибкости, какую даёт полноценный язык программирования на момент генерации дампа. Да и смысла привязываться к такому треш-софту никакого нет. Мы переносили не все настройки, а только самые массовые — тип аккаунта, логины/пароли/контакты пользователей, Caller-ID, DID-ов, привязки DID-номеров к аккаунтам, историю платежей и балансы. Настройки виртуальных PBX, голосовые приветствия, таймауты IVR — всё это переносилось вручную, функции эти в старой системе были реализованы неудобно/криво и ими мало кто пользовался, там не было смысла возиться с генерацией дампа.

Что касается тарифов, то тут ситуация такая — тарифы эти меняются, а в интерфейсе магнуса нет системы для массовой правки цен. То есть один-два-десять префиксов поправить можно, но когда аплинк присылает простыню на 40к+ префиксов с изменившимися ценами — то тут нужно себе облегчить жизнь. Почему столько префиксов на менее 200 стран — читать тут и тут.

Для переноса тарифов использовался такой подход — на сервере магнус-биллинга заводится каталог для своих кастомных скриптов, и туда распаковывается вот это:

https://github.com/Aminuxer/Voipswitch-Additions/tree/master/MagnusBilling7

Я добавил в код проверку логина в админской сессии, но лучше дополнительно подстраховаться и ограничить доступ в этот каталог с помощью .htaccess, оставив только адреса админских машин.

Сперва нам нужно открыть скрипт ../_get_data_from_voipswitch_for_magnusbilling.php
В его шапке должны быть прописаны адрес/логин/пароль старого MySQL-сервера VoipSwitch:

$_vs_addr = 'old-sip.voipswitch.com'; // VoipSwitch database server
$_vs_db = 'voipswitch_database_name';
$_vs_username = 'voipswitch_database_username';
$_vs_password = 'voipswitch_database_password';

На всякий случай добавим ещё один IP-фильтр, уже в коде самого скрипта. Поскольку дамп будет выгружать пароли открытым текстом (без этого в случае протокола SIP увы не обойтись), то надо быть максимально аккуратным, и после миграции все такие дампы с рабочего компа удалить. Утечка их может быть очень болезненной. Я советую сохранять такие дампы только в /tmp (рамдиски при отключенном швопе) или на шифрованные ФС.
Правим список доступа под свою сеть:
$ip_access_subnet = ‘127.0.0.1 192.168.0.0/22’; // Add your IP/subnets — access only whitelist (EXPORT PASSWORDS !!)

Заранее создаём группы для обычных пользователй и PBX (виртуальные АТС). В старом воип-свитче это были сильно разные сущности, причём виртульные АТС прикручивали туда явно с жестокостью и насилием. В магнусе же все пользователи по сути PBX, и тут настройка идёт сокрее от отключения лишних / неоплаченных функций у обычных аккаунтов. iD этих групп стоит заранее посомтреть и вписать в конфиг.

$new_id_group_retails = 3; // id_group in Magnus for voipsw retail-clients; Create before import;
$new_id_group_virtpbx = 4; // id_group in Magnus for voipsw pbx-clients; Create before import;

По умолчанию все наши логины будут считаться созданными рутом. Если у вас своя иерархия аккаунтов — кнопка [Fork] на гитхабе вам в помощь.

$new_id_user_owner = 1; // id_user in users (all new accounts owner/creator). id = 1 for root in magnusbilling.

В старом биллинге DID-номера хранились без кода города/страны, и потом это как-то разруливалось в кривейшем диалплане. Номеров исходно довольно мало, все они в одном городском префиксе.
Поэтому у меня есть ещё одна опция — что дописывать перед внешними номерами при импорте. Например, для Новосибирска будет такое значение:
$new_did_prefix = '7383'; // If voipswitch has local-numbers without country-city code, add this for convert DIDs to E.164

После чего открываем скрипт, он генерит дамп, заливаем его в базу магнуса и делаем рестарт, чтобы астериск всё подцепил.

Что касается тарифов, то тут сперва надо выгрузить тарифы для каждого аплинка из старой системы в CSV-файлы с полями вида
префикс;название;цена или название;префикс;цена. Возможно, вам потребуется отрезать лишние значения в выгрузке с помощью офисного пакета или утилит cut / sed / awk / grep.

Затем CSV-файл тарифа аплинка отправляется через формочку вот этому скрипту:
/prepare_prefixes_tariffs.php

Скрипт опять же в рабочей БД ничего не меняет — а лишь генерит дампы, которые можно проверить и уже залить в базу.
Я вижу такой подход более контролируемым и предсказуемым.

Кроме того, я на этом этапе наконец-то переименовал все префиксы с транслита на нормальный цивильный русский (старая хрень не умела в названия префиксов с не-английским иименами), есть вспомогательный скрипт /rename_prefixes.php.

Цены для клиентов аналогично — только скрипт уже /prepare_client_tariffs.php

На этом этапе наш сервер уже в целом готов к включению — все основные вещи должны работать.

В код системы я внёс только одну правку — защиту от звонков в убыток (это когда цена клиента ниже цены аплинка).
Патч и код фикса вот в этом патче:

https://github.com/magnussolution/magnusbilling7/pull/616/commits/ba41301fddad6cd6aedde321b9715fa6101d4f20

Когда у тебя логика открытым кодом на скриптовом языке — вносить патчи легко и приятно.

На этом месте ожидаются едкие шуточки унылых говноскептиков про биллинг-на-пхп, красноглазие и «несурьёзность». Ну давайте посмеемся вместе — сколько будет стоить реализация подобной штуки в коммерческом ПО даже без учёта санкционного пиздеца ?

Ах да — в отличие от всратой говноподелки за пятизначную сумму в евро, опенсурсный магнус-биллинг-на-пхп не падает, не рвёт вызовы при просмотре логов и легко переносится на другую ноду стандартной миграцией LXC-контейнера.

Что касается обновлений — сейчас там rolling-release, обновления ставятся запуском скрипта
/var/www/html/mbilling/protected/commands/update.sh
Поскольку у нас свой фикс есть, то сперва на тестовом, потом проверяем, применимы ли наши правки. Если всё ок- обновляемся и на боевом.

Впрочем, совсем всё гладко быть не может, и про минусы и плюсы рассказать тоже надо.

Минусы.

— Самый косячный косяк — это перевод. Ведущий разработчик из Бразилии, и русскоязычный перевод они делали явно промтом. Отсюда местами очень ржачные названия некоторых пунктов меню, впрочем, касаются они в основном админской области. В клиентской части всё более-менее нормально.

Я прислал разработчику свои предложения более корректного перевода:
https://github.com/magnussolution/magnusbilling7/pull/616/commits/a0005a76795cecdcaa1986a4cfbb73e957c1ad95

Рекомендую заценить сложности преодоления языкового барьера.

— некоторые вещи, типа переадресации входящих звонков, делаются не совсем очевидным способом.

— Asterisk древний — 13-й. Соответственно, основная потеря — мультилогин. Если несколько устройств с одним логином — то исходящие будут у всех работать согласно лимиту, а вот входящий придёт кому-то одному наугад. Тут только ждать новых версий. Впрочем, это повод перевести хитропопых клиентов на PBX-аккаунты с разными суб-логинами.

Плюсы.

+ Работа в LXC-Unprivileged контейнере. ЖИРНЮЩЩИЙ плюс к простоте обслуживания / бэкапа / рестора / управлению ресурсами / безопасности. Думаю, запуск в докер-контейнере тоже очень даже возможен.
+ Вполне актуальная системная часть — обновляемый Debian 11, php 7.4, MariaDB 15.1, ядро 6.2-ветки
+ Есть девелоперский/тестовый стенд, где можно сперва спокойно проверить новую версию, проверить свои патчи и работу всех функций и только потом выкатить изменения в прод.
+ Asterisk и php-скрипты в логике. Позволили внести нам ключевую функцию безопасности. Респектищще.
Для более нагруженных систем разработчик предлагает уже платный модуль, написанный на Си, который держит большие нагрузки.
+ Консоль астериска доступна как обычно по asterisk — r
Для более удобного мониторинга есть платный модуль SipTrace.
+ пароли на личный кабинет и SIP-аккаунты теперь могут быть разные. В старой системе пароль был общий.
+ пароли админов хэшированы.
+ Личный кабинет использует HTML-5 / JS интерфейс. Никакого УГ типа AdobeFlash/ActiveX/SilverLight.
Работает во всех современных браузерах.
+ Для нашего удобства пришлось написать десяток скриптов. Впрочем, лежат они на том же сервере, используют тот же php.
+ Понятная структура базы данных. Очень облегчила миграцию и написание скриптов.
+ В системе работает уже настроенный fail-2-ban, который эффективно гасит брутфорсеров на заданное время.
+ Записи разговоров корректно разделены по клиентам, файл gsm проигрывается в VLC.
Настраивается как доп-услуга, собирать запись из кусков ручками не требуется =)

Если эта заметка вам понравилась — пишите в комменты, спрашивайте, подскажу по возможности.

По итогу миграция завершилась более чем успешно.
Старый сервер убран на архивное хранение. Им можно пугать новых сотрудников. =)
Это была последняя винда в значимой серверной инфраструктуре компании.
С этой миграцией эпоха виндовс на боевых продакшен-серверах в отдельно взятой компании завершилась окончательно.

- комментарии
  1. Говношутка про биллинг-на-пхп, красноглазие и «несурьёзность» ///
    // EDITED.
    Личные оскорбления не приветствуются. Флуд не по теме в технических заметках тем более.

  2. […] fedrrrrrr к записи OpenSource :: замена телефонно… […]

Оставьте комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.