МАСТЕРКОМ

IT-СИСТЕМЫ ПРОСТО И ДЛЯ ВСЕХ

Asterisk 19.8.1 + FreePBX 16.0.40 on Ubuntu Core 22.04

Статья на тему установки и настройки Asterisk с FreePBX на Ubuntu Core

Это будет ОЧЕНЬ длинная статья, где развёрнуто объясним, как ставить, и чем Вам это грозит. И сразу уточним, что ВСЁ делам из под root!

Установка Ubuntu Core 22.04

Тут всё просто, качаете образ с "родного" сайта, "заливаете" куда хотите и погнали. "Моменты" возникнуть могут с настройкой UEFI на Вашем материнской плате, но это решаемо, путём перебора вариантов в меню.

Первый затык возникнет на моменте установки ИП адреса! Рекомендуем НАСТОЯТЕЛЬНО установить его вручную из меню, поскольку синтаксис сильно изменился, и существующие мануалы далеки от правды. Для этого посмотрим на файл /etc/netplan/00-installer-config.yaml созданный в меню.

network:
  ethernets:
    enp2s0:
      addresses:
      - 192.168.0.151/24
      nameservers:
        addresses:
        - 192.168.0.1
        search:
        - 192.168.0.1
      routes:
      - to: default
        via: 192.168.0.1
  version: 2

Вторым затыком будет отсутствие подключения к Интернет. Без доступа к сети, даже в режиме Core, дистрибутив не встанет! Зачем он коннектиться к серверам - не понятно, но факт есть.

Настройка сервера Ubuntu Core 22.04

Мы подошли к самому интересному. Сначала настроим основные компоненты, а потом будем возвращаться к ним и донастраивать. Увы и ах, иначе можно запутаться.

Обновляем систему

apt update
apt upgrade

Теперь добавляем "старые" репозитории.

apt install software-properties-common apt-transport-https
add-apt-repository ppa:ondrej/php
apt update

Ставим нужные пакеты

apt install mc nano cron curl wget iptables iptables-persistent tar chrony htop sftp iptraf iputils-ping

Настраиваем синхронизацию времени, это ОЧЕНЬ важно! Как не странно.

timedatectl set-timezone Europe/Moscow
systemctl enable chrony --now

Установили, ещё раз, временную зону и запустили службу синхронизации времени.

Добавим русскую локализацию нашим пакетам.

apt install wget tar language-pack-ru

Настраиваем файервол, часть 1

Мы делаем первоначальный конфиг, потом будем обезопасивать себя нормально.

iptables -D INPUT -p tcp --dport 5060 -j ACCEPT
iptables -D INPUT -p tcp --dport 5061 -j ACCEPT
iptables -D INPUT -p udp --dport 5060 -j ACCEPT
iptables -D INPUT -p udp --dport 5061 -j ACCEPT
iptables -I INPUT -p udp --dport 4569 -j ACCEPT
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
iptables -I INPUT -p udp --dport 10000:12000 -j ACCEPT

Хорошо, поясняем. SIP порт сигнализации 5060 должен быть в UDP и TCP, TLS 5061, то же. А вот IAX2 4569 бегает только в UDP, как и "голос" в RTP, в диапазоне от 10000 до 12000. Причём порт 5068 - ТОЛЬКО для внутренних номеров, и это дибилизм мелкомегких, от которого они отказались. Ну а залезать с RTP до 20000 - это вообще БРЕД, которого и в мануалах то нет. Серьёзно?! 10000 одновременно "говорящих" номеров на 1 ИП адрес?

В нашем варианте АТС будет "сидеть" на NAT, т.е. у нас есть пограничный маршрутизатор! Там ОБЯЗАТЕЛЬНО настраиваете НЕ РЕДИРЕКТ порта во внутрь, а именно ПРОБРОС порта через NAT, иначе работать толком не будет. Даже если в настройках АТС прямо указать работать без NAT.

Для сохранения записей в iptables мы используем установленную ранее утилиту.

netfilter-persistent save

Создаём нашего пользователя

Вообще-то без разницы как называть пользователя и его группу. Но мы все понимаем, что потом файлов перекофугурировать придётся - мама дорогая! А мы ленивые...

useradd asterisk -m

Настраиваем сервер баз данных

apt install mariadb-server
systemctl enable mariadb --now

Задаем пароль для суперпользователя СУБД.

mysqladmin -u root password your_pass

А дальше начинается геморой. Поскольку в дальнейшем CDR и подключение к базе работать не будут. Поскольку нам нужен ODBC driver, на самом сайте mariadb есть подробное описание установки, для разных версий.

Открываем браузер и заходим на страницу загрузки коннекторов MariaDB и выбираем новый актуальный ODBC connector для нашей операционной системы. И копируем появившуюся ниже ссылку.

mkdir odbc_package
cd odbc_package
wget https://dlm.mariadb.com/3286256/Connectors/odbc/connector-odbc-3.1.19/mariadb-connector-odbc-3.1.19-ubuntu-jammy-amd64.tar.gz
tar -xvzf mariadb-connector-odbc-*.tar.gz
install lib/mariadb/libmaodbc.so /usr/lib/
install -d /usr/lib/mariadb/
install -d /usr/lib/mariadb/plugin/
install lib/mariadb/plugin/caching_sha2_password.so /usr/lib/mariadb/plugin/
install lib/mariadb/plugin/client_ed25519.so /usr/lib/mariadb/plugin/
install lib/mariadb/plugin/dialog.so /usr/lib/mariadb/plugin/
install lib/mariadb/plugin/mysql_clear_password.so /usr/lib/mariadb/plugin/
install lib/mariadb/plugin/sha256_password.so /usr/lib/mariadb/plugin/

Теперь нам нужен сам диспетчер драйверов.

apt install unixodbc odbcinst

И указать ему в двух файлах, что использовать для подключения к нашей базе.

nano /etc/odbcinst.ini
[MariaDB]
Description     = ODBC for MariaDB
Driver          = /usr/lib/libmaodbc.so
#Driver64        = /usr/lib64/libmaodbc.so
FileUsage       = 1
nano /etc/odbc.ini
[MySQL-asteriskcdrdb]
Description=MySQL connection to 'asteriskcdrdb' database
driver=MariaDB
server=localhost
database=asteriskcdrdb
USER=root
PASSWORD=your_pass
Port=3306
#Socket=/var/lib/mysql/mysql.sock
#option=3
#Charset=utf8

Тут, по сути, ничего менять не надо, поскольку используются шаблоны. Ну пароль и логин от базы, Вы свои подставите надеемся?

Настройка сервера NGINX

Парам-пам-пам! "Текучку" почти сделали.

apt install nginx
apt install php7.4 php7.4-{mysqlnd,cli,common,imap,ldap,fpm,curl,mbstring,zip,gd,gettext,xml,json,snmp,bcmath}

Эм, теперь понятно почему мы подключали другие репозитории? Да, FreePBX использует 7.4 и никак иначе, поэтому мучаемся снова.

nano /etc/nginx/sites-enabled/default

Такс, тут можно просто копировать один к одному. Удалите старый, либо заархивируйте и вставьте текущее.

# Default server configuration
#
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        index index.php;

        root /var/www/html;

        #server_name _;

        location / {
                try_files $uri $uri/ =404;
        }

    # disallows the things that the FreePBX .htaccess files disallow
    location ~ (/\.ht|/\.git|\.ini$|/libraries|/helpers|/i18n|/node|/views/.+php$) {
        deny all;
    }

    # from the api module .htaccess file
    rewrite ^/admin/api/([^/]*)/([^/]*)/?(.*)?$ /admin/api/api.php?module=$1&command=$2&route=$3 last;

        location ~ \.php$ {
            fastcgi_pass unix:/run/php/php7.4-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            fastcgi_param SERVER_NAME $host;
            fastcgi_param HTACCESS on;
        }

}

Тут мы просто даём NGINX доступ к файлам бэкапа, музыки и пр. И прикрываем некоторые дыры.

nano /etc/nginx/nginx.conf

И дописываем.

client_max_body_size 512M;

Теперь настроем сам PHP. Ищите строчки по заголовкам раздалов и меняйте.

;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;
...
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 512M
...
;;;;;;;;;;;;;;;;;
; Data Handling ;
;;;;;;;;;;;;;;;;;
...
; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 512M
...
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
...
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 512M
...
;;;;;;;;;;;;;;;;;;;
; Module Settings ;
;;;;;;;;;;;;;;;;;;;
...
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Europe/Moscow"

И ещё тут, указываем нашего пользователя, от которого будет работать FreePBX.

nano /etc/php/7.4/fpm/pool.d/www.conf
user = asterisk
group = asterisk

Активируем.

systemctl enable nginx
systemctl enable php7.4-fpm

Проверяем конфиг NGINX (ну мало ли). И рестартим сервер.

nginx -t
nginx -s reload

Ставим NodeJS

curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -

Укажим "родной" репозиторий.

apt install nodejs

Установка Asterisk

Фу-у, кто дочитал до сюда - герой. Дальше будет хуже

Открываем браузер и заходим на страницу загрузки. Не, так не работает, FreePBX не имеет поддержку версии старше 19.

wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-19-current.tar.gz
tar -xvf asterisk-*.tar.gz
cd asterisk-*/
./contrib/scripts/install_prereq install

Устанавливаем зависимости для астериска. А если система (иногда бывает, причина непонятна) запросит телефонный код страны, вводим 7 (для России). НЕ ЦИФРА 8!!!!!!!!!!!!!!!! Забудьте наконец этот атавизм!

#############################################
## install completed successfully
#############################################

Ага, всё хорошо. Идём дальше.

make distclean

Чутка приберёмся.

./contrib/scripts/get_mp3_source.sh

Добавим библиотеку для работы с mp3.

./contrib/scripts/get_mp3_source.sh

Конфигурируем.

./configure

А теперь самое неописываемое. Тут главное не прокосячить. Запускаем ракету! Т.е. меню для выбора параметров.

make menuselect

Охо-хо-хо. Тут не зевай.

В разделе "Add-ons" выбираем: chan_mobile, chan_ooh323, format_mp3

В разделе "Applications" выбираем: app_macro

Мм, тут есть "момент", что этот модуль уже не поддерживается, НО в Sangoma это по одному месту. Поэтому, если не хотите получить не работающие внутренние звонки - то и не устанавливайте. А вообще, лучше установите ВСЕ модули.

В разделе "Call Detail Recording" выбираем: cdr_odbc, cdr_adaptive_odbc

В разделе "Channel Drivers" выбираем: chan_sip

В разделе "Channel Event Logging" выбираем: cel_odbc

В разделе "Resource Modules" выбираем: res_odbc, res_odbc_transaction

В разделе "Core Sound Packages" ВСЁ где стоит RU

В разделе "Music On Hold" OPSOUND

В разделе "Extra Sound Packages" ВСЁ где стоит только EN

make

Мы должны увидеть сообщение об успешной сборке. И выполним, что нас просят.

make install

Устанавливаем скрипты для автозапуска АТС и готовые конфигурационные файлы.

make config
make samples

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

nano /etc/asterisk/asterisk.conf
runuser = asterisk
rungroup = asterisk
...
defaultlanguage = ru
documentation_language = ru_RU

Незабываем давать "права" этому пользователю на управление файлами станции.

usermod -aG audio,dialout asterisk
chown -R asterisk:asterisk /var/run/asterisk
chown -R asterisk.asterisk /etc/asterisk
chown -R asterisk.asterisk /var/{lib,log,spool}/asterisk
chown -R asterisk.asterisk /usr/lib/asterisk

Ещё один "момент". В файле с настройкой модулей /etc/asterisk/modules.conf можно включить chan_sip, раскоментировав строку load = chan_sip.so. НО! После этого Ваш pjsip_sip отвалится, поскольку два драйвера не могут жить на одном порту! Для этого, в глобальных настройках FreePBX, есть разделённая настройка портов для chan_sip и pjsip_sip. Если Вам уж ОЧЕНЬ надо и то и другое, то мучайтесь. В этом нет смысла, посколку chan_sip в следующих релизах будет удалён вообще.

nano /etc/asterisk/manager.conf
;include manager_additional.conf
;include manager_custom.conf

Просто расскоментируем строки, для внешнего доступа к файлам настройки.

asterisk -c 

Проверяем настройки. Должно быть зелёная надпись "Asterisk Ready.", на все остальные ошибки не смотрите, их у Вас ещё будет вагон и маленькая тележка. Правяться некоторые просто "заглушками".

sed -i 's";[radius]"[radius]"g' /etc/asterisk/cdr.conf
sed -i 's";radiuscfg => /usr/local/etc/radiusclient-ng/radiusclient.conf"radiuscfg => /etc/radcli/radiusclient.conf"g' /etc/asterisk/cdr.conf
sed -i 's";radiuscfg => /usr/local/etc/radiusclient-ng/radiusclient.conf"radiuscfg => /etc/radcli/radiusclient.conf"g' /etc/asterisk/cel.conf

Ладно, запускаем нашу станцию и "вешаем" в автозагрузку.

systemctl enable asterisk
systemctl start asterisk

Если, что-то, где-то, у нас порой... То, рестартим и смотрим статус.

systemctl restart asterisk
systemctl status asterisk

Установка кодеков Asterisk G729 и G723

Хе-хе-хе, а кто сказал, что у Вас всё работает как надо? В частности кодеки G729 и G723, хоть и есть в системе, и тот же FreePBX позволяет их выбрать - они не работают. В логах будет что-то вроде "channel.c: Unable to find a codec translation path: (slin) -> (g729)" Будем чинить.

Открываем браузер и заходим на страницу загрузки. Сверху нажимаем "Binaries", справа будет надпись "Linux binaries" и название версий Астериска. Нажимаем на "Asterisk 18", выпадет меню выбора версии. Не будем заморачиваться и выберем версию под "gcc4-glibc-x86_64-core2".

cd /usr/lib/asterisk/modules
wget http://asterisk.hosting.lv/bin/codec_g729-ast180-gcc4-glibc-x86_64-core2.so
mv codec_g729-ast180-gcc4-glibc-x86_64-core2.so codec_g729.so
chmod 755 codec_g729.so
chown asterisk:asterisk codec_g729.so
/etc/init.d/asterisk restart
asterisk -rx "core show codecs"
asterisk -rx "core show translation"

С кодеком G723, аналогично.

Установка FreePBX

Устали? А мы ТОЛЬКО на середине пути.

Поставим консольную утилиту для преобразования аудиофайлов из одного формата в другой. Вообще советуется поискать что-то получше, но мы ленивые.

apt install sox mpg123

Качаем этот убогий FreePBX (поплачем по Avaya, NEC, Panasonic). Вообще-то, есть MicroPBX, там интерфейс максимально приближен к старому доброму от Yealink. "Пилят" его русские, на базе немецкого, кое-го скупил 3CX, но там нет перспектив, ибо архитектура закрыта. Есть ещё AskoziaPBX, но это тот же "Pay-to-Win", как FreePBX от Sangoma.

wget http://mirror.freepbx.org/modules/packages/freepbx/freepbx-16.0-latest.tgz
tar zxf freepbx-*.tgz
cd freepbx
./start_asterisk start

Тут мы должны увидеть надпись, что всё хорошо. Тогда продолжаем установку.

STARTING ASTERISK
Asterisk is already running
./install -n --dbuser root --dbpass your_pass --webroot=/var/www/html

Ну, мы понимаем, что устанавливать надо с подключением к нашей базе данных. В конце должна быть зелёная надпись.

You have successfully installed FreePBX

Ещё одни важный пункт - модуль управления сертификатами.

fwconsole ma downloadinstall certman
fwconsole ma updateall
fwconsole reload --verbose

Открываем браузер и заходим по адресу сервера — должна открываться страница конфигурирования FreePBX. Задаем первоначальные настройки. Желательно ВСЁ максимально поотключать.

Конфигурирование FreePBX

Ну теперь попрёт жара...

Неявные настройки, которые лучше сделать сразу.

Для начала, отключим следилку: "Общие настройки" -> "Дополнительные настройки" -> "Browser Stats". Ибо нефиг "палить контору".

Добавим модули в нашу систему: "Админ" -> "Updates" -> "Module Updates". Выбираем "Standart" и "Extended", после чего нажимаем "Проверить онлайн". Тут будут 2 варианта: "Скачать всё" и "Обновить всё". Со скачкой есть "момент" - отключите из выбора те модули которыми ТОЧНО не будете пользоваться (навроде DAHDi), а так же коммерческие модули. Так же, есть модули которые зависят от других. В частности, нужный нам по зарез "Asterisk REST Interface Users". После нажатия "Запустить процесс" может вылезти, что модуль зависим, тогда ставьте что можете и повторите процедуру он-лайн поиска модулей и их установку снова.

Добавим лог-файл, для автобана всяких гадов: "Общие настройки" -> "Настройки логфайлов Астериска" -> "Файлы журнала" -> "+ New Log". Назовём его "fail2ban" и активируем: Ошибка, Замечание, Предупреждение, Безопасность. В принципе можете поиграться в значениях, но система не совсем тупая.

Добавим директорию для ручного бэкапа настроек (они могут и более 200Мб занимать): "Общие настройки" -> "Filestore" -> "Local" -> "+ Add Local Path". Назовём его "manual_back" и укажем директорию "/var/www/html/backups/". Теперь идём в "Админ" -> "Резервное копирование и восстановление" -> "+ Add Backup". Назовём его "Manualback" и в "Базовая информация" -> "Пункты бекапа" выберем ВСЁ (если не выбрано! после добавления новых модулей - пункты надо выбрать вручную!). В "Storage" -> "Storage Location" -> "manual_back".

Рабочии дни и праздники на "автомате": "Приложения" -> "Calendar" -> "+ Add Calendar" -> "+ Add Remote iCal Calendar". Назовём его "Google_Calendar" и в "Remote URL" укажем ссылку на наш календарь из Гугла. Который мы берём в "Google Calendar" -> "Настройки" -> "Настройки других календарей" -> "Праздники России" -> "Общедоступный адрес в формате iCal". Там ещё есть "закрытый", но зачем свой личный календарь использовать?

Немного о птичках.

Такс. Что-бы ПРАВЕЛЬНО настроить станцию надо понимать философию её работы. Попробуем привести пример. Сначала для входящего звонка.

Оператор SIP транка -> Ваш ВНЕШНИЙ IP адрес -> Firewall / iptables (будем считать, что Ваш пограничный маршрутизатор прозрачен для SIP) -> Asterisk -> "Входящая маршрутизация" на настроеном транке -> "Правила по времени" / рабочии дни -> "Правила по времени" / рабочии часы -> IVR -> "Группы вызова" -> "Внутренние номера" -> Телефон с нужным внутренним номером.

Вот тут, на любом моменте, Ваш вызов может сдохнуть. Дебагить Вам придётся в консоли Астериска, который вызываем командой asterisk -rvvvvvv. Там будет "море шлака", особенно когда Вас будут "ломать". Ещё из неприятного, не все ошибки выводятся в консоль. Если "залип" какой-то модуль внутри станции - ВООБЩЕ НИЧЕГО не увидете. Самое забавное, что иногда и полная перезагрузка железа не помогает, а помогает рандомно потыкать настройки глючащего модуля и сохранить их.

Нужно понимать, что ПРАВЕЛЬНО настроенная станция может и не работать. И тут танцы с бубном очень актуальны. Ведь это может быть, как банальное несовпадение кодеков (хотя эта зараза должна бы сверяться с обоими абонентами!). Так и тупо баг. Если в 16 Freepbx при указании транка, вообще по барабану какое будет название, то в 15-ой версии нужно указывать DID, иначе тупорикс вместо номера телефона транка, отправляет оператору само название транка! Или ещё прикол, если в 1.6 тупорикса можно было использовать логин транка буквенно-цифровой, то теперь ТОЛЬКО цифровой, иначе тупорикс неправельно собирает Dial и оператор транка непонимает, что от него хотят.

Такс. Если ВСЕ входящие валятся в общак, то с исходящими несколько по другому, хоть и проще.

Телефон с нужным внутренним номером -> "Внутренние номера" -> "Исходящая маршрутизация" / правила набора -> "Исходящая маршрутизация" / разрешение выхода на линию -> Выбранный транк -> Asterisk -> Оператор SIP транка.

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

Внутренние номера.

Начнём с них, как основы всего. По умолчанию, что-то автоматом может уже и быть, или удалите, или переделайте. Работать мы будем ТОЛЬКО с pjsip!

Идём в "Приложения" -> "Внутренние номера" -> "+ Добавить внутренний номер" -> "+ Добавить навый SIP [chan_pjsip] внутренний номер" (ну да, перевод тот ещё).

В "Общие" -> "Добавить внутренний номер" -> "Внутренний номер пользователя" нужно указать номер из той адресации, что Вы выбрали для этой станции. Одновременно создастся "пользователь" в системе, можно подключить существующего, но мы делаем с чистого листа. В "Отображаемое имя" можете записать ФИО или что угодно. Болше тут ничего интересного.

В "Голосовая почта" всё понятно, настраивать её не будем - бестолковая вещь. Как и остальное, в том числе iSymphony. Оставьте всё по дефолту, для работы оно не важно, а сломать легко.

В "Найти меня/следуйте сюда" гораздо важнее. Тут переадресация в случае, входящего вызова. В "Общие" включить/выключить понятно. Можно привязать к календарю (выше уже рассматривали). "Начальное время звонка" - это время когда будет звонить сам редактируемый номер (20 секунд оптимально). "Стратегия обзвона" - тут сам чёрт ногу сломит, когда будет выбирать какой вариант предпочтительней (memoryhunt оптимально, для дальнейшей настройки; можете выбрать своё). "Время звонка" - сколько звонят все следующие, куда ушло перенаправление (20 секунд оптимально на каждый телефон). "Список" - тут надо понимать как список ID, можно задать что угодно (группы, внешние номера, мобильники и т.д.), выстраиваются по порядку обзвона, и для НЕ внутренних номеров добавляется # на конце номера. Мелодии, префиксы и т.д. лучше ставить "НЕТ" или пусто. "Изменять конфигурацию внешнего Caller ID" -> "Режим" тут кому что нравиться, мы поставим "Использовать набранный номер", чтобы при переадресации сохранялся входящий номер. "Назначения" -> "Нет ответа" - самый интересный параметр, в идеале, если занят вызываемый номер, то его можно отправить куда угодно, в том числе создать петлю и завесить модуль Find Me/Follow Me.

На этом можно заканчивать. Все извращения дальше сами.

Транки

Мы можем звонить внутри, но нам нужен целый мир. Поэтому идём в "Подключения" -> "Транки" -> "+ Добавить транк" -> "+ Добавить SIP (chan_pjsip) транк" (это умилительно, детский перевод).

Про "приколы" писали выше, теперь будем настраивать так, как оно, хоть как-то работает, до следующего патча. Поэтому идём в "Общие" -> "Название транка" и пишем, к примеру - "Msk_Telphin". "Скрыть CallerID" - "НЕТ". "Исходящий CallerID" - тут номер линии выданный оператором SIP (000123456). "Максимально каналов" - оставляем по дефолту, как и все другие поля и чек-боксы.

Далее сразу в "pjsip Общие настройки" -> "Настройки PJSIP" -> "Общие". "Имя пользователя" - "НЕТ". "Исходящий CallerID" - тут номер линии выданный оператором SIP (000123456). "Auth username" - тут номер линии выданный оператором SIP (000123456). "Секрет" - пароль выданный оператором SIP. "SIP сервер" - у нас Телфин и будет sip.telphin.com. "Порт SIP сервера" - стандартный 5060. Остальное по дефолту.

И усё. Переключаем бегунок "Общие" -> "Выключить транк" в "НЕТ", сохраняем, применяем, радуемся! Наверное... Обычно нет.

Транк IAX2 настраивается аналогично простому chan_sip, возможно по этому в 5-ом издании своей книги О`Рейли, "похоронил" IAX2, хотя в 4-ом воспевал перспективы.

И снова идём в "Подключения" -> "Транки" -> "+ Добавить транк" -> "+ Добавить IAX2 транк".

"Общие" -> "Название транка" и пишем, к примеру - "Msk_office-IAX". "Скрыть CallerID" - "НЕТ". В принципе всё оставляем по дефолту, как и все другие поля и чек-боксы.

Далее сразу в "iax Общие настройки" -> "Исходящий" -> "Название транка" - не будем оригенальничать, напишем "Msk_office-IAX". "опции для PEER":

type=friend
qualify=yes
trunk=yes
host=XXX.XXX.XXX.XXX

Вот по идее, общие параметры транков должны указываться в "Общие настройки" -> "Установки Asterisk для IAX" -> "Дополнительные настройки" -> "Другие установки IAX". Вот ток они не работают от туда! Поэтому в САМОМ транке и указываем type=friend - звонки в обе стороны, qualify=yes - качество, можно задать и числом, trunk=yes - это транк.

И раз мы уже в "Общие настройки" -> "Установки Asterisk для IAX" -> "Основные настройки" сразу сверим "Время регистрации" - оно должно быть ОДИНАКОВЫМ на обоих концах! "Включить джиттер буфер" - это то же ДОЛЖНО БЫТЬ ОДИНАКОВО включено. В "Настройки кодеков" можете поиграться с шириной канала, можете потыкать кнопки, кто будет выдавать приоритет кодеков в канал. Но всё это фигня, поскольку как настроите последовательность в "Аудио кодеки", так он и будет брать самый верхний. А посему - СВЕРЯЙТЕ ПРИОРИТЕТЫ НА ОБОИХ КОНЦАХ ВРУЧНУЮ!!!!

Кстати, SIP транк-то так и не поднялся, несмотря на то, что прошло больше 1 минуты? Прально и не должон! Шагаем в "Общие настройки" -> "Установки Asterisk для SIP" -> "Общие настройки SIP". Проверяем, что отключены всякие анонимные звонки (хз зачем это вообще нужно). "Настройки NAT" - тыкаем "Детектировать сетевые настройки", и молимся что при MultiWAN настроен проброс шлюза только на 1 внешний IP, иначе забанят Вашу станцию к чертям, минут через 10-ть.

"Локальные сети" - ставьте свои, главное себя не отрубите! "Настройки RTP" - про диапазон портов было выше. "ICE Blacklist" - ну так себе, мы далее сделаем по нормальному. Остальное не трогаем. Про кодеки - аналогично IAX. Единственно, у нас сложилась традиция выбирать их так: ulaw, alaw, gsm, g729, ilbc. iLBC, кстати бывает разным, рекомендуется выбирать который скоростью 15 с 20мс.

Кстати! Пока мы в "Общие настройки" -> "Установки Asterisk для SIP" сходим в "SIP Settings [chan_pjsip]" -> "Транспорты" и проверим, что включено как UDP, так и TCP. Часто бывает, что из-за говносетей, по UDP телефон не подключает, что не делай.

В нашей конфигурации мы не будем настраивать TLS/SSL/SRTP - мы ленивые.

Входящие звонки

Согласно философии, сначала было время... Но нет так быстро.

Сначал нам нужны "Приложения" -> "Группы вызова" -> "+ Добавить группу вызова", чтобы правельно настроить IVR и привязать ко времени всё это.

"Описание группы" - напишем "All-Manager". "Лист внутренних номеров" - выбираем наши номера. "Стратегия вызова" - как хотите, у нас "звонят все". "Время звонка" - 20 секунд. Остальное или пропускаем, либо отключаем. "Пропускать занятого оператора" - "ДА". "Задействовать перехват звонка" - "ДА". "Назначение, если никто не ответил" - "Terminal Call / Busy" сбрасывем вызов, если все заняты.

Теперь "Приложения" -> "Интерактивное меню IVR" -> "+ Добавить IVR". "Название Интерактивного меню" - напишем "Hello_Rus", для рабочего времени. "Уведомление" - выбираем голосовой файл, если не загрузили свой, используйте встроенное. "Разрешить прямые наборы" - "Разрешить". "Неудачные попытки" - "3" этого достаточно. Всё остальное или "НЕТ" или "0". "Назначение при таймауте" - "Группа вызова / Manager_anoter". В "Пункты Интерактивного меню" -> "Digits" указываем куда хотим отправить звонок при нажатии кнопки от 0 до 9; если указали не группу вызова, а номер, то есть возможность указать на возврат звонка в меню (ну сами понимаете - пошаговое меню).

А вот тут сделано максимально через жопу. Идём в "Приложения" -> "Временная группа" -> "+ Добавить временную группу". Заметьте, что справа тикают часы! Мы не просто так синхронизацию в самом начале настраивали.

Ту мы создадим 2-ве группы: holidays-in-year и worker_time. С последней всё понятно - указываем время работы конторы, к примеру пн-пц с 9 до 18. С первой - всё сложно. В идеальном мире она и не нужна, выше мы настраивали "Calendar", но вот не работает он и всё тут! Мы столкнулись с "плавающей" ошибкой неправельной записи временной метки в DB. Ошибка может возникнуть в любом месте FreePBX, нам вот свезло тут. Посему, открывает в Интернете производственный календарь и вручную вбиваем праздники их переносы.

Далее. Идём в "Приложения" -> "Правила по времени" -> "+ Добавить временное правило". Тут то же создаём 2 правила - сначала проверку на выходные дни, потом на рабочии часы. Да, криво-косо, но что делать.

"Имя условия по времени" - напишем "worker-data-rus". "Mode" выбираем "Time Mode Group". "Временная группа" - "holidays-in-year", долго плачем... "Назначение , если текущее время попадает в интервал" - "IVR / Not_work_time". "Назначение , если текущее время не попадает в интервал" - "Правила по времени / worked-time-for-rus". Вообще не удивляйтесь, что у Вас этого ещё нет этих параметров, вся настройка Астреска - это тупое беганье туда-сюда по меню. Если чего-то нет, ставьте первое попавшееся значение, потом поменяете!

Ну вот и второе условие "Имя условия по времени" - напишем worked-time-for-rus. "Mode" выбираем "Time Mode Group". "Временная группа" - "worker_time", долго снова плачем... "Назначение , если текущее время попадает в интервал" - "IVR / Hello-Rus". "Назначение , если текущее время не попадает в интервал" - "IVR / Not_work_time".

И вот ТОЛЬКО ТЕПЕРЬ мы идём в "Подключения" -> "Входящая маршрутизация" -> "+ Добавить входящий маршрут". в "Общие" -> "Описание" пишем "Moscow-Telphin". "Номер DID" - выданный оператором SIP (писать номер надо именно ТАК, КАК его описали в "Подключения" -> "Транки" -> "ваш-транк" -> "pjsip Общие настройки" -> "Расширенный" -> "Контактная персона" иначе работать не будет!), мы укажем +7499XXXXXXX. Болше ничего не трогаем, кроме самого важного - "Установить направление / worker-data-rus"! В принципе на этом настройка окончена. Можете сходить во вкладку "Факс" и настроить переадресацию на внутренний номер факса, если он есть.

Исходящие звонки

Тут, главное понимать куда и что мы будем выводить. В примере, будет участновать 2 транка: внутриофисный и внешний. Причем логика простая, чем правило выше, тем оно проверяется первым! Но, если есть прямое совпадение ниже, будет браться именно это совпадение!!!

Сначал нам нужны "Подключения" -> "Исходящая маршрутизация" -> "+ Добавить исходящий маршрут". В "Настройки маршрутов" -> "Название маршрута" укажем "spb-office_out" - это звонок в офис в Санк-Петербурге. "Тип маршрута" - "Внутрикорпоративный". "Последовательность транков для совпавших маршрутов" указываем наш транк с офис в СПб. В "Правила набора" просто пишем их диапазон номеров в поле "совпадение шаблона" - "32X" и всё. Теперь все в нашем офисе смогут звонить всем в их офисе!

Создадим ещё один с названием "all_out". Тут нужно указать ТОЛЬКО транк для выхода в "Последовательность транков для совпавших маршрутов". Временные зоны и пр. можете настроить отдельно сами. В "Правила набора" в поле "совпадение шаблона" [78]XXXXXXXXXX и +ZXXXXXXXXXX. В поле Caller ID или оставляем пусто, и тогда ВСЕ могут набирать данный шаблон и выходить на этот транк. Или указываем номера, котормым разрешаем набирать наши шаблоны.

Так же в "Правила набора" в поле "совпадение шаблона" можно указать выход на конкретный транк по "городскому номеру" вида: +[78]814. или XXXXXXXX (так называемый "прямой номер"). Так же, для Москвы актуален шаблон вида +[78]49[589]. для разных адресаций.

В "Правила набора" так же есть "приставка" - она добавлет к шаблону номера символы. А так же "префикс" - он удаляет из набранного номера символы. Лучше не использовать, а то сами запутаетесь, что куда, проще пользователей натренировать - без шуток! Тем более, что рекомендуется создавать шаблоны так, чтобы при взломе станции, злоумышленики не смогли названивать в Никарагуа и пр.

Настраиваем файервол v2.0

Настраиваем файервол, часть 2

На самом деле, iptables можно законфигурировать как угодно. В частности по "имени клиента", но это ОЧЕНЬ плохая практика! Есть скрипт автобана при DDOS, и выглядит оно вот так.

iptables -N dos-filter-sip-external
iptables -A INPUT -p udp -m udp --dport 5060 -j dos-filter-sip-external
iptables -A INPUT -p tcp -m tcp --dport 5060 -j dos-filter-sip-external
iptables -A INPUT -p udp -m udp --dport 5080 -j dos-filter-sip-external
iptables -A dos-filter-sip-external -m hashlimit --hashlimit 5/sec --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-name SIPMSG --hashlimit-htable-size 24593 --hashlimit-htable-expire 90000 -j RETURN
iptables -A dos-filter-sip-external -j REJECT --reject-with icmp-admin-prohibited
iptables -N dos-filter-ssh
iptables -I INPUT -p tcp -m tcp --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN -j dos-filter-ssh
iptables -A dos-filter-ssh -m hashlimit --hashlimit 3/min --hashlimit-burst 10 --hashlimit-mode srcip,dstip --hashlimit-name ssh_hash --hashlimit-htable-expire 60000 -j ACCEPT
iptables -A dos-filter-ssh -j DROP

Но мы будем пользоваться 2 другими решениями. Они не очень идеальны, даже очень не очень, но в данный момент самые актуальные.

APIBAN

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

apt install jq dos2unix

Для начала нам нужен сам JSON и, в качестве "пилюли" закинем утилиту проверки кодировки и пр. для наших скриптов (мало ли скопируется криво, если всё делаете в Linux - то пропускайте лишнее).

#! /bin/bash
# * This file is part of APIBAN.org.
# *
# * apiban-iptables-client is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version
# *
# * apiban-iptables-client is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
NOW=$(date +"%Y-%m-%d %H:%M:%S")

# APIKEY and last known ID are stored in config file
CONFIG=/usr/local/bin/apibanconfig.sys

# Output to a LOD
LOG=/usr/local/bin/apiban-client.log

if [ ! -e "${CONFIG}" ] ; then
    # cant find config file
    echo "does $CONFIG exist?"
    echo "unable to locate config file $CONFIG"
    exit 0
fi

# APIKEY and last known ID are stored in apibanconfig.sys
source $CONFIG

# Exit if no APIKEY
if [ -v "$APIKEY" ] ; then
    echo "$NOW - Cannot determine APIKEY. Exiting." >> $LOG
    exit 0
fi

# If no LKID, make it 100
if [ -v "$LKID" ] ; then
    LKID="100"
fi

# check if chain APIBAN exists
CURRIPS=$(iptables -S APIBAN | awk '$1 !="-P"' | awk '{print $4}' | awk '{gsub("/32", "");print}')
if [ -z "$CURRIPS" ] ; then
    echo "$NOW - Making target chain, resetting LKID." >> $LOG
    LKID=100
    iptables -N APIBAN
    iptables -I INPUT -j APIBAN
    iptables -I FORWARD -j APIBAN
fi

BANLIST=$(curl -s https://apiban.org/api/$APIKEY/banned/$LKID)
IPADDRESS=$(echo $BANLIST | jq -r ".ipaddress? | .[]")
CURRID=$(echo $BANLIST | jq -r ".ID?")

# No new bans
if [ "$CURRID" = "none" ] ; then
    echo "$NOW - No new bans since $LKID. Exiting." >> $LOG
    exit 0
fi

# If CURRID is not numeric, exit.
re='^[0-9]+$'
if ! [[ $CURRID =~ $re ]] ; then
    echo "$NOW - Unexpected response from API ERR1 $CURRID. Exiting." >> $LOG
    exit 1
fi

# update LKID
sed -i "s/^\(LKID=\).*$/\1${CURRID}/" $CONFIG

# parse through IPs
IPADDRESSARR=(${IPADDRESS//$'\"'/})
for i in "${IPADDRESSARR[@]}"
do
  NOW=$(date +"%Y-%m-%d %H:%M:%S")
  if [[ $CURRIPS =~ "$i" ]]; then
    echo "$NOW - $i already in APIBAN chain. Bad LKID?" >> $LOG
  else
    iptables -I APIBAN -s $i -j DROP
    echo "$NOW - Adding $i to iptables" >> $LOG
  fi
done

echo "$NOW - All done. Exiting." >> $LOG

У-ух, адово. В этом файле "apiban.sh" от оригинала отличие в паре строк. А именно, чтобы скрипт bash нашел файл "apibanconfig.sys" с паролем и создал "apiban-client.log" для журнала, необходимо указать абсолютный путь, и поэтому файлы должны быть помещены в папку "/usr/local/bin/". Сам файл "apibanconfig.sys" состоит всего из двух строк, в одной из которых содержится пароль, который мы получим по электронной почте с сайта.

APIKEY=MY_API_SUPER_EMAIL_KEY
LKID=1

Проверяем наш файл на криворукость копи-паста, даём права и запускаем адову машину.

dos2unix /usr/local/bin/apiban.sh
chmod 777 /usr/local/bin/apiban.sh
bash /usr/local/bin/apiban.sh

Сначала выдаст ошибку - игнорим, в течении своей работы создастся всё что нужно. И создадим ещё один файл с названием "delete_one_day_apiban.sh".

#!/bin/bash
while true
do
    # Delete old 2500 in APIBAN
    iptables -L APIBAN -n --line-numbers | grep -v "Chain\|num" | sort -k1 -nr | awk 'NR>2500{print $1}' | while read num ; do iptables -D APIBAN $num ; done
    # Wait 24 Hour
    sleep 24h
done

Раз в сутки он будет стирать старые записи, оставляя 2500 наиболее свежих. Работает? Хорошо, теперь надо всё это в "crontab -e" прописать.

*/10 * * * * /usr/local/bin/apiban.sh
30 8 * * * /usr/local/bin/delete_one_day_apiban.sh
chmod +x /usr/local/bin/apiban.sh
chmod +x /usr/local/bin/delete_one_day_apiban.sh

И да "crontab" не будет выполнять скрипт, если его не сделать исполняемым.

Fail2Ban

Fail2Ban - ОЧЕНЬ тупая штука. Она просто берёт лог настроенного приложения и прописывает его в iptables до перезагрузки последнего. Ха-ха-ха!

apt install iptables
nano /etc/fail2ban/jail.conf
[DEFAULT]
...
ignoreip = 127.0.0.1/8 192.168.0.0/16
...
[ACTIONS]
...
# Destination email address used solely for the interpolations in
# jail.{conf,local,d/*} configuration files.
#destemail = root@localhost

# Sender email address used solely for some actions
#sender = root@
...
[JAILS]
...
[sshd]
mode   = normal
port    = ssh
#logpath = %(sshd_log)s
backend = %(sshd_backend)s
...
# Miscellaneous
...
[asterisk]
enabled  = true
port     = 5060,5061
action_  = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
logpath  = /var/log/asterisk/fail2ban
maxretry = 10

Как обычно, ищите разделы - меняете значения. Сам файл логирования мы настраивали в интерфейсе FreePBX ранее.

service fail2ban restart

Итоги

Этот экспресс курс по настройке далеко не полный. Но Вам самим придёться с толкнуться со всеми "прелестями" этой системы. Мужайтесь, поскольку "у самурая нет цели, есть только путь".