IPTables правила для Asterisk

Чтобы разрешить подключение SIP в IPTables, добавим правила (первое для соединений, второе для голосового трафика):

sudo iptables -A INPUT -p udp -m udp --dport 5060 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp --dport 10000:20000 -j ACCEPT

Чтобы разрешить подключения только с конкретного адреса, то вместо правил выше укажем (где 192.168.1.50 доверенный IP адрес):

sudo iptables -A INPUT -p udp -m udp -s 192.168.1.50 --dport 5060 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp -s 192.168.1.50 --dport 10000:20000 -j ACCEPT

Аналогично укажем для каждого IP либо сразу для подсети, например:

sudo iptables -A INPUT -p udp -m udp -s 192.168.1.0/24 --dport 5060 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp -s 192.168.1.0/24 --dport 10000:20000 -j ACCEPT

Чтобы удалить првило укажем ту же команду, заменив -A на -D, например:

sudo iptables -D INPUT -p udp -m udp -s 192.168.1.0/24 --dport 5060 -j ACCEPT
sudo iptables -D INPUT -p udp -m udp -s 192.168.1.0/24 --dport 10000:20000 -j ACCEPT

Посмотреть список правил можно командой:

sudo iptables -nvL

Управление модулями Asterisk

Подключимся к консоли Asterisk:

sudo asterisk -rvv

Просмотрим какие модули уже используются:

module show

Файлы модулей с расширением *.so находятся в директории /usr/lib/asterisk/modules/

Для загрузки и выгрузки модуля используются команды (имя модуля указывается без расширения файла, например не chan_sip.so, а chan_sip):

module load NAME
module unload NAME

Для того чтобы нужные модули загружались автоматически при запуске Asterisk, их нужно указать в файле /etc/asterisk/modules.conf, например откроем его в текстовом редакторе nano:

sudo nano /etc/asterisk/modules.conf

Можно включить автозагрузку всех существующих модулей в папке /usr/lib/asterisk/modules/:

[modules]
autoload=yes

А потом исключить ненужные командами:

noload => module.so

Либо запретить загрузку всех и указать только те которые нужны, например:

;SIP VoIP драйвер
load => chan_sip.so
load => res_rtp_asterisk.so
load => app_dial.so
load => bridge_simple.so
load => res_features.so
; музыка при удержании вызова
load => res_musiconhold.so
load => res_adsi.so
load => pbx_config.so
; список необходимых кодеков
load => codec_a_mu.so
load => codec_adpcm.so
load => codec_alaw.so
load => codec_ulaw.so
load => codec_gsm.so
load => codec_ilbc.so
load => codec_lpc10.so
; нужен если использовать платы Dahdi для аналоговых линий
load => chan_dahdi.so
; парковка вызовов
load => res_parking.so 
; ниже модули которые мне понадобились при настройке записи разговоров
; требуется если используется res_monitor.so
load => func_periodic_hook.so
; требуется если используется res_monitor.so, функция STRFTIME
load => func_strings.so
; требуется если используется res_monitor.so для определения номера, функция CALLERID
load => func_callerid.so
; требуется если используется res_monitor.so для MixMonitor
load => app_dial.so
; для записи разговоров
load => res_monitor.so
; для поддержки формата WAV
load => format_wav.so
; для поддержки формата MP3
load => format_mp3.so
; для записи статистики звонков в MySQL базу
load => cdr_mysql.so
; для включения функционала SNMP, например чтобы собирать статистику различными системами мониторинга
load => res_snmp.so
; для совершения вызовов из контекста помещаемых файлов в директорию /var/spool/asterisk/outgoing/
load => pbx_spool.so

Чтобы применить изменения в файле /etc/asterisk/modules.conf выполним команду из консоли Asterisk:

module reload

Если понадобится, сам Asterisk можно перезагрузить так:

sudo service asterisk restart

Оповещения Zabbix по телефону через Asterisk

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

Наведу пример варианта оповещений Zabbix используя телефонный вызов через Asterisk.

У Asterisk должен быть загружен модуль, для этого откроем файл конфигурации модулей, например в редакторе nano (Ctrl+X для выхода, y/n для сохранения или отмены изменений):

sudo nano /etc/asterisk/modules.conf

И проверим есть ли cтрока, если нет — добавим:

load => pbx_spool.so

А также подгрузим его в данный момент:

sudo asterisk -rvv
module load pbx_spool
quit

В моем случае Zabbix и Asterisk находятся на разных серверах.

На сервере с Asterisk я написал русский текст уведомления в текстовый файл high_temperature.txt которое должно воспроизвестись при звонке.

Установил festival, русский мужской голос чтобы конвертировать текст в звуковой файл и rsync чтобы копировать файл звонка на сервер Asterisk:

sudo apt-get install festival festvox-ru rsync

Собственно команда конвертации текста в звуковой файл:

text2wave -eval '(voice_msu_ru_nsh_clunits)' < high_temperature.txt > high_temperature.wav

Далее конвертировал формат файла wav в ulaw, так как у меня используется он:

sox -V high_temperature.wav -r 8000 -c 1 -t ul high_temperature.ulaw

И переместил готовый звуковой файл в директорию со звуковыми файлами Asterisk:

sudo mv high_temperature.ulaw /usr/share/asterisk/sounds/ru_RU/high_temperature.ulaw

Смотрите также — Как конвертировать звуковые файлы в ulaw, alaw, gsm, g722 и т.д. для Asterisk

На сервере с Zabbix используя текстовый редактор nano я создал файл:

sudo nano /etc/zabbix/zabbix.call

И добавил в него содержимое (где 0670000000 номер телефона на который нужно звонить, а цифра 4 это номер канала Goip4 GSM шлюза с которого будет совершен звонок):

Channel: SIP/goip4/40670000000
Application: Playback
Data: high_temperature
MaxRetries: 10
RetryTime: 60
WaitTime: 30

На файл я установил права 777 чтобы разрешить доступ всем, пользователь zabbix будет его копировать, а на другом сервере пользователь asterisk прочитает и удалит после звонка:

sudo chmod 777 /etc/zabbix/zabbix.call

Также нужно создать сам файл скрипта, который будет выполнять Zabbix (я создал в директорий со скриптами zabbix/alert.d/asterisk_call.sh):

rsync -avh -e "ssh -p 22" /etc/zabbix/zabbix.call root@192.168.1.5:/var/spool/asterisk/outgoing/zabbix.call

Скрипт просто копирует файл zabbix.call на сервер с Asterisk в директорию /var/spool/asterisk/outgoing/, после попадания в которую, Asterisk сразу обрабатывает его и совершает звонок.
По сути скрипту можно передавать номер звонящего и составлять файл zabbix.call, но мне это не нужно было.

Если Asterisk и Zabbix на одном сервере, то строку в скрипте заменим на:

cp /etc/zabbix/zabbix.call /var/spool/asterisk/outgoing/zabbix.call

Или:

rsync -avh /etc/zabbix/zabbix.call /var/spool/asterisk/outgoing/zabbix.call

Чтобы rsync выполнял копирование без запроса пароля, нужно сгенерировать SSH ключ и скопировать его на сервер Astersik, как это делать я описывал в конце статьи — Установка и настройка SSH

Если доступ к серверу по SSH предоставляется пользователю root, то в целях безопасности можно ограничить доступ по IP средствами SSH:

sudo nano /etc/ssh/sshd_config
AllowUsers user1 user2 root@192.168.1.4
sudo service ssh restart

Если проблемы с правами на сервере с Zabbix, например при копировании call файла, можно в файле конфигурации /etc/zabbix/zabbix_server.conf указать следующий параметр:

AllowRoot=1

Осталось добавить новый тип оповещения в панели Zabbix («Администрирование» — «Способы оповещений»).
Далее создал новую группу узлов и добавил устройство для которого отрабатывает триггер о высокой температуре.
Создал отдельного пользователя, указал ему созданный тип оповещения и добавил в созданную группу узлов.
Также добавил действие в «Настройка» — «Действия» указав отправку сообщений через скрипт.

Все, после срабатывания триггера, Zabbix выполнит скрипт который скопирует готовый call файл на сервер Asterisk, а он уже обработает его и совершит звонок, как указано в файле — «MaxRetries: 10», будет пытаться дозвонится 10 раз.

Скрипт отправки СМС через Goip4 шлюз

Приведу пример скрипта написанного на PHP, для отправки СМС сообщений через Goip4 шлюз.
Скрипт получает данные из базы SQL запросом и поочередно отправляет СМС на каждый номер, а также заносит запись об отправке в специальную таблицу sms.

#!/usr/bin/php

<?php

include("config/config.inc.php");
include("config/connect.inc.php");


$Result = mysqli_query($db,
"
SELECT
    abon.first_name,
    abon.second_name,
    abon.id as id,
    abon.depozit as balance,
    abon.id,
    abon.otkl,
    abon.mobile,
    abon.tarif,
    new_tarif.cost_day,
    new_tarif.cost as cost_month,
    new_tarif.dayORmonth as period
FROM
    abon, new_tarif
WHERE
    abon.tarif = new_tarif.id AND abon.state=1 AND abon.killed='' AND abon.tarif=114
"
);


while($Row = mysqli_fetch_array($Result))
{
$user = $Row[id];
$balance =$Row[balance];
$phone = $Row[mobile];

$phone_length=strlen($phone);

if($phone_length==10)
{
$mess_ = "Текст сообщения. На вашем счету $balance";
$mess =  rawurlencode($mess_);

print("$phone           $mess_\n");

//test phone
//$phone = "0670000000";
$r = file_get_contents("http://192.168.22.10/goip/en/dosend.php?USERNAME=ЛОГИН&PASSWORD=ПАРОЛЬ&smsprovider=3&goipname=lifecell&smsnum=$phone&method=2&Memo=$mess");
mysqli_query($db, "INSERT INTO sms VALUES(NULL, '$user', '$phone', NOW(), '$mess_', '$balance')");
//print($r);
//exit();

}
}
?>

Содержимое config.inc.php:

<?php
$mysql_host="localhost";
$mysql_user="ЛОГИН";
$mysql_password="ПАРОЛЬ";
$mysql_base="БАЗА";
?>

Содержимое connect.inc.php:

<?php
$db=mysqli_connect($mysql_host, $mysql_user, $mysql_password, $mysql_base);
mysqli_query($db, "SET NAMES 'utf8'");
?>

Как конвертировать звуковые файлы в ulaw, alaw, gsm, g722 и т.д. для Asterisk

После заказа озвучки у профессионального диктора и нарезки в звуковом редакторе, понадобилось сохранить звуки в разных форматах, оригинал был в wav, так вот приведу пример конвертации через sox (он уже был в системе с Asterisk):

sox -V vm-intro.wav -r 8000 -c 1 -t ul vm-intro.ulaw
sox -V vm-intro.wav -r 8000 -c 1 -t al vm-intro.alaw
sox -V vm-intro.wav -r 8000 -c 1 -t gsm vm-intro.gsm

Кодек g722 вроде он не поддерживает, по крайней мере в man sox не нашел, поэтому установил ffmpeg (в системе Ubuntu Server):

sudo apt-get install ffmpeg

И выполнил конвертирование:

ffmpeg -i vm-intro.wav -ar 16000 -acodec g722 vm-intro.g722

Стандартная директория со звуками Asterisk — /usr/share/asterisk/sounds

Как убрать отображение «New User» в CallerID Asterisk

Заметил однажды, что при входящих звонках с Goip4 шлюза на SIP телефонах отображается не только номер звонящего, а и переменно с номером телефона мигает имя «New User», которое явно лишнее и мешает.

После просмотра конфигурационных файлов Asterisk, заметил в файле /etc/asterisk/users.conf в секции general некоторые стандартные значения, а именно:

[general]
fullname = New User

Которые нужно закомментировать:

;fullname = New User

И перезапустить Asterisk чтобы применить изменения:

sudo service asterisk restart

Все, теперь при входящих звонках будет отображаться только номер телефона.

Решение ошибки в Asterisk «File vm-newn does not exist in any format»

При звонке на номер голосовой почты заметил в консоли Asterisk следующие ошибки:

[Apr 10 17:08:01] WARNING[19135][C-00001cf4]: file.c:701 ast_openstream_full: File digits/1n does not exist in any format
[Apr 10 17:08:01] WARNING[19135][C-00001cf4]: file.c:1017 ast_streamfile: Unable to open digits/1n (format (ulaw)): No such file or directory
[Apr 10 17:08:01] WARNING[19135][C-00001cf4]: file.c:701 ast_openstream_full: File vm-newn does not exist in any format
[Apr 10 17:08:01] WARNING[19135][C-00001cf4]: file.c:1017 ast_streamfile: Unable to open vm-newn (format (ulaw)): No such file or directory

Ошибки возникают из-за отсутствия звуковых файлов, например в моем случае в голосовой почте одно сообщение и при попытке сказать «у вас одно(1n.ulaw) новое(vm-newn) сообщение возникает ошибка и ложится трубка.

Архив с набором нужных файлов достаточно просто загрузить с официального сайта http://downloads.asterisk.org/pub/telephony/sounds/releases/ и распаковать в директорию /usr/share/asterisk/sounds
После этого ошибки не должно быть.

Настройка голосовой почты в Asterisk

Для примера настрою голосовую почту для SIP номера 207.
Голосовые сообщения будут отправляться на email с помощью Postfix.
Как его установить я описывал в этой статье — Установка и настройка Postfix.

Для начала укажем в контексте SIP 207 (обычно в файле /etc/asterisk/sip.conf) следующее:

mailbox=207@voicemailcontext

Далее настроим конфигурацию голосовой почты в файле /etc/asterisk/voicemail.conf:

[general]
; формат звуковых файлов
format=wav49|gsm|wav
; от кого слать письма с уведомлениями
serveremail=noreply@example.com
; прикреплять ли к письму аудио файл
attach=yes
; максимальное количество сообщения (стандартно 100, максимум 9999)
maxmsg=100
; максимальное время сообщения в секундах
maxsecs=120
; максимальное время приветствия в секундах
maxgreet=60
; Количество секунд тишины до завершения записи
maxsilence=10
; порог чувствительности к тишине, чем ниже тем чувствительнее, значение от 0 до 256, стандартно 128
silencethreshold=128
; Максимальное число неудачных попыток подключения
maxlogins=3
; Автоматически перемещать прослушиваемые сообщения в папку «Old». По умолчанию включено.
moveheard=yes
; Кодировка сообщений, стандартная ISO-8859-1, с ней у меня часть текста отображалась неверно, поэтому лучше указать UTF-8
charset=UTF-8
; Пропустить строку «[PBX]:» из заголовка сообщения
pbxskip=yes
; Текст строки «От:»
fromstring=VoiceMail
; Тема письма
emailsubject=Новое голосовое сообщение ${VM_MSGNUM} в ящике ${VM_MAILBOX}
; Содержимое письма
emailbody=Уважаемый ${VM_NAME}:\n\n\tВам пришло новое голосовое сообщение длиной ${VM_DUR} под номером (number ${VM_MSGNUM})\nв ящик ${VM_MAILBOX} от ${VM_CALLERID}, в ${VM_DATE}. \n\t
; Формат даты
emaildateformat=%A, %d %B %Y в %H:%M:%S
pagerdateformat=%T %D
; стандартная программа для отправки почты
mailcmd=/usr/sbin/sendmail -t
; удалять ли сообщения с сервера после отправки в почтовом вложении
delete=yes

[zonemessages]
ru=Europe/Moscow|'vm-received' q 'digits/at' H 'hours' M 'minutes'
ua=Europe/Kiev|'vm-received' q 'digits/at' H 'hours' M 'minutes'

; пропишем параметры контекста voicemailcontext, 1111 - пароль голосовой почты(можно не указывать), Username - имя пользователя, test@example.com - на какой адрес слать голосовые сообщения, после запятой можно указать еще один, в конце опции
[voicemailcontext]
207 => 1111,Username,test@example.com,,attach=yes|tz=ua|delete=yes

Теперь в конфигурации плана набора /etc/asterisk/extensions.conf в основной контекст добавим номер позвонив на который можно прослушать почту

exten => 500,1,Log(NOTICE, Dialing out from ${CALLERID(all)} to VoiceMail (500))
exten => 500,n,VoiceMailMain(0${CALLERID(num)}@voicemailcontext,s)
exten => 500,n, Hangup

И добавим в контекст набора номера 207 строку VoiceMail (после чего, если номер не отвечает или не в сети, будет срабатывать голосовая почта), например:

[207]
exten => 207,1,Dial(SIP/207,30)
exten => 207,n,Answer
exten => 207,n,VoiceMail(207@voicemailcontext)

Напоследок подключимся к консоли Asterisk, перезагрузим конфигурацию, посмотрим список голосовых ящиков и писем:

asterisk -rvv
sip reload
voicemail reload
dialplan reload
voicemail show users
exit

Записанные сообщения хранятся в директории /var/spool/asterisk/voicemail/
Звуковые файлы хранятся в /usr/share/asterisk/sounds

Смотрите также:
Решение ошибки в Asterisk «File vm-newn does not exist in any format»

Как конвертировать звуковые файлы в ulaw, alaw, gsm, g722 и т.д.

Добавление SIP клиента во FreePBX

Чтобы добавить SIP клиента во FreePBX, откроем меню «Applications» — «Extensions«, выберем например «Generic CHAN SIP Device» и укажем основные параметры:

User Extension: 6000 (номер SIP)
Display Name: Operator (любое имя для отображения)
Secret: ПАРОЛЬ
и нажмем «Submit«.

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

Как добавить SIP в конфигурационном файле я описывал в этой статье — Добавление SIP клиентов в Asterisk

Установка и настройка GoIP СМС-сервера

На примере настрою GoIP СМС-сервер в Ubuntu Server 14.04 LTS x64.
Переключимся сразу на root пользователя:

sudo -i

Обновим систему и установим веб-сервер и mysql сервер:

apt-get update
apt-get upgrade
apt-get install apache2 php5 mysql-server

Посмотрим есть ли новые версии СМС сервера тут http://www.hybertone.com/en/news_detail.asp?newsid=21
(Архив с версией которую устанавливал я можно скачать тут — https://drive.google.com/open?id=0B6jR5-c775m9bEtTZUNQankzcWc)
Скачаем во временную директорию архив с goip смс-сервером и запустим скрипт установки:

cd /tmp
wget http://118.142.51.162/update/goip_install-v1.24.2.tar.gz
tar xvfz goip_install-v1.24.2.tar.gz
cd goip_install
./goip_install.sh

Во время установки ответим на несколько вопросов:
1) Расположение директории с конфигурацией веб-серера (создастся файл с веб настройками), в моем случае это /etc/apache2/conf-enabled
2) Пароль root пользователя к Mysql серверу (создастся база goip)
3) Расположение Mysql, стандартно оно так и есть /usr/bin/mysql, просто жмем Enter

Перезапустим веб-сервер чтоб загрузился файл с настройками из /etc/apache2/conf-enabled:

service apache2 restart

В браузере уже можно открыть панель управления смс-сервером http://сервер/goip
У меня отобразилась ошибка:

Forbidden
You don’t have permission to access /goip on this server.

Причиной этому устаревшие параметры в /etc/apache2/conf-enabled/goip.conf, закомментируем две строки символом # и добавим строку после них:

#    Order allow,deny
#    Allow from all
Require all granted

После этого все открылось, стандартный логин и пароль root.

Приступим к настройке.
В «System Manage» — «Provider Manage» добавим провайдера, для этого укажем в Provider(1) его имя или просто номер самими цифрами.

Теперь перейдем в «System Manage» — «GoIP Manage«, вверху нажмем «Add GoIP» и добавим аккаунт для первого канала GoIP шлюза (первой сим).
ID:ks1
Batch Lines:1
Provider:созданный провайдер
Password:пароль
Confirm Password:пароль

Откроем веб-интерфейс GoIP шлюза и перейдем в «Configurations» — «SMS» где укажем параметры этого аккаунта.
SMS Server:Enable
SMS Server IP: адрес СМС-сервера
SMS Server Port:44444
SMS Client ID: ks1
Password: пароль
Send SMSC Number: Enable

После этого в СМС-сервере «System Manage» — «GoIP Manage» должен отобразится статус «Login«.

Если статус Login не появляется, у меня так было на Ubuntu Server 14.04 LTS x64 и замечал сообщение:

but cannot get response from process named «goipcron»

Для решения этой проблемы пришлось доставить библиотеки:

cd /etc/apt/sources.list.d
echo "deb http://old-releases.ubuntu.com/ubuntu/ raring main restricted universe multiverse" >ia32-libs-raring.list
apt-get update
apt-get install ia32-libs
ln -s /var/run/mysqld/mysqld.sock /var/lib/mysql/mysql.sock

И наново запустить goipcron:

cd /usr/local/goip
./run_goipcron

Для автозапуска run_goipcron создадим файл например используя редактор nano:

sudo nano /etc/init.d/goipcron

Добавим в файл:

#! /bin/sh
cd /usr/local/goip
./run_goipcron

Сделаем файл выполняемым:

sudo chmod +x /etc/init.d/goipcron

И добавим в автозагрузку:

sudo update-rc.d goipcron defaults 80

На сервере в случае проблем с соединением можно ловить пакеты через tcpdump например так:

tcpdump -i any -vnn -s0 port 44444

Сервер может принимать POST и GET запросы, приведу пример отправки СМС (номеров получателей можно указать несколько через запятую без пробелов):

http://192.168.1.21/goip/en/dosend.php?USERNAME=логин&PASSWORD=пароль&smsprovider=1&goipname=ks1&smsnum=номерполучателя&method=2&Memo=текст сообщения

Входящие СМС можно увидеть в Send Message — Inbox, исходящие в Send Message — Examine Sendings.
Чтобы не писалась статистика звонков (у меня ее пишет Asterisk), в System ManageSystem Manage поставим Disable напротив GoIP Report Record, а также поставим Disable на Save message before sending(browser should support javascript) чтобы не использовать java со стороны клиента при отправке СМС через API.

Приведу примеры SQL запросов которыми можно посмотреть/посчитать количество СМС отправленных/доставленных, отправленных/не доставленных за все время и в конкретную дату:

SELECT * FROM `sends` WHERE received=1;
SELECT * FROM `sends` WHERE received=0;
SELECT * FROM `sends` WHERE received=0 AND time LIKE '2017-02-05%';

Если на Linux используется iptables, то добавим правило разрешающее подключение Goip4 шлюза (где 192.168.2.2 — адрес Goip4 шлюза):

iptables -A INPUT -s 192.168.2.2/32 -p udp -m udp --dport 44444 -j ACCEPT