Настройка "с нуля"
Введение, начало
Установка и настройка FreePBX
Подключение GSM модема
Настройка fail2ban
Настройка Mikrotik
Введение, начало
В небольшой офис потребовалась АТС, для звонков по России и между сотрудниками. Был выбор между использованием готовых решений от SIP провайдеров и самодельной личной АТС. У каждой стороны есть свои плюсы и минусы. Так как офис только запускался, сотрудников мало, тотальный режим экономии, то от провайдеров отказался - абонентская плата за номер (при том что номер дается городской, к которому сложно привязать мессенджеры, мобильные номера от провайдера у клиентов не вызывают доверия и так же имеют проблемы с привязкой к мессенджерам) и тарифы на звонки на мобильные номера клиентов у всех не менее 1,5 руб./мин.
Т.к. в наличии был не используемый Raspberry Pi 3B+, то решено было использовать его в качестве АТС с Asterisk. MicroSD карта, от 8Гб, желательно 16Гб для установки системы. Были попытки установки голой версии с нуля по различным туториалам из сети, но во всех постоянно были какие то проблемы, т.к. они все написаны от 2 до 10 лет назад, на быстрый старт они не сработали.
Так же для автономной работы без зависимости от провайдеров нужен USB модем с поддержкой голосовых вызовов, есть списки нормально работающих модемов (предварительно разблокированных по инструкциям из 4ПДА), у меня работает Huawei E1550.
Для безопасной работы в сети использую Mikrotik RB951G, теоретически можно любой, OS у них одна и та же (основ настройки роутера здесь не будет, подразумевается, что у вас интернет через него уже работает). Так же нужен интернет провайдер с возможностью предоставить статический или динамический IP адрес, что бы можно было подключатся к АТС из любого места сети интернет. Через приватные адреса у меня не получилось работать (через мобильные сети тоже, они все предоставляют адрес, к которому нет подключения снаружи, да же через DDNS сервисы).
Установка и настройка FreePBX
Сохраняем себе в закладки сайт http://www.raspberry-asterisk.org/ , там скачиваем образ системы raspbx-10-10-2020.zip. Распаковываем архив, если для записи используется программа Win32DiskImager, можно без распаковки и использовать для записи, например, BalenaItcher. Записываем на компьютер скачанный образ на карту microSd, записанную карту вставляем в raspberry, подключаем кабели (сеть к роутеру, питание), включаем и ждем загрузки, монитор не нужен. В роутере в разделе ip-dhcp server-leases смотрим назначенный адрес нашей АТС, это нужно будет для подключения по ssh.
В браузере набираем http://raspbx/, проходим первоначальную регистрацию, назначение имени и пароля администратора FreePBX, желательно сложный защищенный, если нет желания все снова настраивать восстанавливать. В конечном итоге после входа должно получится так:
Так же подключаемся через Putty к asterisk, логин и пароль пока стандартные root/raspberry. Меняем пароль по умолчанию:
passwd
Все пароли сохраняйте в надежных местах, потому что, когда долго не подходишь к работающему устройству, то память может и забыть пароль для входа, который достаточно сложно восстановить.
Так как система основана на Debian, то здесь работают стандартные команды. Обновляем систему, настраиваем свою временную зону, устанавливаем модуль для работы с USB модемом, файловый навигатор MC для удобства:
raspbx-upgrade
configure-timezone
install-dongle
apt install mc
При установке модуля dongle указываем реальный номер, который будет использоваться в модеме (у оператора сотовой связи выбираем тариф с пакетом минут на звонки по России).
Так как у меня не получилось запустить систему на современном драйвере pjsip (в телефонах тишина), то все настройки будут на legacy sip, работает на всех абонентских устройствах.
В браузере переходим по порядку основные настройки:
Переходим на закладку SIP legacy setting:
Так же меняем стандартное значение порта на вкладке PJSIP, все сохраняем и применяем ( submit & apply config).
Настраиваем extension (это номера для подключения абонентов):
настроили абонентов, Submit & Apply config.
Настройка trunk для модема:
Маршрут для входящих звонков:
Маршрут для исходящих звонков:
С графической частью закончили. Главное не забывать после каждых действий Submit & Apply Config, что бы внесенные изменения сохранялись.
Подключение GSM модема
Здесь собранная копипаста из разных источников:
Тестированные модемы:
Предварительно на компьютере перевести GSM-модем в режим работы «только модем» ( AT^U2DIAG=0 ) и в режим только 2G (AT^SYSCFG=13,1,3fffffff,0,0 ) с помощь Putty или любым другим способом, можно и через raspberry, но и так здесь большой объем.
E171 - ОК
E1550 - ОК
E150 - Голос только в одну сторону
E3131 - Работают не стабильно, при исходящих голос только в одну сторону
E352 - Нет голосовых функций
Подключаем GSM-модем HUAWEI E1550, проверяем появились ли устройства ttyUSB*:
ls -al /dev | grep ttyUSB
полученный ответ команды
crw-rw---- 1 root dialout 188, 0 фев 27 11:34 ttyUSB0
crw-rw---- 1 root dialout 188, 1 фев 27 11:33 ttyUSB1
crw-rw---- 1 root dialout 188, 2 фев 27 12:37 ttyUSB2
Чтобы при подключении GSM-модема, Asterisk имел доступ к нему, необходимо устройству назначить владельца asterisk и группу dialout. Создаем файл (nano /etc/udev/rules.d/92-dongle.rules) со следующим содержимым:
KERNEL=="ttyUSB*", MODE="0666", OWNER="asterisk", GROUP="dialout" |
Перезагружаем raspberry командой reboot и переподключаемся к атс с помощью Putty.
Настройка файла dongle.conf ( nano /etc/asterisk/dongle.conf ) - проверяем параметр exten и прописываем imei модема, остальное можно не трогать:
initstate=start ; specified initial state of device, must be one of 'stop' 'start' 'remote'
; 'remove' same as 'disable=yes'
exten=+79234567890 ; Проверяем наш номер сим карты, он связан с ранее настроенными
dtmf=relax ; control of incoming DTMF detection, possible values:
; off - off DTMF tones detection, voice data passed to asterisk unalte$
; use this value for gateways or if not use DTMF for AVR or in$
; inband - do DTMF tones detection
; relax - like inband but with relaxdtmf option
; default is 'relax' by compatibility reason
; dongle required settings
[dongle0]
audio=/dev/ttyUSB1 ; tty port for audio connection; no default value
data=/dev/ttyUSB2 ; tty port for AT commands; no default value
imei=351234567898991 ; ПРОПИСЫВАЕМ IMEI модема
;imsi=123456789012345
В консоли asterisk, перечитываем конфигурацию chan_dongle и проверяем состояние устройства. Если все было сделано правильно, то подключение к GSM-модему будет осуществлено и устройство будет отображаться в консоли asterisk:
root@raspbx:/# asterisk -rv
raspbx*CLI> dongle show devices
ID Group State RSSI Mode Submode Provider Name Model Firmware IMEI IMSI Number
dongle0 0 Free 26 3 3 MegaFon E1550 11.608.14.15.311 35******* 2**************3 Unknown
Настройка файла конфигурации для звонков и смс (настраивал только входящие смс с переадресацией на настроенный extension) :
nano /etc/asterisk/extensions_custom.conf
[from-trunk-dongle]
; можно раскомментировать, тогда смс будут записываться в файл sms.txt, смотреть потом в логах
;exten => sms,1,Verbose(Incoming SMS from ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})})
;exten => sms,n,Set(FILE(/var/log/asterisk/sms.txt,,,a)=${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLE$
;exten => sms,n,System(echo >> /var/log/asterisk/sms.txt)
;exten => sms,n,Hangup()
exten => _.,1,Set(CALLERID(name)=${CALLERID(num)})
exten => _.,n,Goto(from-trunk,${EXTEN},1)
; закомментировать, если выше было раскомментировано
exten => sms,1,Set(MESSAGE(body)=${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: ${$
exten => sms,n,Set(MESSAGE(from)="${CALLERID(num)}" <${CALLERID(num)}>)
exten => sms,n,Set(CALLERID(name)=${CALLERID(num)})
exten => sms,n,Verbose(1,${MESSAGE(from)})
exten => sms,n,MessageSend(sip:250,${MESSAGE(from)}) ; Прописываем куда пересылать входящие сообщения - на номер 250
exten => sms,n,Hangup()
exten => ussd,1,Verbose(Incoming USSD: ${BASE64_DECODE(${USSD_BASE64})})
exten => ussd,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME}: ${BASE64_DECODE(${US$
exten => ussd,n,Hangup()
Сохраняем, перезагружаем, пробуем звонить (входящие исходящие) и присылать смс. Должно все работать.
Пробовал вариант подключения смартфона по Bluetooth в качестве шлюза, все работало, но качество связи было ужасное, причем на стороне астериска (голос сильно искаженный, скорее всего из-за кодеков блютуза, настроить не смог).
Настраиваем защиту asterisk freepbx с помощью fail2ban (By @UKVoIPForums )
Полноценных русскоязычных гайдов для начинающих не нашел, есть на английском форуме:
install-fail2ban
Создаем тюрьму:
sudo nano /etc/fail2ban/jail.local
Копируем содержимое в файл jail.local
[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space separator.
ignoreip = 127.0.0.1/8 ::1
[asterisk]
enabled = true
filter = asterisk
action = iptables-asterisk[name=asterisk]
logpath = /var/log/asterisk/security_log
bantime = 31536000
findtime = 86400
maxretry = 3
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
banaction = iptables-allports
bantime = 31536000
findtime = 86400
maxretry = 3
[freepbx]
enabled = true
port = http,https
filter = freepbx
logpath = /var/log/asterisk/freepbx_security.log
bantime = 31536000
findtime = 86400
maxretry = 3
Еще 6 файлов конфигурации нужно создать/изменить, поехали:
sudo nano /etc/fail2ban/filter.d/freepbx.conf
1. Копируем содержимое в файл freepbx.conf
[INCLUDES]
before = common.conf
[Definition]
datepattern = ^\[%%Y-%%b-%%d %%H:%%M:%%S\]
failregex = \[freepbx_security\.NOTICE\]: Authentication failure for .* from <HOST>
sudo nano /etc/fail2ban/filter.d/asterisk.conf
2. Копируем содержимое в файл asterisk.conf, на всякий случай скопируйте существующее содержимое оригинального файла
# Fail2Ban configuration file
#
#
# $Revision: 251 $
#
[INCLUDES]
# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf
[Definition]
#_daemon = asterisk
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching and is only an alias for
# (?:::f{4,6}:)?(?P<host>\S+)
# Values: TEXT
#
# Asterisk 1.8 uses Host:Port format which is reflected here
failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Wrong password
NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - No matching peer found
NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Username/auth name mismatch
NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Device does not match ACL
NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Peer is not supposed to register
NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - ACL error (permit/deny)
NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Device does not match ACL
NOTICE.* .*: Registration from '\".*\".*' failed for '<HOST>:.*' - No matching peer found
NOTICE.* .*: Registration from '\".*\".*' failed for '<HOST>:.*' - Wrong password
NOTICE.* <HOST> failed to authenticate as '.*'$
NOTICE.* .*: No registration for peer '.*' \(from <HOST>\)
NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
NOTICE.* .*: Failed to authenticate user .*@<HOST>.*
NOTICE.* .*: <HOST> failed to authenticate as '.*'
NOTICE.* .*: <HOST> tried to authenticate with nonexistent user '.*'
SECURITY.* .*: SecurityEvent="ChallengeSent",.*,.*,Service="(PJ)?SIP",.*,AccountID="<unknown>",.*,.*,RemoteAddress=".*/.*/<HOST>/.*",Challenge=""
SECURITY.* .*: SecurityEvent="InvalidAccountID",.*,Severity="Error",Service="(PJ)?SIP",.*,.*,.*,.*,RemoteAddress=".*/.*/<HOST>/.*"
SECURITY.* .*: SecurityEvent="ChallengeResponseFailed",.*,Severity="Error",Service="(PJ)?SIP",.*,.*,.*,.*,RemoteAddress=".*/.*/<HOST>/.*",.*
SECURITY.* .*: SecurityEvent="InvalidPassword",.*,Severity="Error",Service="(PJ)?SIP",.*,.*,.*,.*,RemoteAddress=".*/.*/<HOST>/.*",.*
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
sudo nano /etc/fail2ban/action.d/iptables-asterisk.conf
3. Копируем содержимое в файл iptables-asterisk.conf (в файле по аналогии добавляем наши кастомные порты, которые мы прописывали в настройках SIP)
# Fail2Ban configuration file
#
# Author: Razvan Turtureanu
#
# $Revision$
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I <chain> -p tcp --dport 5061 -j fail2ban-<name>
iptables -I <chain> -p udp --dport 5060 -j fail2ban-<name>
iptables -I <chain> -p tcp --dport 5060 -j fail2ban-<name>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = iptables -D <chain> -p tcp --dport 5061 -j fail2ban-<name>
iptables -D <chain> -p udp --dport 5060 -j fail2ban-<name>
iptables -D <chain> -p tcp --dport 5060 -j fail2ban-<name>
iptables -F fail2ban-<name>
iptables -X fail2ban-<name>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck = iptables -n -L <chain> | grep -q fail2ban-<name>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
[Init]
# Defaut name of the chain
#
name = default
# Option: chain
# Notes specifies the iptables chain to which the fail2ban rules should be
# added
# Values: STRING Default: INPUT
chain = INPUT
sudo nano /etc/asterisk/logger_logfiles_custom.conf
4. Копируем содержимое в файл logger_logfiles_custom.conf
security_log => SECURITY,NOTICE
sudo nano /etc/logrotate.d/asterisk-security
5. Копируем содержимое в файл asterisk-security
/var/log/asterisk/security_log {
weekly
missingok
rotate 4
size 2000k
sharedscripts
create 0664 asterisk asterisk
su asterisk asterisk
postrotate
/usr/sbin/invoke-rc.d asterisk logger-reload > /dev/null 2> /dev/null
endscript
}
sudo nano /etc/logrotate.d/freepbx-security
6. Копируем содержимое в файл freepbx-security
/var/log/asterisk/freepbx_security.log {
weekly
missingok
rotate 4
size 2000k
sharedscripts
create 0664 asterisk asterisk
su asterisk asterisk
postrotate
/usr/sbin/invoke-rc.d asterisk logger-reload > /dev/null 2> /dev/null
endscript
}
Перезагружаемся - reboot
Памятка для работы с fail2ban:
File permissions and owner/group information:
/etc/fail2ban/jail.local = rw-r--r-- root root
/etc/fail2ban/filter.d/freepbx.conf = rw-r--r-- root root
/etc/fail2ban/filter.d/asterisk.conf = rw-r--r-- root root
/etc/fail2ban/action.d/iptables-asterisk.conf = rw-r--r-- root root
/etc/asterisk/logger_logfiles_custom.conf = rw-rw-r-- asterisk asterisk
/etc/logrotate.d/asterisk_security = rw-r--r-- root root
Basic Fail2ban commands:
Start Fail2ban = sudo service fail2ban start
Stop Fail2ban = sudo service fail2ban stop
Restart Fail2ban = sudo service fail2ban restart
Get the current status of an individual jail:
FreePBX status = sudo fail2ban-client status freepbx
Asterisk status = sudo fail2ban-client status asterisk
SSHD status = sudo fail2ban-client status sshd
Ban/Unban IP addresses:
Ban IP = sudo fail2ban-client set *YOURJAILNAMEHERE banip IPADDRESSHERE
Unban IP = sudo fail2ban-client set *YOURJAILNAMEHERE unbanip IPADDRESSHERE
*Replace YOURJAILNAMEHERE with freepbx, asterisk or sshd.
*Replace IPADDRESSHERE with the IP address that you want to ban/unban.
Настройка Mikrotik
Нужно настроить проброс портов и защиту.
IP-Firewall-жмем на плюсик:
Создаем ловушки на стандартных портах и рядом стоящих для сканировщиков и отправляем в бан. Правило копируем и делаем для tcp, так же можно сделать для других стандартных портов 22,3389,8291
Делаем проброс портов во вкладке NAT (номера, которые прописывали в SIP настройках FreePBX), копируем и пишем диапазон RTP по аналогии
Проброс портов для работы абонентов в локальной сети
Так же можно/желательно делать перезагрузку системы в автоматическом режиме по расписанию, для сброса зависшего модема, у меня завис через 5 дней работы, а рядом никого, пришлось ехать и в ручную перегружать.
crontab -e
# пишем в конце файла (перезагрузка каждый день в 5 утра)
0 5 * * * /sbin/reboot
Желательно настроить VPN доступ к микротику из интернета, для разруливания внештатных ситуаций по случайно забаненым адресам абонентов.
Долго собирал из разных источников эту работающую инструкцию. Может кому то и поможет.
Javian
Если питание с модема не снимать, то он может не отвиснуть — habr.com/ru/post/324436
Dmitry27 Автор
Да, я читал. По этому и рекомендация перевести модем в режим 2G, для снижения энергопотребления по USB, вероятность зависнуть меньше будет. У распбери есть особенность, что при перезагрузке он сбрасывает инициализацию по USB, из-за этого многие жесткие диски при подключении по USB нормально иногда не отрабатывают.