< meta name="referrer" content="origin">
Home » Asterisk » Asterisk — SIP АТС для офиса, пошаговая инструкция по настройке с нуля

Asterisk — SIP АТС для офиса, пошаговая инструкция по настройке с нуля

Одним из рабочих инструментов офиса, несмотря на стремительные изменения последних десятилетий, по-прежнему является телефон. Мы займемся пошаговой настройкой с нуля АТС asterisk — современного инструмента для организации телефонии в офисе на основе протокола SIP. Я подробно с примерами и описанием проведу вас по основным параметрам, необходимым для базового функционала.

Введение

Не буду останавливаться на описании сервера asterisk, в интернете много информации на эту тему. Да и сам я кратко рассказывал в своих предыдущих статьях про установку. Материал будет объемный, поэтому сразу перейдем к сути.

Статья планируется учебная, поэтому использовать будем голый asterisk без каких-либо web панелей для управления. Выполнять настройку asterisk будем с нуля, то есть с самой начальной установки самого сервера телефонии и всех зависимостей. Если вы разберетесь и освоите этот материал, то потом без проблем сможете настроить и поддерживать любую конфигурацию на основе астериска.

Я хочу подробно рассказать о настройке asterisk на конкретном примере, где будет собран в одном месте расширенный функционал, отвечающий практически на все запросы среднестатистического офиса.

Сразу хочу обратить внимание на очень важный момент. Я не являюсь профессионалом в настройке asterisk. Данный материал является калькуляцией всех моих знаний на текущий момент, которые я методично шаг за шагом собирал из доступных в интернете источников. По этой статье вы получите рабочий, многофункциональный сервер телефонии, работу которого я проверял на практике. Но это не означает, что все, что здесь настроено, сделано наилучшим образом. Я постоянно учусь и совершенствую свои знания. Если вы увидите ошибки, недочеты, варианты более правильной и удобной настройки, прошу об этом сообщить в комментариях, я проверю и обновлю статью.

Для примера опишем наш воображаемый офис:

  • Работает 30 сотрудников. Номера будут трехзначные, от 100 до 130.
  • У нас будут 3 отдела — менеджеры, техподдержка, руководство и все остальные.
  • Номер секретаря 100, менеджеры 101-110, техподдержка 111-120, руководство 121-130.
  • Мы будем использовать одного SIP провайдера для звонков.

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

Для настройки я буду использовать учетную запись сервиса zadarma.com. Сразу скажу, что в реальной работе я никогда не использовал этот сервис и его качество мне не известно. Беру его для примера, потому что удобно использовать для тестирования конфигурации. Сразу после регистрации вам дают аккаунт, пример настроек для asterisk. Вы можете позвонить на прямой городской номер, ввести добавочный и совершить звонок на свой аккаунт. Это полностью эмулируер работу sip подключения от какого-нибудь провайдера.

В качестве операционной системы у меня выступает CentOS 7. Но для данной статьи это не имеет принципиального значения. Конфигурация астериск кроссплатформенная, без проблем переносится между системами.

Приступаем к нашей работе по настройке сервера телефонии.

Быстрая установка

Вопроса установки asterisk я уже касался в своей прошлой статье. Но там я использовал связку с панелью управления freepbx. Здесь же мы будем использовать голый астериск, без обвязок. Более того, я не буду использовать никаких дополнительных плат расширения и модемов. Будет только софтовая АТС, которая легко переносится с одного сервера на другой при желании. Считаю, что такой подход наиболее эффективен и к нему стоит стремиться. Настроив виртуальную машину, вы навсегда будете отвязаны от конкретного железа и спокойно можете переносить свой сервер куда угодно, заменив только сетевые настройки.

Таким образом, нам нужно установить непосредственно asterisk и pjproject с jansson. На первоначальном этапе этого достаточно. Если вы предпочитаете сервер debian, то воспользуйтесь отдельной инструкцией по установке asterisk 13 на debian 8. После этого можете сразу же переходить на следующий этап настройки. Приступим.

Первым делом обновляем систему и отключаем SELinux, как рассказано в статье про настройку centos.

Подключаем репозиторий epel и устанавливаем необходимые пакеты, которые нам пригодятся в дальнейшем:

# yum -y install epel-release
# yum -y install lynx mariadb-server mariadb php php-mysql php-mbstring tftp-server httpd ncurses-devel sendmail sendmail-cf sox newt-devel libxml2-devel libtiff-devel audiofile-devel gtk2-devel subversion kernel-devel git php-process crontabs cronie cronie-anacron wget vim php-xml uuid-devel sqlite-devel net-tools gnutls-devel php-pear phpmyadmin
# yum -y groupinstall core base "Development Tools"

Скачиваем и устанавливаем pjproject:

# cd /usr/src
# wget http://www.pjsip.org/release/2.4/pjproject-2.4.tar.bz2
# tar -xjvf pjproject-2.*
# cd pjproject-2.*
# CFLAGS='-DPJ_HAS_IPV6=1' ./configure --prefix=/usr --enable-shared --disable-sound --disable-resample --disable-video --disable-opencore-amr --libdir=/usr/lib64
# make dep
# make
# make install

Скачиваем и устанавливаем jansson:

# cd /usr/src
# wget -O jansson.tar.gz https://github.com/akheron/jansson/archive/v2.7.tar.gz
# tar vxfz jansson.tar.gz
# cd jansson-*
# autoreconf -i
# ./configure --libdir=/usr/lib64
# make
# make install

Скачиваем и устанавливаем asterisk 13:

# cd /usr/src
# wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-13-current.tar.gz
# tar xvfz asterisk-13-current.tar.gz
# cd asterisk-*
# contrib/scripts/install_prereq install
# contrib/scripts/get_mp3_source.sh
# ./configure --libdir=/usr/lib64
# make menuselect

Выбираем необходимые модули и звуки:

  • Add-ons: format_mp3, res_config_mysql, app_mysql и cdr_mysql.
  • Core Sound Packages: Выбираем русские звуки RU-WAV.
  • Music On Hold File Packages: Выбираем звук WAV.
  • Extras Sound Packages: Выбираем английский EN-WAV, русского к сожалению нет.

Выбор параметров установки

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

Продолжаем установку:

# make
# make install
# make samples
# make config
# ldconfig

Устанавливаем русскую core озвучку хорошего качества и английскую для extra, русской к сожалению нету:

# cd /var/lib/asterisk/sounds
# wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-core-sounds-ru-wav-current.tar.gz
# wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-extra-sounds-en-wav-current.tar.gz
# tar xvf asterisk-core-sounds-ru-wav-current.tar.gz
# tar xvf asterisk-extra-sounds-en-wav-current.tar.gz

Добавляем астериск в автозагрузку и запускаем:

# chkconfig asterisk on
# service asterisk start

Проверим, запустился ли он, зайдя в консоль:

# asterisk -r

Проверка работы asterisk

Если получили такой же вывод команды, значит все в порядке, астериск установлен.

Настройка iptables, asterisk за NAT, проброс портов

Сразу же уделим внимание настройке iptables для работы астериск. У нас может быть 2 ситуации, которые требуют двух принципиально различных настроек:

  1. Сервер телефонии имеет свой внешний ip адрес и напрямую смотрит через него в интернет.
  2. Сервер стоит за шлюзом, не имеет своего внешнего адреса, доступ в интернет с помощью NAT.

В первом случае нам нужно открыть на iptables необходимые порты для работы, все остальное закрыть. Подробно вопрос настройки iptables я рассматривал в отдельной статье. Там есть примеры и пояснения, рассказан мой подход к настройке.

Я не могу привести универсальные настройки для всех случаев. У каждого будут свои нюансы. Кто-то, к примеру, будет пользоваться phpmyadmin для настройки базы mysql для хранения статистики звонков. Потом эту же статистику будет просматривать через cdr viewer, установленный на веб сервере. Доступ к этому веб серверу можно открыть через внешний IP адрес, а можно только через локальную сеть. Настройки iptables в данном случае будут разные.

В моем примере сервер будет находиться в локальной сети офиса за nat. Доступ в интернет осуществляется через офисный шлюз, на котором установлены iptables. На нем будет сделан проброс необходимых портов для работы внешних телефонных аппаратов. В случае, если у вас все телефоны будут находиться в локальной сети офиса вместе с сервером телефонии, пробрасывать ничего не нужно. С сервисом zadarma все будет работать без проброса портов. Пиры зарегистрируются на внешнем сервере провайдера и этого будет достаточно для приема и совершения звонков.

С другими провайдерами этого может быть не достаточно. В общем случае для настройки asterisk за nat нужно будет на шлюзе пробросить порт 5060 и диапазон 10000:20000. По-умолчанию астериск использует UDP порты. Если вы не будете менять эти настройки, то пробрасывать нужно именно UDP.

В моем случае получается следующая картина. На шлюзе сделан проброс необходимых портов:

iptables -t nat -A PREROUTING -p udp --dst $WAN_IP --dport 5060 -j DNAT --to 192.168.1.25:5060
iptables -t nat -A PREROUTING -p udp --dst $WAN_IP --dport 10000:20000 -j DNAT --to 192.168.1.25
$WAN_IP Внешний IP адрес на шлюзе
192.168.1.25 Локальный адрес сервера астериск

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

Подключение абонентов и проверка внутренних звонков

Астериск у нас установлен, firewall настроен. Можно попробовать подключиться и протестировать работу АТС. Я для отладки использую бесплатную софтовую звонилку 3CXPhone 6-й версии. Не знаю, где ее сейчас найти в интернете. У самого производителя давно уже вышли более новые и платные версии, которые работают только с его АТС. А эта версия универсальная. В ней отличный функционал, удобные настройки, есть дебаг режим с подробным логированием. Пользоваться программой удобно и приятно. Скачиваем ее у меня и устанавливаем.

Теперь нам нужно сделать некоторые общие настройки и добавить пользователей. Работать будем с файлом конфигурации /etc/asterisk/sip.conf. Файлы настроек астера хорошо закомментированы, но мне это мешает с ними работать. Они слишком большие и громоздкие, неудобно прокручивать вверх и вниз, поэтому я их полностью чищу и вношу только те настройки, которые мне нужны. Так удобнее и нагляднее получается. Сохраните на всякий случай куда-нибудь оригинальный файл sip.conf и начинайте новую настройку. Вот мой пример конфига для нашего случая:

[general]
;Внешний ip адрес
externaddr=212.78.136.18:5060
;Указываем использовать русскую озвучку
language=ru
context=default
allowoverlap=no
udpbindaddr=0.0.0.0
tcpenable=no
tcpbindaddr=0.0.0.0
transport=udp
srvlookup=yes
allowguest=no
limitonpeers=yes

[authentication]

;Создаем шаблон для телефонов менеджеров
[managers-phones](!)
type=friend
context=call-out
secret=123
host=dynamic
nat=no
qualify=yes
canreinvite=no
callgroup=1
pickupgroup=1
call-limit=1
dtmfmode=auto
disallow=all
allow=alaw
allow=ulaw
allow=g729
allow=g723
allow=g722

;Создаем пользователей менеджеров
[100](managers-phones)
callerid="Number 100" <100>
[101](managers-phones)
callerid="Number 101" <101>
[102](managers-phones)
callerid="Number 102" <102>
[103](managers-phones)
callerid="Number 103" <103>
[104](managers-phones)
callerid="Number 104" <104>
[105](managers-phones)
callerid="Number 105" <105>
[106](managers-phones)
callerid="Number 106" <106>
[107](managers-phones)
callerid="Number 107" <107>
[108](managers-phones)
callerid="Number 108" <108>
[109](managers-phones)
callerid="Number 109" <109>
[110](managers-phones)
callerid="Number 110" <110>

;Создаем шаблон для телефонов поддержки
[support-phones](!)
type=friend
context=call-out
secret=456
host=dynamic
nat=no
qualify=yes
canreinvite=no
callgroup=2
pickupgroup=2
call-limit=1
dtmfmode=auto
disallow=all
allow=alaw
allow=ulaw
allow=g729
allow=g723
allow=g722

;Создаем пользователей техподдержки
[111](support-phones)
callerid="Number 111" <111>
[112](support-phones)
callerid="Number 112" <112>
[113](support-phones)
callerid="Number 113" <113>
[114](support-phones)
callerid="Number 114" <114>
[115](support-phones)
callerid="Number 115" <115>
[116](support-phones)
callerid="Number 116" <116>
[117](support-phones)
callerid="Number 117" <117>
[118](support-phones)
callerid="Number 118" <118>
[119](support-phones)
callerid="Number 119" <119>
[120](support-phones)
callerid="Number 120" <120>

;Создаем шаблон для телефонов топов
[top-phones](!)
type=friend
context=call-out
secret=789
host=dynamic
nat=no
qualify=yes
canreinvite=no
callgroup=3
pickupgroup=3
call-limit=1
dtmfmode=auto
disallow=all
allow=alaw
allow=ulaw
allow=g729
allow=g723
allow=g722

;Создаем пользователей топов
[121](top-phones)
callerid="Number 111" <121>
[122](top-phones)
callerid="Number 122" <122>
[123](top-phones)
callerid="Number 123" <123>
[124](top-phones)
callerid="Number 124" <124>
[125](top-phones)
callerid="Number 125" <125>
[126](top-phones)
callerid="Number 126" <126>
[127](top-phones)
callerid="Number 127" <127>
[128](top-phones)
callerid="Number 128" <128>
[129](top-phones)
callerid="Number 129" <129>
[130](top-phones)
callerid="Number 130" <130>

Я немного пояснил комментариями отдельные моменты. Чтобы сократить размер sip.conf, я использую шаблоны групп номеров, где задаю общие настройки для группы. Затем просто создаю пользователей и указываю их принадлежность к группе. Они берут все настройки этой группы. Если вам необходимо будет задать отдельные настройки для какого-то пользователя, как у меня, к примеру, callerid, то вы просто в его разделе указываете эти настройки.

У меня стоит один и тот же пароль для всей группы. Это удобно, если все телефоны стационарные и стоят в офисе, настраивают их только сисадмины. Делать каждому персональный пароль особого смысла нет. Если вам это не нужно, то указывайте персональный пароль для каждого пользователя. Я просто привожу примеры использования тех или иных настроек, но не призываю делать так же, как я. Во многих случаях так делать нельзя. Уточню еще некоторые нюансы.

  • Параметры callgroup и pickupgroup задают группы перехвата звонков. Люди из одной группы могут перехватывать звонки друг друга. Удобно заводить в одну группу людей, сидящих в одной комнате. Так они видят, что человека нет на месте и перехватывают его звонок. Эти параметры можно индивидуально задать для каждого пользователя в отдельности, если разбивка по шаблонам настроек не соответствует реальной рассадке людей в офисе.
  • Параметр callerid можно задать кириллицей, но могут возникнуть проблемы с некоторыми телефонами и точно возникнут проблемы, когда вы будете вести статистику звонков в mysql. Я не смог победить эту проблему с кодировками, поэтому использую только латиницу в этом параметре. Туда можно писать либо должность, либо ФИО человека.
  • call-limit=1 задает количество одновременных соединений на линию. Если у вас один человек = один телефонный аппарат, то разрешать больше одной линии на пользователя нет смысла. Ему будет идти новый звонок в тот момент, как он разговаривает. Конечно, если есть необходимость переключаться между разговорами и ставить кого-то на удержание, то можно делать и больше линий. Но мне кажется, это неудобно. Если ты разговариваешь, пусть звонящий лучше услышит занято и перезвонит.
  • Я всех добавляю в один context. В данном примере у нас будет только один номер телефона на всех. Если у вас их будет несколько, то контекстами можно будет разводить звонки на разные номера. Эту ситуацию я рассмотрю в отдельной статье.

Сохраняем sip.conf. Теперь нам нужно добавить план звонков, для того, чтобы можно было совершать вызовы. Для этого как и с предыдущим конфигурационным файлом, очищаем файл extensions.conf и записываем туда следующую информацию:

[general]
static=yes
writeprotect=no
[globals]
[default]

;Вешаем трубку
[handup-sip]
exten => _X!,1,HangUp()

;Исходящие звонки
[call-out]
;Звонок на внутренний номер
exten => _XXX,1,Dial(SIP/${EXTEN})
include => handup-sip

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

У нас все готово для внутренних звонков через asterisk. Заходим в консоль и перезагружаем его:

# asterisk -r
CLI> reload

Вы увидите некоторые предупреждения и ошибки. Это не страшно, так и должно быть, так как мы многое еще не настроили. Загружаются модули, которым не хватает настроек. Проверим список созданных пользователей с помощью команды в консоли:

CLI> sip show users

sip show users

Видим всех наших пользователей, их пароли и контекст. Список отсортирован не по порядку, не пугайтесь, если не заметите какой-то номер.

Дальше устанавливайте любую софтовую звонилку на компьютер или можете сразу использовать телефон, если он у вас под рукой. С телефонами удобнее, но не всегда они есть. В 3CXPhone задаем следующие настройки подключения к нашей ip атс:

Пример подключения телефона к asterisk

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

Подключение 3CXPhone к астериск

Проверим на сервере список подключенных пиров с помощью команды:

CLI> sip show peers

Должна быть строка с подключенным пиром:

100/100                   192.168.1.100                            D  No         No             59891    OK (104 ms)

Если у вас так же, то все в порядке. Чтобы протестировать звонки, нам нужно подключить двух абонентов. Настраивайте еще один телефон или софтофон. Проверяйте в списке подключенных пиров чтобы было 2 подключения и попробуйте позвонить друг другу. Если вы все сделали правильно, то локальные звонки должны работать.

После звонка в файле /var/log/asterisk/cdr-csv/Master.csv появится запись о совершенном звонке:

"","100","121","call-out","""Number 100"" <100>","SIP/100-00000000","SIP/121-00000001","Dial","SIP/121","2016-04-21 12:32:37","2016-04-21 12:32:42","2016-04-21 12:32:46",9,4,"ANSWERED","DOCUMENTATION","1461241957.0",""

В этом файле будет накапливаться статистика звонков. Позже мы перенесем ее в mysql. Я позвонил с номера 100 на номер 121, там мне ответили. В файле отражены все основные данные этого звонка.

Один небольшой шажок по настройке voip атс asterisk мы сделали. Будем двигаться дальше.

Настройка sip trunk (транка) и добавление номера

Регистрируемся у какого-нибудь sip провайдера и получаем настройки транков для подключения. Как я говорил выше, я буду использовать провайдера zadarma. После регистрации в личном кабинете я вижу свой логин, пароль для подключения и адрес сервера. Там же можно узнать пример настройки подключения для астериска и номера для тестовых звонков:

  • Номер для эхо-теста: 4444.
  • Информация про остаток на счету: 1111
  • Прямой звонок: Москва +7 (495) 777-66-75 и внутренний номер клиента (логин)

Нам этого будет достаточно для полноценного тестирования конфигурации астериска. Добавляем необходимые настройки sip транка, чтобы выполнить его регистрацию. Редактируем sip.conf, добавляем в самый конец нового пира в соответствии с инструкцией провайдера:

[397945]
host=sip.zadarma.com
insecure=invite,port
type=friend
fromdomain=sip.zadarma.com
disallow=all
allow=alaw
dtmfmode=auto
secret=password
defaultuser=397945
trunkname=397945
fromuser=397945
callbackextension=397945
context=call-in
qualify=400
directmedia=no
nat=force_rport,comedia

В данном случае 397945 мой внутренний номер в сервисе, password — пароль. Сохраняем файл и даем команду астеру перечиать его:

CLI> sip reload

Тут же в консоли, если все в порядке, вы получите сообщение:

chan_sip.c:24403 handle_response_peerpoke: Peer '397945' is now Reachable. (55ms / 400ms)

Это означает, что наш пир успешно зарегистрировался у провайдера. Проверить это можно с помощью уже известной команды:

CLI> sip show peers
397945/397945             185.45.152.161                              Auto (No)  No             5060     OK (54 ms)

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

Dial-plan — пример маршрутизации звонков

Начало построения диалплана для маршрутизации звонков мы уже положили, когда настраивали внутренние звонки. Теперь нужно дополнить dial-plan для совершения исходящих и приема входящих звонков. Редактируем extensions.conf и приводим его к следующему виду:

[general]
static=yes
writeprotect=no
[globals]
[default]

;Вешаем трубку
[handup-sip]
exten => _X!,1,HangUp()

;Исходящие звонки
[call-out]
;Звонок на внутренний номер
exten => _XXX,1,Dial(SIP/${EXTEN})
;Звонок на внешний номер
exten => _XXX.,1,Dial(SIP/${EXTEN}@397945)

include => handup-sip

;Входящие звонки
[call-in]
exten => 397945,1,Dial(SIP/100)

Я выложил полную версию файла, а не только то, что добавил. Добавленные строки выделил цветом.

В нашем примере в контекст исходящих звонков мы добавили правило набора любого номера длиннее трех символов через транк 397954. Если в локальных звонках маска экстеншена задается тремя любыми символами, то тут мы в конец добавили точку, которая означает любое количество символов.

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

Контекст [call-in] описывает поведение при входящем звонке. В нашем случае все входящие звонки с транка 397945 будут направляться на номер секретаря 100. К этому контексту мы еще вернемся позже, когда будем настраивать голосовое меню.

Сохраняем dial-plan и перезагружаем астериск единой командой reload, либо отдельно перезагружаем sip и dialplan командами:

CLI> sip reload
CLI> dialplan reload

Теперь можно попробовать позвонить, к примеру, на тестовый номер zadarma — 4444 для эхотеста. Если все получилось, значит вы правильно настроили исходящие звонки. Для проверки входящего звонка, позвоните в Москве на номер +7 (495) 777-66-75 и введите свой добавочный номер в виде логина. Звонок должен переключиться на номер 100. Чтобы это произошло, необходимо, чтобы peer с номером 100 был подключен к астериску.

Я проверил, без проблем дозвонился и по исходящему номеру, и по входящему. В файле Master.csv появилась информация о совершенных звонках:

"","100","4444","call-out","""Number 100"" <100>","SIP/100-00000002","SIP/397945-00000003","Dial","SIP/4444@397945","2016-04-21 14:07:05","2016-04-21 14:07:05","2016-04-21 14:07:34",28,28,"ANSWERED","DOCUMENTATION","1461247625.3",""
"","79998056609","397945","call-in","""79998056609"" <79998056609>","SIP/397945-00000004","SIP/100-00000005","Dial","SIP/100","2016-04-21 14:09:32","2016-04-21 14:09:40","2016-04-21 14:09:44",12,4,"ANSWERED","DOCUMENTATION","1461247772.6",""

После звонков в консоли астера и в логе /var/log/asterisk/messages вы увидите множество ошибок:

res_hep.c: Unable to send packet: Address Family mismatch between source/destination

Чтобы их не было, вам нужно на сервере отключить протокол ipv6.

В таком виде АТС уже вполне работоспособна, можно пользоваться, но есть ряд неудобств. Например, если позвонить на трехзначный номер, которого не существует, или на номер, который не зарегистрирован в данный момент на устройстве, вы просто получите сброс звонка и не поймете, в чем проблема. Для этих событий нужна отдельная обработка. Чтобы не загружать сразу файл конфигурации длинными и непонятными конструкциями, я рассмотрю этот момент ниже, когда буду рассказывать про голосовую почту. Это не критичная настройка, в таком виде все будет замечательно работать, но не так удобно, как могло бы.

Приветствие и голосовое меню (ivr)

Основной функционал asterisk реализован. Будем его расширять. Практически на всех АТС присутствует голосовое меню, которое встречает звонящего. Я рассмотрю настройку самого простого варианта голосового меню, как его еще называют ivr. Позвонив, человек услышит какое-то приветствие, далее ему будет предложено ввести внутренний номер абонента, если он его знает, либо дождаться ответа секретаря.

Для простоты настройки и отладки, поделюсь способом, который использую я. У проекта zadarma есть клиент под андроид — Zadarma SIP. Скачиваете его на телефон и регистрируете еще одну учетную запись в проекте. Логинитесь под ней в телефоне и можете звонить на свой астериск, просто набирая 6-ти значный номер аккаунта, который используете на сервере. Таким образом вы быстро, удобно и бесплатно эмулируете входящие звонки с внешних линий на свой сервер.

Начнем настройку с того, что создадим возможность для записи приветствия. Вы можете записать его где угодно и потом скопировать на сервер astersik. Но можно поступить удобнее — записать прямо с телефонного аппарата приветствие и использовать его в голосовом меню. Чтобы это сделать, необходимо добавить в dialplan в контекст исходящих звонков, в моем примере это [call-out], в самое начало следующую конструкцию:

;Номер для записи звуков, окончание записи #
exten => _35X, 1, NoOp()
exten => _35X, n, Wait(2)
exten => _35X, n, Playback(beep)
exten => _35X, n, Record(/tmp/music${EXTEN:2}:wav)
exten => _35X, n, Wait(1)
exten => _35X, n, Playback(/tmp/music${EXTEN:2})
exten => _35X, n, Wait(2)
exten => _35X, n, Hangup()

Перезагружаем dialplan:

CLI> dialplan reload

Теперь при звонке на любой из номеров 350-359 вы услышите бип, после которого начнется запись всего, что сказано в трубку. Чтобы завершить запись, нажмите #. После этого вы прослушаете то, что было записано. Файл с записью будет сохранен в папку /temp. Если вы позвоните на номер 351, то файл будет иметь имя music1.wav, если на 355, то music5.wav. Можно записать до 10-ти разных вариантов и потом из них выбирать.

Сохраните подходящую запись с именем ivr-main.wav и разместите его в какой-нибудь папке. Я положил в папку /etc/asterisk/ivr. Добавим пример голосового меню в нашу конфигурацию asterisk. Для этого снова открываем extensions.conf и добавляем в него новый контекст [ivr-main] следующего содержания:

[ivr-main]
exten => s,1,Answer()
;Проигрываем приветствие
exten => s,2,Background(/etc/asterisk/ivr/ivr-main)
;Ждем 5 секунд ввода добавочного номера
exten => s,3,WaitExten(5)
;Звоним по введенному добавочному
exten => _XXX,1,Dial(SIP/${EXTEN})
;Если введен не существующий номер, то говорим об этом и отправляем в начало приветствия
exten => _XXX,2,Playback(privacy-incorrect)
exten => _XXX,3,Goto(ivr-main,s,1)
;Если звонящий ничего не вводит, то звоним секретарю
exten => t,1,Dial(SIP/100)

В комментариях я сделал все пояснения. Мы создали контекст для ivr. Теперь его надо добавить в контекст входящих звонков. Для этого изменяем существующий контекст [call-in], заменяя в нем единственную строку на новую:

exten => 397945,1,Goto(ivr-main,s,1)

Перезапускаем диал план и звоним снаружи на внешний номер. Вы должны услышать голосовое приветствие ivr, которое мы только что настроили. После этого этапа ваш файл extensions.conf должен выглядеть примерно так (комментарии вырезал):

[general]
static=yes
writeprotect=no
[globals]
[default]

[handup-sip]
exten => _X!,1,HangUp()

[call-out]
exten => _35X, 1, NoOp()
exten => _35X, n, Wait(2)
exten => _35X, n, Playback(beep)
exten => _35X, n, Record(/tmp/music${EXTEN:2}:wav)
exten => _35X, n, Wait(1)
exten => _35X, n, Playback(/tmp/music${EXTEN:2})
exten => _35X, n, Wait(2)
exten => _35X, n, Hangup()
exten => _XXX,1,Dial(SIP/${EXTEN})
exten => _XXX.,1,Dial(SIP/${EXTEN}@397945)
include => handup-sip

[call-in]
exten => 397945,1,Goto(ivr-main,s,1)

[ivr-main]
exten => s,1,Answer()
exten => s,2,Background(/etc/asterisk/ivr/ivr-main)
exten => s,3,WaitExten(5)
exten => _XXX,1,Dial(SIP/${EXTEN})
exten => _XXX,2,Playback(privacy-incorrect)
exten => _XXX,3,Goto(ivr-main,s,1)
exten => t,1,Dial(SIP/100)

Включаем голосовую почту

Продолжаем наращивать функционал voip атс. В данном разделе опишу настройку голосовой почты в asterisk. Для начала пару слов о том, что это такое. Если адресат звонка долго не отвечает, мы можем предложить звонящему оставить для него голосовое сообщение. Когда получатель вернется на место, он сможет прослушать оставленные ему сообщения. При этом, после записи голосового сообщения, будет отправлено письмо с записью этого сообщения на почтовый адрес получателя.

На практике я не видел, чтобы голосовую почту активно использовали. Но для полноты картины расскажу про нее, возможно вам она пригодится. Открываем файл voicemail.conf на редактирование. Я не трогал настройки по-умолчанию, просто добавляем в секцию [default] ящики голосовой почты для нужных нам сотрудников в следующем виде:

130 => 1234,Number 130,user130@mail.ru
100 => 1234,Number 100,user100@mail.ru
130 внутренний номер абонента
1234 пароль доступа к ящику голосовой почты
user130@mail.ru почтовый адрес, куда будет отправлено записанное голосовое сообщение

Для корректной отправки почтовых сообщений сразу на внешние почтовые ящики необходимо правильно настроить локальный почтовый сервер, либо использовать внешний. Я рекомендую использовать отдельный сервер, наверняка он есть в организации, либо на локальном использовать какой-то публичный с авторизацией по smtp.

В консоли перезапускаем модуль голосовой почты и проверяем пользователей:

CLI> voicemail reload
Reloading voicemail configuration...
asterisk*CLI> voicemail show users
Context Mbox User Zone NewMsg
default 130 Number 121 0
default 100 Number 100 0
other 1234 Company2 User 0
3 voicemail users configured.

Наши два добавленных пользователя и один тестовый остался из дефолтной конфигурации. Его можно удалить. Их вообще два должно быть. Одного я уже удалил, второго забыл.

Это пол дела. Теперь нам нужно добавить голосовую почту в dialplan. Причем в 2 разных места. Я буду использовать номер 500 для звонка в панель управления голосовой почтой. Позвонив на этот номер, пользователь введет свой пароль и сможет управлять голосовыми сообщениями (слушать, удалять, менять настройки). Добавим в контекст для исходящих звонков звонок на этот номер. Добавлять следует сразу за номерами для записи, которые мы ранее создали и перед правилом набора трехзначных номеров.

[call-out]
;Номер для записи звуков, окончание записи #
exten => _35X, 1, NoOp()
exten => _35X, n, Wait(2)
exten => _35X, n, Playback(beep)
exten => _35X, n, Record(/tmp/music${EXTEN:2}:wav)
exten => _35X, n, Wait(1)
exten => _35X, n, Playback(/tmp/music${EXTEN:2})
exten => _35X, n, Wait(2)
exten => _35X, n, Hangup()
;Управление голосовой почтой
exten => 500,1,VoiceMailMain()
;Звонок на внутренний номер
exten => _XXX,1,Dial(SIP/${EXTEN},15)
;Звонок на внешний номер
exten => _XXX.,1,Dial(SIP/${EXTEN}@397945)

Добавленные данные выделил цветом. Обращаю внимание на цифру 15. Ранее этой настройки не было, сейчас я добавил. Она будет означать, что звонок будет длиться 15 секунд. Если за это время никто не ответит, он будет сброшен. До использования голосовой почты, можно было не устанавливать этот параметр, оставить его значение по-умолчанию, оно очень большое, не помню точно сколько по времени. Но сейчас нам нужно при неснятии трубки дольше 15-ти секунд, включать запись голосового сообщения.

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

Пока мы просто добавили номер, куда можно позвонить для управления голосовой почтой. Теперь добавим непосредственно возможность записи голосовых сообщений по событиям. Остановимся на этом пункте поподробнее. Для начала уясним, в каких состояниях может пребывать номер:

  1. Номера вообще не существует на сервере. В нашем случае, к примеру, это любой номер не из диапазона 100-130.
  2. Номер существует, но он не зарегистрирован на АТС, то есть аппарат с этим номером не подключен.
  3. Номер существует, зарегистрирован, но при звонке на него никто не отвечает.
  4. Номер существует, зарегистрирован, но в данный момент занят.

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

Обработка этих событий не такая простая, как кажется на первый взгляд. Я сразу же столкнулся с трудностью следующего характера. С параметром call-limit=1 при звонке на номер, который занят в данный момент, астериск возвращает статус CHANUNAVAIL, что может означать, к примеру, что канал недоступен. На статус занято BUSY это совсем не похоже. Для разрешения этой ситуации я воспользуюсь функцией ChanIsAvail, которая проверяет не статус пира, а статус канала и возвращает значение 2 или 3, когда он занят.

Для различения несуществующих и не подключенных пиров я буду использовать функцию SIPPEER. Если она ничего не возвращает, значит номера не существует, если значение UNKNOWN, значит номер не подключен. С отсутствием ответа какое-то время проще всего. Если пир возвращает статус NOANSWER, включаем голосовую почту. Собираем все статусы в одно место и добавляем голосовую почту.

Для этого в контекст [ivr-main] добавляем новые параметры и приводим его к следующему виду:

[ivr-main]
exten => s,1,Answer()
exten => s,2,Background(/etc/asterisk/ivr/ivr-main)
exten => s,3,WaitExten(5)
exten => _XXX,1,Dial(SIP/${EXTEN},15)
;Задаем переменную для передачи в голосовую почту
exten => _XXX,n,Set(dstNUM=${EXTEN})
;Проверяем статус пира, существует или нет
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status)}" = ""]?num-not-exist,1)
;Проверяем статус пира, подключен или нет
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status):0:2}" = "UN"]?num-not-connected,1)
;Проверяем канал на занятость
exten => _XXX,n,ChanIsAvail(SIP/${EXTEN},s)
;Выводим в лог значение функции ChanIsAvail, нужно только для отладки, можно удалить строку
exten => _XXX,n,NoOp(=========== ChanIsAvail STATUS: ${AVAILSTATUS} ===========)
;Если функция возвращает 2 или 3, значит абонент занят
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 2]?num-BUSY,1)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 3]?num-BUSY,1)
;Обрабатываем остальные статусы
exten => _XXX,n,Goto(num-${DIALSTATUS},1)
;Если номера не существует говорим "Ошибочный номер, попробуйте еще раз"
exten => num-not-exist,1,Wait(2)
exten => num-not-exist,n,Playback(invalid)
;Если номер не подключен, говорим "Набранный вами номер отключен, проверьте номер и повторите попытку
exten => num-not-connected,1,Wait(2)
exten => num-not-connected,n,Playback(ss-noservice)
;Если номер занят, говорим "Занято"
exten => num-BUSY,1,Wait(2)
exten => num-BUSY,n,Playback(vm-isonphone)
;Если номер не отвечает, включаем голосовую почту
exten => num-NOANSWER,1,Wait(2)
exten => num-NOANSWER,n,Voicemail(${dstNUM},u)
;Если еще по какой-то причине будет статус CHANUNAVAIL, говорим, что номер не доступен в данный момент
exten => num-CHANUNAVAIL,1,Wait(2)
exten => num-CHANUNAVAIL,n,Playback(vm-isunavail)
;Если в голосовом меню не выбрали внутренний номер, адресуем звонок секретарю
exten => t,1,Dial(SIP/100,15)

Если вам нужна обработка статусов номеров для внутренних звонков, то скопируйте обработку состояний в контекст [call-out], за исключением последней строки, которая отвечает за звонок секретарю. Полностью контекст внутренних звонков будет выглядеть вот так:

[call-out]
;Номер для записи звуков, окончание записи #
exten => _35X, 1, NoOp()
exten => _35X, n, Wait(2)
exten => _35X, n, Playback(beep)
exten => _35X, n, Record(/tmp/music${EXTEN:2}:wav)
exten => _35X, n, Wait(1)
exten => _35X, n, Playback(/tmp/music${EXTEN:2})
exten => _35X, n, Wait(2)
exten => _35X, n, Hangup()
;Управление голосовой почтой
exten => 500,1,VoiceMailMain()
;Звонок на внутренний номер
exten => _XXX,1,Dial(SIP/${EXTEN},15)
exten => _XXX,n,Set(dstNUM=${EXTEN})
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status)}" = ""]?num-not-exist,1)
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status):0:2}" = "UN"]?num-not-connected,1)
exten => _XXX,n,ChanIsAvail(SIP/${EXTEN},s)
exten => _XXX,n,NoOp(=========== ChanIsAvail STATUS: ${AVAILSTATUS} ===========)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 2]?num-BUSY,1)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 3]?num-BUSY,1)
exten => _XXX,n,Goto(num-${DIALSTATUS},1)
exten => num-not-exist,1,Wait(2)
exten => num-not-exist,n,Playback(invalid)
exten => num-not-connected,1,Wait(2)
exten => num-not-connected,n,Playback(ss-noservice)
exten => num-BUSY,1,Wait(2)
exten => num-BUSY,n,Playback(vm-isonphone)
exten => num-NOANSWER,1,Wait(2)
exten => num-NOANSWER,n,Voicemail(${dstNUM},u)
exten => num-CHANUNAVAIL,1,Wait(2)
exten => num-CHANUNAVAIL,n,Playback(vm-isunavail)
;Звонок на внешний номер
exten => _XXX.,1,Dial(SIP/${EXTEN}@397945)
include => handup-sip

Я во всех звонках установил время ожидания ответа 15 секунд. Если вы считаете, что нужно больше, измените этот параметр.

Обращаю ваше внимание, что в контексте голосового меню я не сделал обработку статусов состояния телефона секретаря, хотя это может быть нужно, если у вас будет один секретарь принимать звонки. Ему и голосовая почта может пригодиться. В следующем пункте я расскажу про случай, когда в офисе работают 2 секретаря и обработкой звонков будет заниматься очередь (queue), поэтому статусы в том виде, как они реализованы здесь будут не нужны. Вы можете использовать любую конфигурацию, которая вам подойдет. Например, использовать очередь, но с одним секретарем в ней. Настраивайте по аналогии, я даю базовый функционал. Все возможные случаи разобрать невозможно.

Перечитывайте диалплан и тестируйте конфигурацию. При звонке абоненту и его неответе, звонящий услышит в трубке сообщение о том, что номер не отвечает и предложение оставить голосовую почту. Если звонивший оставит сообщение, то получатель получит это сообщение по email и сможет его прослушать там, либо позвонить на номер 500, ввести свой номер и пароль, заданные в voicemail.conf и послушать сообщение по телефону.

Я сталкивался с ошибкой, когда у пользователя в настройках отключена голосовая почта, но он все равно получал сообщения. У него мигало оповещение на телефонном аппарате. Нужно было оперативно удалить все оставленные сообщения без прослушивания. Как удалить голосовую почту в астериск я написал в отдельной заметке.

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

Очереди (queues) входящих звонков

С помощью очередей в астериске можно управлять потоком входящих звонков, перераспределяя их по определенным правилам. В нашей конфигурации asterisk мы настроим очередь (queue) для направления звонка двум секретарям одновременно. Кто первый ответит, тот и будет разговаривать со звонящим. Если один секретарь уже разговаривает, новый звонок поступит к другому. Если оба секретаря будут заняты, звонящий будет слушать мелодию и ожидать, пока кто-нибудь не освободится. Как только один из секретарей освободится, звонящего из очереди направит на освободившийся номер.

Номер первого секретаря — 100, второго — 130. Я настраиваю простейшую конфигурацию очереди в астериск для понимания принципа работы. Более сложный вариант настройки это сделать 3 очереди для каждого отдела и в голосовом меню-приветствии сделать возможность позвонить в конкретный отдел. Эту конфигурацию я рассмотрю в отдельной статье, хотя в нем и нет ничего сложного. Делается по аналогии с приведенным примером.

Открываем файл queues.conf и добавляем в самый конец:

[secretary]
strategy = ringall
member => SIP/100
member => SIP/130

Все остальные настройки оставляю по-умолчанию. Параметр strategy может принимать следующие значения:

ringall вызываются все доступные участники до тех пор, пока кто-то из них не ответит на вызов (по умолчанию).
leastrecent Вызывается первый свободный участник, который меньше всего вызывался из этой очереди.
fewestcalls Вызывается первый свободный участник, который обработал наименьшее количество вызовов из данной очереди.
random случайным образом вызывается не занятый участник, обрабатывающий очередь.
rrmemory циклическое распределение с памятью, запоминается последний участник, ответивший на вызов.

Вы можете выбрать наиболее подходящую вам стратегию распределения звонков в очереди. Дальше нужно добавить в extensions.conf в созданный нами ранее контекст с голосовым меню отправку звонка в очередь с секретарями. Для этого меняем строку в [ivr-main]:

exten => t,1,Dial(SIP/100,15)

на новую:

exten => t,1,Queue(secretary,t)

Если раньше при звонке на внешний номер, звонящий не набирал внутренний номер абонента, то через 5 секунд он перенаправлялся к секретарю с номером 100. Теперь он будет отправляться в очередь secretary, в которую мы завели 2 номера — 100 и 130. Можно добавить и больше номеров, если есть необходимость.

Перечитываем полностью конфигурацию asterisk:

CLI> reload

Состояние созданной очереди:

CLI> queue show secretary
secretary has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s
Members:
SIP/100 (ringinuse enabled) (Not in use) has taken no calls yet
SIP/130 (ringinuse enabled) (Not in use) has taken no calls yet
No Callers

Теперь можете позвонить на внешний номер и дождаться перенаправления на секретаря. Зазвонят оба аппарата. Если оба заняты, звонок будет висеть в очереди и ждать освобождения. После звонка статистика очереди изменится:

CLI> queue show secretary
secretary has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 2s talktime), W:0, C:1, A:1, SL:0.0% within 0s
Members:
SIP/100 (ringinuse enabled) (Not in use) has taken 1 calls (last was 63 secs ago)
SIP/130 (ringinuse enabled) (Not in use) has taken no calls yet
No Callers

Вот так легко организовать простую queue (очередь) в asterisk. Более сложные примеры я буду рассматривать в отдельных статьях.

Учет и просмотр статистики звонков (cdr viewer)

Важной и нужной возможностью современной АТС на базе asterisk является сбор и просмотр статистики звонков. По умолчанию, астериск ведет статистику в файле /var/log/asterisk/cdr-csv/Master.csv. Разобрать этот файл и передать куда-то в обработку не очень сложно, если у вас есть что-то или кто-то, кто способен написать на каком-нибудь языке программирования обработку.

Мы будем использовать готовые бесплатные инструменты для просмотра статистики звонков. Все необходимое для этого мы установили в самом начале. Перенесем сбор статистики в mysql базу. Для этого запускаем mariadb сервер, добавляем в автозагрузку и устанавливаем пароль администратора:

# systemctl start mariadb
# systemctl enable mariadb.service
# /usr/bin/mysql_secure_installation

Подключаемся к mysql и создаем пользователя и базу данных:

# mysql -uroot -p
MariaDB [(none)]> create database asterisk;
MariaDB [(none)]> use asterisk;
MariaDB [asterisk]> CREATE TABLE `cdr` (   `id` int(9) unsigned NOT NULL auto_increment,   `calldate` datetime NOT NULL default '0000-00-00 00:00:00',   `clid` varchar(80) NOT NULL default '',   `src` varchar(80) NOT NULL default '',   `dst` varchar(80) NOT NULL default '',   `dcontext` varchar(80) NOT NULL default '',   `channel` varchar(80) NOT NULL default '',   `dstchannel` varchar(80) NOT NULL default '',   `lastapp` varchar(80) NOT NULL default '',   `lastdata` varchar(80) NOT NULL default '',   `duration` int(11) NOT NULL default '0',   `billsec` int(11) NOT NULL default '0',   `disposition` varchar(45) NOT NULL default '',   `amaflags` int(11) NOT NULL default '0',   `accountcode` varchar(20) NOT NULL default '',   `uniqueid` varchar(32) NOT NULL default '',   `userfield` varchar(255) NOT NULL default '',   PRIMARY KEY  (`id`),   KEY `calldate` (`calldate`),   KEY `accountcode` (`accountcode`),   KEY `uniqueid` (`uniqueid`),   KEY `dst` (`dst`),   KEY `src` (`src`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
MariaDB [asterisk]> grant all on asterisk.* to 'asterisk_user'@'localhost' identified by '12345678';
asterisk имя базы данных
asterisk_user пользователь базы данных
12345678 пароль пользователя бд

Устанавливаем odbc коннекторы:

# yum install -y mysql-connector-odbc.x86_64 unixODBC-devel.x86_64

Редактируем файлы конфигурации. Добавляем в самый конец /etc/asterisk/res_odbc.conf:

[asterisk]
enabled => yes
dsn => MySQL-asterisk
username => asterisk_user
password => 12345678

В конец файла /etc/asterisk/cdr_adaptive_odbc.conf:

[cdr_adaptive_connection]
connection=asterisk
table=cdr
alias start => calldate

Создаем файл /etc/odbc.ini следующего содержания:

[MySQL-asterisk]
Description = MySQL Asterisk database
Driver = MySQL
Server = localhost
User = asterisk_user
Password = 12345678
Socket = /var/lib/mysql/mysql.sock
Database = asterisk

Редактируем файл /etc/odbcinst.ini. Я его не трогал, оставил по-умолчанию, только в самый конец секции [MySQL] добавил две недостающие строки. Я не разбирался нужны они или нет, просто подсмотрел в другой инструкции. Вот как этот файл выглядит у меня:

[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/libmyodbc5.so
Setup = /usr/lib/libodbcmyS.so
Driver64 = /usr/lib64/libmyodbc5.so
Setup64 = /usr/lib64/libodbcmyS.so
FileUsage = 1
CPTimeout =
CPReuse =

Настроим использование нашего часового пояса в записях cdr. По-умолчанию там стоит часовой пояс GTM. Для этого в файле /etc/asterisk/cdr.conf указываем параметр:

usegmtime=no

После этого перезапускаем астериск:

# service asterisk restart

Совершаем звонок и проверяем таблицу. Для удобства дальнейшей проверки и настройки, я запустил httpd и настроил phpmyadmin. Они должны были установиться в самом начале. Запускаем httpd и добавляем в автозагрузку:

# systemctl start httpd
# systemctl enable httpd

С phpmyadmin сами разберитесь, в интернете море инструкций, либо воспользуйтесь моей по установке и настройке phpmyadmin. Теперь астериск сохраняет статистику звонков в mysql базу asterisk в таблицу cdr. Дальше нам надо настроить какую-нибудь web панель для просмотра этой статистики. Я решил сразу установить панель, которая позволяет не только смотреть статистику, но прослушивать записанные разговоры. Поэтому дальнейшая настройка панели просмотра статистики переходит в следующий раздел, в котором я расскажу, как записывать звонки.

Запись (record) разговоров

Запись разговоров в asterisk настраивается относительно не сложно. Буквально нужно добавить несколько строк в dialplan. Но мы сразу сделаем более расширенную настройку. Мы будем не просто записывать все разговоры, но станем хранить информацию о звонках в mysql, чтобы их можно было прослушивать через удобную web панель просмотра статистики.

Хранить записи будем в mp3, потому нам понадобится утилита lame, для конвертации файлов из формата wav в mp3. Скачаем ее и установим.

# cd /usr/src
# wget http://sourceforge.net/projects/lame/files/lame/3.98.4/lame-3.98.4.tar.gz
# tar zxvf lame-3.*
# cd lame-3.*
# ./configure
# make
# make install

В качестве web панели я буду использовать Asterisk-CDR-Viewer-Mod. Очень простая и функциональная штука. Настраивается легко, пользоваться удобно. Скачиваем исходники с github:

# cd /usr/src
# wget https://github.com/prog-it/Asterisk-CDR-Viewer-Mod/tarball/master 
# tar xzvf master

Копируем содержимое папки /usr/src/master в корень web сервера. Если вам нужно, можете в отдельную папку положить. У меня обычно на сервере с астериском больше ничего нет, так что сойдет и корень — /var/www/html

В папке docs подробная инструкция по настройке. Все дальнейшие действия делаются в соответствии с ней. Исправляются только некоторые особенности данной версии системы. Нам необходимо добавить дополнительное поле в таблицу cdr для хранения имени файла. Для этого либо в консоли mysql, либо через phpmyadmin выполните код:

alter table  `cdr` add column `filename` varchar(120) DEFAULT 'none' after `userfield`;

Редактируем файл /etc/asterisk/cdr_mysql.conf, добавляя в самый конец 2 строки:

alias realdst => realdst
alias filename => filename

Дальше редактируем диалплан. Открываем /etc/asterisk/extensions.conf и добавляем в секцию globals переменную, соответствующую папке, где будут храниться записи разговоров.

[globals]
DIR_RECORDS=/mnt/calls/

Добавляем макрос для записи перед контекстами звонков:

[macro-recording]
exten => s,1,Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(monopt=nice -n 19 /usr/local/bin/lame -b 32 --silent "${DIR_RECORDS}${fname}.wav" "${DIR_RECORDS}${fname}.mp3" && rm -f "${DIR_RECORDS}${fname}.wav" && chmod o+r "${DIR_RECORDS}${fname}.mp3");
exten => s,n,Set(CDR(filename)=${fname}.mp3);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b,${monopt});
exten => s,n(no),Verbose(Exit record);

И редактируем контексты входящих и исходящих разговоров, добавляя туда макрос на запись. Он идет самым первым, перед набором номера. Вот так у меня выглядит контекст локальных звонков и входящих через ivr меню с учетом всех сделанных ранее настроек:

[call-out]
;Номер для записи звуков, окончание записи #
exten => _35X, 1, NoOp()
exten => _35X, n, Wait(2)
exten => _35X, n, Playback(beep)
exten => _35X, n, Record(/tmp/music${EXTEN:2}:wav)
exten => _35X, n, Wait(1)
exten => _35X, n, Playback(/tmp/music${EXTEN:2})
exten => _35X, n, Wait(2)
exten => _35X, n, Hangup()
;Управление голосовой почтой
exten => 500,1,VoiceMailMain()
;Звонок на внутренний номер
exten => _XXX,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _XXX,n,Dial(SIP/${EXTEN},10)
exten => _XXX,n,Set(dstNUM=${EXTEN})
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status)}" = ""]?num-not-exist,1)
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status):0:2}" = "UN"]?num-not-connected,1)
exten => _XXX,n,ChanIsAvail(SIP/${EXTEN},s)
exten => _XXX,n,NoOp(=========== ChanIsAvail STATUS: ${AVAILSTATUS} ===========)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 2]?num-BUSY,1)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 3]?num-BUSY,1)
exten => _XXX,n,Goto(num-${DIALSTATUS},1)
exten => num-not-exist,1,Wait(2)
exten => num-not-exist,n,Playback(invalid)
exten => num-not-connected,1,Wait(2)
exten => num-not-connected,n,Playback(ss-noservice)
exten => num-BUSY,1,Wait(2)
exten => num-BUSY,n,Playback(vm-isonphone)
exten => num-NOANSWER,1,Wait(2)
exten => num-NOANSWER,n,Voicemail(${dstNUM},u)
exten => num-CHANUNAVAIL,1,Wait(2)
exten => num-CHANUNAVAIL,n,Playback(vm-isunavail)
;Звонок на внешний номер
exten => _XXX.,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _XXX.,n,Dial(SIP/${EXTEN}@397945)
include => handup-sip

[ivr-main]
exten => s,1,Answer()
exten => s,2,Background(/etc/asterisk/ivr/ivr-main)
exten => s,3,WaitExten(5)
exten => _XXX,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _XXX,n,Dial(SIP/${EXTEN},10)
exten => _XXX,n,Set(dstNUM=${EXTEN})
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status)}" = ""]?num-not-exist,1)
exten => _XXX,n,GotoIf($["${SIPPEER(${EXTEN},status):0:2}" = "UN"]?num-not-connected,1)
exten => _XXX,n,ChanIsAvail(SIP/${EXTEN},s)
exten => _XXX,n,NoOp(=========== ChanIsAvail STATUS: ${AVAILSTATUS} ===========)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 2]?num-BUSY,1)
exten => _XXX,n,GoToIf($[${AVAILSTATUS} = 3]?num-BUSY,1)
exten => _XXX,n,Goto(num-${DIALSTATUS},1)
exten => num-not-exist,1,Wait(2)
exten => num-not-exist,n,Playback(invalid)
exten => num-not-connected,1,Wait(2)
exten => num-not-connected,n,Playback(ss-noservice)
exten => num-BUSY,1,Wait(2)
exten => num-BUSY,n,Playback(vm-isonphone)
exten => num-NOANSWER,1,Wait(2)
exten => num-NOANSWER,n,Voicemail(${dstNUM},u)
exten => num-CHANUNAVAIL,1,Wait(2)
exten => num-CHANUNAVAIL,n,Playback(vm-isunavail)
exten => t,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => t,n,Queue(secretary,t)

Перезапускаем астериск для применения всех настроек:

# service asterisk restart

Осталось только указать настройки подключения к базе данных cdr viewer. Эти настройки находятся в файле inc/config.inc.php. Задаем там следующие параметры:

Mysql
$db_type = 'mysql';
$db_host = 'localhost';
$db_port = '3306';
$db_user = 'asterisk_user';
$db_pass = '12345678';
$db_name = 'asterisk';
$db_table_name = 'cdr';

$system_storage_format = 5;
$system_monitor_dir = '/mnt/calls';

Остальные параметры я оставил без изменений. Можно звонить и тестировать запись разговоров, просмотр статистики через Asterisk CDR Viewer Mod. Все записанные файлы складываются в одну папку /mnt/calls. В readme.txt описан пример, как настроить сортировку записей по папкам с датами. Если вам это нужно, сделайте, ничего сложного нет, все рассказано подробно. В web панель можно зайти просто набрав в браузере ip адрес сервера, если скрипты положили в корень веб сервера.

Просмотр статистики и записей звонков

Музыка на ожидании (on hold)

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

За конфигурацию music on hold отвечает соответствующий файл настроек — /etc/asterisk/musiconhold.conf. Изначально он выглядит так:

[general]
[default]
mode=files
directory=moh

Директория указана как moh, полный ее путь /var/lib/asterisk/moh, мелодии проигрываются отсюда. Я не буду менять настройки по-умолчанию. Добавим еще один класс музыки и укажем его в свойствах очереди, где будем ее проигрывать.

Я привожу пример использования. Если у вас везде будет одна и та же мелодия, то отредактируйте канал default. Так вам не придется каждый раз указывать добавленный канал.

Копируем любым способом mp3 файл на сервер в домашнюю директорию root. Создаем директорию /var/lib/asterisk/mohmp3 и кодируем в нее мелодию из mp3 в wav:

# mkdir  /var/lib/asterisk/mohmp3
# lame --decode /root/music.mp3 /var/lib/asterisk/mohmp3/music.wav

Добавляем новый класс в musiconhold.conf в самый конец:

[mp3]
mode=files
directory=mohmp3

Теперь добавим эту мелодию в свойства очереди. Для этого в описание очереди добавьте новый параметр:

[secretary]
music = mp3
strategy = ringall
member => SIP/100
member => SIP/130

Теперь нужно перечитать настройки очереди и мелодии. Проще перезапустить сам астериск:

# service asterisk restart

Можно звонить на внешний номер и ждать попадания в очередь. Вы должны услышать добавленную мелодию во время ожидания.

Чтобы добавить эту мелодию вместо длинного гудка, необходимо отредактировать dialplan, добавив новый параметр в правило набора. Если добавляете свой класс музыки, то указываете его в свойствах:

exten => _XXX,1,Dial(SIP/${EXTEN},15,m(mp3))

Если используете музыку по-умолчанию, то достаточно написать вот так:

exten => _XXX,1,Dial(SIP/${EXTEN},15,m)

Для отладки музыки на ожидании, я рекомендую добавить в dialplan в контекст локальных звонков такую конструкцию:

exten => 336,1,Answer
exten => 336,2,MusicOnHold()

336 — любой не занятый реальным пиром номер. При звонке на этот номер, вы услышите заданную дефолтную мелодию в соответствии с настройками в файле musiconhold.conf. Для проигрывания не дефолтного класса, укажите его имя в скобках. Так вы можете прослушать как звучат ваши мелодии, протестировать порядок проигрывания и т.д.

Не забывайте перезагружать диалплан после редактирования. На этом настройка music on hold закончена. Можете добавлять разные мелодии и использовать в необходимых местах диалплана или очередях.

Настройка конференций

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

Создаем конфигурацию конференции. Для этого в файл confbridge.conf добавляем в самый конец:

[confer]
type=bridge
max_members=20
mixing_interval=10
internal_sample_rate=auto
record_conference=yes

В контекст исходящих звонков [call-out] добавляем в самое начало:

exten => 999,1,Answer()
exten => 999,n,ConfBridge(1,confer)

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

Как выполнять переводы и переадресации звонков я расскажу ниже.

Перевод, перехват, переадресация звонка

Рассмотрим несколько необходимых функций и возможностей телефонной станции asterisk. Начнем с перевода звонка. Как перевести звонок на другого абонента? По-умолчанию в астериске для трансфера звонка предусмотрена клавиша #. Посмотреть, так ли это в вашей конфигурации, введите в консоли астера команду:

CLI> features show
Builtin Feature               Default Current
---------------               ------- -------
Pickup                           *8     *8
Blind Transfer                    #      #
Attended Transfer
One Touch Monitor
Disconnect Call                   *      *
Park Call

Во время разговора нужно нажать # и набрать номер, куда вы хотите перевести звонок. Для того, чтобы трансфер состоялся, он должен быть разрешен в диалплане в команде Dial следующим образом:

exten => _XXX,n,Dial(SIP/${EXTEN},15,Tt)
T дать возможность звонящему (вызывающему) абоненту совершать перевод звонка на другой номер.
t дать возможность вызываемому абоненту сделать перевод звонка на другой номер

В предыдущих примерах я не указывал этот параметр. Сейчас пришло время рассказать о нем и добавить во все участки диалплана, если вам необходимо осуществлять перевод звонков в asterisk.

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

Кнопка перевода звонка

С включенным по-умолчанию Blind Transfer есть проблемы. Например, вы перенаправляете звонок на другой номер, а он не ответил или у него занято. Входящий вызов сбрасывается. В астериске есть другой режим перевода звонка, он называется Attended Transfer, по-умолчанию он выключен. Работает он более изящно. Сначала вы звоните тому, куда хотите перевести номер, разговариваете с ним, убеждаетесь, что он доступен и готов принять звонок. Только после этого переводите звонок на этого абонента. Чтобы включить такое перенаправление вызова, нужно раскомментировать в features.conf строку:

atxfer => *2

Горячую клавишу можно переназначить на любую другую. На этом о переводе звонка в астериске все.

Теперь поговорим о перехвате звонка. Хотя говорить тут особо нечего. В asteerisk перехват работает из коробки и не требует никаких настроек. Для того, чтобы перехватить звонок, нужно снять трубку и нажать комбинацию *8. Комбинация задается в том же файле, что и перехват — features.conf. Перехватывать звонки могут только абоненты в одной группе. Это задается в свойствах пользователя, я об этом рассказывал в самом начале, когда мы создавали sip аккаунты. Напомню, что речь идет о параметрах callgroup и pickupgroup.

Разберем теперь переадресацию звонка на какой-то внешний номер, например, мобильный телефон. Многие телефоны имеют встроенный функционал по перенаправлению звонка. Читаете инструкцию к телефону, смотрите, можно ли на нем установить переадресацию и как, и делаете. Работает это только если ваш телефон подключен к АТС. Он принимает звонок и сам его переадресовывает на указанный номер. Это самый простой и быстрый вариант автоматической переадресации звонка на внешний номер.

Рассмотрим другой случай переадресации на мобильный телефон. Допустим, у нас есть номер 115, который вообще отсутствует в офисе, у него нет стационарного телефона. Нам нужно, чтобы при звонке на этот номер, вызов переадресовывался на внешний номер, а конкретно на мобильный сотрудника. Для этого в dialplan нужно добавить следующую строку:

exten => 115,n,Dial(SIP/89151234567@397945)

Если вы хотите, чтобы переадресация работала только при звонках с внутренних номеров офиса, то добавить эту строку нужно в контекст [call-out] перед общим правилом набора на внутренние номера:

exten => 115,n,Dial(SIP/89151234567@397945)
exten => _XXX,n,Dial(SIP/${EXTEN},15,Tt)

Для того, чтобы переадресация на внешний номер работала и для звонков из вне, правило перенаправления на мобильный нужно поставить в контекст с голосовым приветствием [ivr-main]. Ставим туда же, перед строкой набора на внутренние номера:

exten => 115,n,Dial(SIP/89151234567@397945)
exten => _XXX,n,Dial(SIP/${EXTEN},15,Tt)

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

Защита asterisk с помощью fail2ban

Если ваш астериск имеет внешний ip адрес, либо на него сделан проброс портов с внешнего ip, то необходимо обеспечить защиту от перебора учеток и прочих множественных подключений. Организуем защиту с помощью известного и популярного средства fail2ban. Сделать это не сложно, fail2ban поддерживает astersik из коробки. Достаточно просто установить его и активировать некоторые настройки.

Устанавливаем fail2ban на сервер с астериском:

# yum install -y fail2ban

Включаем запись в лог файл событий типа security. Для этого открываем файл /etc/asterisk/logger.conf и раскомментируем строку:

security => security

Перечитываем настройки хранения логов:

# asterisk -x "logger reload"

В папке /var/log/asterisk появился новый файл security. Его записи мы будем передавать в fail2ban для анализа. Открываем файл /etc/fail2ban/jail.conf, ищем там секцию [asterisk] и меняем путь к логфайлу и добавляем строку активации джейла:

logpath  = /var/log/asterisk/security
enabled  = true

Запускаем fail2ban и добавляем в автозапуск:

# systemctl start fail2ban
# systemctl enable fail2ban

Чтобы fail2ban работал, у вас должен быть запущен и настроен iptables. Отмечу также, что по-умолчанию fail2ban в centos 7 использует команды firewalld. Если вы его отключили и используете голые iptables, то вам необходимо удалить файл /etc/fail2ban/jail.d/00-firewalld.conf и перезапустить fail2ban. Если этого не сделать, работать он не будет.

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

Заключение

Время подвести итог проделанной работы. На всякий случай приведу полный конфиг основного файла, с которым мы работали — extensions.conf. Я писал статью почти 2 месяца, что-то добавляя, проверяя, редактируя. Она актуальна полностью на момент написания. Можно простым копипастом переносить конфигурацию и все заработает. Я проверил перед публикацией. Со временем что-то может измениться, но не думаю, что сильно. Синтаксис конфигурационных файлов почти не меняется в разных версиях астера, это позволяет без проблем переносить настройки между версиями, и тем более между операционными системами.

Я планирую раскрыть более широко затронутую тему. У меня есть примеры интересных и полезных конфигураций. По мере возможности буду писать новые статьи по серверу телефонии. На сегодня у меня все, хороших вам настроек  🙂

Обсуждение статьи на форумессылка открывается в новой вкладке.


Помогла статья? Есть возможность отблагодарить автора

109 комментариев

  1. Отличная статья, Большое Спасибо!!!
    Были некоторые моменты неясные, дошло ))

  2. Александр

    Статья правда хорошая, только вот столкнулся с проблемой:
    Сделал точно всё по приводимым в статье инструкциям, но входящие звонки с внешнего транка — не идут (Ошибка 486 : Busy Here, то бишь занято). Использовал сервис Zadarma. Внутренние звонки работают, исходящие наружу то же, а вот обратно нет. Пробовал отключать iptables — не помогло. В чём может быть проблема?

    • Может быть сам zadarma глючит? Либо с фаерволом проблемы. Если он отключен, то проброс портов надо проверять, если он есть. Отсутствие входящих с нормальными исходящими очень похоже на не проброшенный порт 5060.

      • Александр

        Имеется ввиду проброс порта на роутере?

        • Да. У меня такое было. Если неправильно проброшен порт, то исходящие звонки совершать можно, их инициирует сам астериск, если у него есть доступ в интернет, то он нормально позвонит. А вот входящие не проходят, соединение инициирует провайдер. Возможно он не может достучаться до сервера и выдает статус Занято.

  3. Александр

    ОК

  4. Александр

    Настройка в menuselect:
    # make menuselect
    пункт: Core Sound Packages: Выбираем русские звуки RU-WAV,
    — Оные отсутствуют. Имются только EN-WAV.
    Почему? Всё делалось по последовательно по пунктам статьи. Русская озвучка потом будет работать?
    Тема добавлена в форум.

    • Можно будет вручную скачать и установить. Возможно состав пакета установки изменился. Когда я последний раз настраивал астериск русский язык был по-умолчанию.

  5. Огромное спасибо за статью! Признаться я полный ноль не только в Asterisk но и VoIP, но хотел бы задать интересующий меня вопрос (надеюсь кто то ответит). Этот экстеншен: exten => _XXX.,1,Dial(SIP/${EXTEN}@397945) предназначен для звонков на внешние номера. Автор говорит что благодаря этому можно звонит на городские номера. Работает ли это для звонков на другие сервера Asterisk? Т.е. абонент набирает 6-и значный внутренний номер в сервисе zadarma и попадает на другой Asterisk сервер, правильно ли я понял?

  6. Все хорошо, кроме одного момента — вылезла ошибка с кодеками.
    [Nov 14 17:38:43] WARNING[28879][C-00000000]: translate.c:481 ast_translator_build_path: No translator path: (starting codec is not valid)
    [Nov 14 17:38:43] WARNING[28879][C-00000000]: translate.c:481 ast_translator_build_path: No translator path: (starting codec is not valid)
    [Nov 14 17:38:43] WARNING[28879][C-00000000]: translate.c:481 ast_translator_build_path: No translator path: (starting codec is not valid)
    [Nov 14 17:38:43] WARNING[28879][C-00000000]: translate.c:481 ast_translator_build_path: No translator path: (starting codec is not valid)
    Как исправить еще не доковырял.

    Плюс ко всему необходимо в modules.conf добавить
    MACRO & MIXMONITOR если их нет в арр

    • можно попросить ваш modules.conf, чтобы понять, что у меня не подгружено.

      • Это был тестовый стенд, его уже нет. Но файл modules.conf я не трогал вообще. Какой он был после установки, такой и оставался.

        • Разобрался.
          Таки нехватка кодека. Астериск ставил без установки примеров и т.д., файл modules.conf был пустой. Решилось загрузкой module load codec_alaw.so
          Теперь осталось разобраться с тем, что в панели отображает звонки, но вместо файла записи — знак отсутствия файла.

  7. Разобрался и с отсутствием файлов… в config.inc.php устанавливается размер файла, с которого файл не считается отсутствующим. Поэтому мои коротенькие тестовые звонки и не отображались в панели.
    Спасибо огромное за статью. Весьма подробно, а ко всему еще и позволило не только тупо накопипастить, но еще и изучить некоторые вопросы самостоятельно, поняв смысл написанного выше.

  8. Владимир

    Здравствуйте я новичек

    В Asteriske хочу блокировать все номера с префиксом 001xxxxx, как мне это сделать или это нужно с делать с помощью iptables?

    заранее спасибо

    • Что значит блокировать номера? Запретить на них звонить, или запретить с них вызовы?

    • и советую почитать Asterisk: The Future of Telephony.Хотя бы 5 главу — Основы диаплана. Книга конечно старенькая — последняя редакция 2009 года, если не ошибаюсь, но десяток страниц даст вам много пищи для размышлений и понимания того, что описано в статье. Написано конечно хорошо, но тупо копипастить не годится — вы должны понимать, что делаете. Тогда и ошибок не будет. И не забывайте, что это деньги. Были случаи, когда неправильные настройки и защита астериска приводили к многотысячным счетам за телефонию.
      Судя по вашему вопросу по iptables — почитайте обязательно по защите сервера.

  9. Владимир

    запретить с них вызовы

    • exten => _8XX/_001xxxxx,1,Hangup()

      такой конструкцией отбей. первое номер на который звонят (в данном случае шаблон), второе номер с которого звонят (тоже шаблон) — отбить, или любое действие какое ты хочешь.
      В данном примере при звонке на номера с 800 по 899 с номеров 001(00000-99999) будет положена трубка. Если я не так тебя понял, то шаблоны можно поменять местами.
      Причем тут iptables вообще непонятно — он нужен только для разруливания кто может к твоему астериску получить доступ.

  10. точно так же все настроил но почему то выход в город только через +7 или 7, как 7ку заменить на 8ку?

    • Это от оператора связи зависит. Заменить 7 на 8 можно в диалплане. В интернете без проблем можно найти пример, у меня нет под рукой.

  11. Владимир

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

  12. в конструкции
    exten => t,1,Macro(recording,${CALLERID(num)},${EXTEN})
    exten => t,n,Queue(secretary,t)
    есть один недостаток.
    Если в очереди 2 телефона секретаря, то в базу данных будет писаться два разговора.
    Для примера из статьи 100 и 130. Если трубку возьмет 100, то 130 будет отображаться в cdr viewer не отвеченным. Если два телефона — в принципе не проблема… если в очереди 10-20-30 тел, то при одном звонке — 9 лишних записей — немножко накладно по использованию ресурсов. Как обойти данную проблему еще не нашел решения. Если у кого-то есть наработки — намекните.

    • Да, любопытно. Я не сталкивался с этим. Я стараюсь запись не включать, там, где она явна не нужна. Не стоит забывать про УК РФ, Статья 138. Без ведома людей, записывать их нельзя. Нужно предупреждать об этом и сотрудников компании, и их абонентов.

    • Максрос использовать непосредственно в очереди как вариант. т.е. в queue.conf непосредственно

  13. Александр

    Отличная статья. Спасибо.
    в контексте [ivr-main]:
    ;Если введен не существующий номер, то говорим об этом и отправляем в начало приветствия
    exten => _XXX,2,Playback(privacy-incorrect)
    exten => _XXX,3,Goto(ivr-main,s,1)
    Есть специальный экстеншн «i» — Вызывается, при попытке вызова неизвестного екстеншена.

    • Спасибо за дополнение. Я знаю про него, иногда использую. Для остальных, речь идет вот о чем. Просто после:
      exten => t,1,Dial(SIP/100)
      можно добавить например вот так:
      exten => i,1,Dial(SIP/100).
      И звонок уйдет на номер 100, если ввели неправильно внутренний номер.
      Так даже более правильно будет, чем то, что у меня сейчас, но я почему-то в статье сделал таким образом. Не помню почему.

      • И почти правильно делали, exten => i,1,Dial(SIP/100). это не отработает и будет сброс звонка. Эта проблема ранее не однократно обсуждалась. В данном случае нужно выпольнить по ошибке переход в определенный контекст, и из него уже выполнить набор абонента.

  14. Доброго дня. А можете подсказать откуда же запрашивается авторизация у свеже-установленного модуля статистики ? все перекопал. авторизацию сам не настраивал…

  15. Вопрос снимается) переименовал каталог и авторизация ушла:) чтото в апачах и /var/www/html допилить забыл.

  16. Александр

    Еще по записи звуков хотел бы поправить:
    1. Не понятно, зачем нужна первая строка? NoOp() в данном случае ничего не делает, вместо этой команды логичнее поставить Answer()
    2. Перед командой Record() нет смысла в Playback(beep). Команда Record, сгенерирует beep на канале, перед началом записи

    • Спасибо за содержательные замечания. Я проверю информацию и исправлю статью, как будет возможность.

    • NoOp() — Эта команда выводит содержимое переменной без ее выполнения, то есть, Вы можете написать так:
      NoOp(${CALLERID(num)}) — и при просмотре в консоли лога Астериска будет выведено содержимое этой переменной
      NoOp(${EXTEN}) — тоже самое, вы в консоли увидите вызываемый экстеншен. Для отладки в основном используется

  17. Zerox, благодарю за статью! Довольно доходчиво и понятно описаны основы. После прочтения за пару часов поднял тестовый астер, и что самое главное, я понял , что я сделал, и как это работает. (Я новичок, который никогда не занимался телефонией в принципе).
    Спасибо Вам огромное!

    • Спасибо за отзыв. Я рад, что у меня получилось задуманное. Целью было написать наиболее понятным для новичка языком, как настроить функциональную и законченную систему телефонии на базе asterisk.

  18. iptables -t nat -A PREROUTING -p udp —dst $WAN_IP —dport 5060 -j DNAT —to 192.168.1.25:5060
    iptables -t nat -A PREROUTING -p udp —dst $WAN_IP —dport 10000:20000 -j DNAT —to 192.168.1.25

    И влетаем на самые распространенные грабли с астериском за Nat, а потом курим почему голос ходит в одну сторону, не? 🙂

    • А в чем тут проблема? Сейчас нет времени вникать в суть, но у меня с натом не было каких-то особых проблем с iptables.

      • Данный проброс дает возможность подключиться SIP клиенту из вне. Далее он подключился со своего IP(SIP_IP) к Вашему WAN_IP. Тут проблем нет.
        При звонке будет попытка установить соединение SIP_IP к WAN_IP это пройдет на ура. А в обратную сторону не пойдет потому что астериск будет отправлять «голос» на SIP_IP в ответ.
        А так проблема не в Nat. А с самим RTP.

        • ну кроме случаев если у вас SIP_IP это внешний белый IP. В таком случае проблем не будет

        • Вечером приведу примеры работающих серверов с реальными примерами iptables, сравним.

          • Да, я посмотрел потом на конфиг астера что Вы приводите и там стоит canreinvite=no, он как раз решает проблему. Правда он устарел еще в 11м астериске. Теперь используется Directmedia

  19. Только не пойму зашем вам pj если у вас только SIP, и зачем у вас в конфиге g729 коммерческий кодек которого, если мне склероз не изменяет, его в обычной поставке астериска нет 🙂

  20. А так вы молодец! Мне бы такую статью года 2 назад в руки! В общем всяческие похвалы!

  21. Добавить стоить в sip.conf alwaysauthreject=yes, это при попытках брутфорса будет показывать всегда 401 Не авторизован. В связке с fail2ban который все же имеет ряд дырочек будет плюсом.

  22. Камрад! Замечательная статья, настроил нужное по ней, но остались ошибки. Часть ошибок я нагуглил, но часть осталась, не могу сообразить, как исправить. Не сталкивались с такими ошибками:

    [Feb 8 13:52:59] WARNING[9416]: res_odbc.c:526 load_odbc_config: The ‘pooling’, ‘shared_connections’, ‘limit’, and ‘idlecheck’ options were replaced by ‘max_connections’. See res_odbc.conf.sample.
    [Feb 8 13:52:59] WARNING[9416]: res_odbc.c:526 load_odbc_config: The ‘pooling’, ‘shared_connections’, ‘limit’, and ‘idlecheck’ options were replaced by ‘max_connections’. See res_odbc.conf.sample.
    [Feb 8 13:52:59] NOTICE[9416]: res_odbc.c:617 load_odbc_config: Registered ODBC class ‘asterisk’ dsn->[MySQL-asterisk]
    [Feb 8 13:52:59] NOTICE[9417]: sorcery.c:1409 sorcery_object_load: Type ‘system’ is not reloadable, maintaining previous values
    [Feb 8 13:52:59] WARNING[9416]: res_phoneprov.c:1231 get_defaults: Unable to find a valid server address or name.
    [Feb 8 13:52:59] ERROR[9416]: ari/config.c:314 process_config: No configured users for ARI
    [Feb 8 13:52:59] NOTICE[9416]: pbx_lua.c:1640 load_or_reload_lua_stuff: Lua PBX Switch loaded.
    [Feb 8 13:52:59] WARNING[9416]: res_config_pgsql.c:1355 parse_config: PostgreSQL RealTime: Not connected
    [Feb 8 13:52:59] NOTICE[9416]: chan_skinny.c:8424 config_load: Configuring skinny from skinny.conf
    [Feb 8 13:52:59] NOTICE[9416]: cel_custom.c:97 load_config: No mappings found in cel_custom.conf. Not logging CEL to custom CSVs.
    [Feb 8 13:52:59] NOTICE[9416]: app_queue.c:8839 reload_queue_rules: queuerules.conf has not changed since it was last loaded. Not taking any action.

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

      • Понял, спасибо! Да все работает, но смущали эти предупреждения. А понял что это модули, тока часть отключить не получалось, но как это обычно бывает, как только я опубликовал вопрос, так тут же что-то нашлось в инете. Вот тут — http://wikiadmin.net/asterisk/ парень описал какие модули отключал у себя. Попробую сравнить имена в его списке и отключить у себя такие.

      • Смушают оставшиеся 3 строки:
        WARNING[9416]: res_odbc.c:526 load_odbc_config: The ‘pooling’, ‘shared_connections’, ‘limit’, and ‘idlecheck’ options were replaced by ‘max_connections’. See res_odbc.conf.sample.
        NOTICE[9416]: res_odbc.c:617 load_odbc_config: Registered ODBC class ‘asterisk’ dsn->[MySQL-asterisk]
        ERROR[9416]: ari/config.c:314 process_config: No configured users for ARI

        по 1-му и 2-ому, мы же в мануале настраивали odbc конекты, если я отключу их, по идее работать не будет же то что настраивали с их помощью.
        по 3-ему Это ошибка непонятная, похожего модуля не нашел.

  23. Вопрос дилетанта: «Вот поставили мы PJSIP и выбрали его в menuselect.» Это означает что он по умолчанию на нем будет работать? Я просто почему спрашиваю, вот к примеру регистрирую ростелеком, не угадал с пароле и ошибка выдалась: » WARNING[2397]:chan_sip.c:24286 handle_response_register: Forbidden — wrong password on authentication for REGISTER for ‘213162’ to ‘10.10.10.100’»
    И в ошибке четко видно «chan_sip.c», разве там не должен быть pjsip? Как проверить что все работает на PJSIP ?

  24. Дмитрий

    Добрый день!
    Что только не делал, выскакивает ошибка в веб-интерфейсе детализации звонков:
    PDO::errorInfo(): SQLSTATE[28000] [1045] Access denied for user ‘asterisk’@’localhost’ (using password: YES)
    причём user у меня asterisk_user, всё делал по вашим конфигам.
    Где рыть, что копать? В логах ничего нет. Может, где-то можно включить режим логирования debug, и это что-то даст?…

  25. Дмитрий

    Разобрался.
    Почему-то после изменении необходимых параметров логина/пароля в файлике /var/www/html/inc/config.inc.php всё устранилось.
    А я правил /etc/phpMyAdmin/config.inc.php 🙁
    Допишите пожалуйста в статье полный путь этого файла..

    И ещё… Огромное вам спасибо за ваш труд.

  26. Дмитрий

    А ещё, может кому-то потребуется, у меня никак asterisk не соединялся по odbc с mysql. Выдавал ошибку:
    res_odbc.c:958 odbc_obj_connect: res_odbc: Error SQLConnect=-1 errno=1045 [unixODBC][MySQL][ODBC 5.2(w) Driver]Access denied for user ‘asterisk_user’@’localhost’ (using pass
    Проблема оказалась в том, что пароль пользователя asterisk_user содержал точку с запятой.
    Я так, понял, спецсимволов быть не должно.

    • Они могут быть, но их надо экранировать. Если нет большой необходимости, лучше некоторые спецсимволы не использовать. Например, с # обычно проблем не бывает, а вот с запятыми, кавычками очень часто.

  27. Дмитрий

    Я, конечно, извиняюсь, может быть вы мне подскажете, пол интернета перерыл.
    Мне нужно, чтобы ivr произносил числа (в т.ч. и отрицательные и дробные) из таблицы mysql на том же сервере (ну или на другом, значения не имеет).
    Сижу, всю голову поломал.
    Как можно написать это правило в extension.conf?
    Я бы туда ещё и рубли с копейками запихнул, которые в say.conf пытаюсь приделать.
    В интернете есть много примеров с произнесением времени и даты, но вот с деньгами проблема. Может, хоть немного поможете? Больше не к кому обратиться, за что зацепиться.
    Спасибо!

    • Даже не знаю, с какой стороны подходить к решению данной задачи. Ни разу не сталкивался.

    • Аноним

      Я думаю вам путь в AGI. На хабре есть описание автоматизации текстов 1С + Астериск

  28. Здравствуйте!
    Хотелось бы в первую очередь поблагодарить автора за действительно замечательную статью — СПАСИБО!
    Как полный новичок в IP-телефонии хотел бы спросить у гуру «куда и где копать» чтобы у локального пользователя заработал телефон в следующей ситуации:
    После выхода с больничного у локального абонента перестала работать связь (ни туды и ни сюды). Забрался через браузер в FreePBX и в логах по нему нашел такую запись:
    «… LocalAddress=»IPV4/TCP/0.0.0.0/5038″,RemoteAddress=»IPV4/TCP/127.0.0.1 …»

  29. Здравствуйте. Подскажите пожалуйста, у нас настроена атс Астериск. настроено 6 удаленных офисов. через впн. Телефоны грандстрим. Так вот сегодня на одной точке, возникла проблема. Если во время входящего разговора, приходит ещё один внешний звонок, то оператор перестаёт слышать абонента с которым уже разговаривает.
    Куда смотреть? интересно то. что если звонить внутри сети. т.е. разговаривает оператор точки 1 с оператором точки 2 и звонит на точку1 оператор точки3, то никаких проблем со звуком нет. Только при внешних звонках.

    • Даже нет идей. Если раньше все работало, то надо смотреть, что изменилось за последнее время.

      • Ничего не менялось. в CDR репортсе, в это время нет записей о том. что я по внутренниму номеру разговаривал с проблемной точкой. А мы говорили и не раз и не по 10 секунд.
        А сегодня история повторилась. Я попытался с внешнего телефона дозвониться до точки, сработал автоответчик и когда подняли трубку, я кроме оператора. слышал длинные гудки. как будто мне ещё не ответили.

  30. Александр

    Здравствуйте.
    А не могли бы вы написать такую же подробную статью по отправке и приему факсов ..и при]м факса на емейл? спасибо

    • Я с факсами вообще не связываюсь. Мороки много — толку мало. Факс отжившая технология, вообще не вижу смысла ими пользоваться. Самый простой вариант — купить voip шлюз с аналоговой линией и подключить факс к нему. Хотя еще проще — воспользоваться онлайн сервисом каким-нибудь по приему факса. Я делал так, когда факс просили. Но обычно я отговариваю от факса. Зачем он нужен?

      • Аноним

        Аналоговая линия вообще не вариант. Факс все еще востребован в глубинке. А вот любой SIP провайдер с нормальной поддержкой T38 поможет, + допиливаение астериска

  31. Виктор

    День добрый в инете не нешел подробностей по этой строчки exten => _X!,1,HangUp()
    почему именно так вешаете трубку?
    конкретно два вопроса
    1) что даёт восклецательный знак?
    2) почему приоретет 1 а не n ?
    заранее спасибо

  32. Виктор

    + exten => _X!,1,HangUp() это же наверное можно вписать в блок [default] и не испоьовать include верно?

  33. виктор

    и спасибо за суперский мануал!

  34. Большое спасибо за подробную статью! Очень познавательно и полезно.
    Скажите пожалуйста, правильно ли я понимаю, что использование внешнего SIP-провайдера (zadarma в примере) опционально? Т.е., как я понял, необходимо для связи нашего Астерикса с ТФОП?
    Например, можно ли поднять Астерикс на машине с белым IP, абоненты А и Б через интернет подключены к этому Астериксу. Возможно ли абоненту А звонить через городскую линию абонента Б?

  35. Статья супер! Пройдя поэтапно получилось разобраться в астере, и начал понимать конфиги. Перед этим пробовал freepbx, так и не смог совладать, с конфигами както проще, знаешь где что. Поставили задачу по переезду коллцентра на свое железо, благо всего 6 опеаторов работает.

    Один вопрос. Не играет приветствие, ни Background, ни Playback. В трубке тишина, гудков тоже нет.
    wav конвертил, брал готовые, нет звука. В чем проблема может быть? Ставил все по статье, ничего лишнего, из коробки.

    ;голосовое приветствие
    [ivr-main]
    exten => s,1,Set(CALLERID(name)=ZADARMA)
    exten => s,2,Answer()
    exten => s,n,Playback(queue-callswaiting) ;/etc/asterisk/ivr/welcome
    exten => s,n,Queue(queue-5zvezd,Tt)

    • Надо включить full лог и посмотреть на сообщения в момент, когда должно проигрываться приветствие. Скорее всего что-то с музыкальными файлами — либо формат не тот, либо путь к файлу не правильно указан.

      • Подставлял родные мелодии из самого астера. Также тишина. В логах написано что типа играет.
        == Using SIP RTP CoS mark 5
        — Executing [zadarma@zadarma-in:1] BackGround(«SIP/zadarma-00000015», «/etc/asterisk/ivr/welcome_sold») in new stack
        — Playing ‘/etc/asterisk/ivr/welcome_sold.slin’ (language ‘ru’)
        — Executing [zadarma@zadarma-in:2] Dial(«SIP/zadarma-00000015», «SIP/100») in new stack
        == Using SIP RTP CoS mark 5
        — Called SIP/100
        — SIP/100-00000016 is ringing
        == Spawn extension (zadarma-in, zadarma, 2) exited non-zero on ‘SIP/zadarma-00000015’
        в папке лежит wav файл, в логах slin. Вот это пока не понятно, вроде как на лету декодит астер.

  36. Здравствуйте! Столкнулся с такой проблемой: при попытке состыковать астериск и MySql через ODBC, по написанному в Вашей статье образцу, получаю ошибку: res_odbc.c:962 odbc_obj_connect: res_odbc: Error SQLConnect=-1 errno=-201315904 [iODBC][Driver Manager]MySQL: cannot open shared object file: No such file or directory. При этом isql -v MYSQL-asterisk asterisk_user 12345678 спокойно соединяется с БД.

  37. На виртуальной машине поднял сервер Астерикса за натом. При звонке с одного софтофона на другой случилась проблема. Не было слышно 1 абонента. Звонил шел через внешний ип по внутреннему номеру. 100 слышно, 101 нет. пробовал directmedia, пробросы портов на роутере, отрубал iptables, а помогло указание внутренней под сети сервера в sip.conf — localnet=192.168.1.0/255.255.255.0 над externaddr

    • дополнение для sip.conf для поддержки видео звонков.

      [general]
      videosupport=yes

      [managers-phones](!)
      type=friend
      context=call-out
      secret=123
      host=dynamic
      nat=no
      qualify=yes
      canreinvite=no
      callgroup=1
      pickupgroup=1
      call-limit=1
      dtmfmode=auto
      disallow=all
      allow=alaw
      allow=ulaw
      allow=g729
      allow=g723
      allow=g722
      allow=h261
      allow=h263
      allow=h263p

  38. Добрый день!
    очень помогают ваши статьи. Спасибо вам за этот труд.
    Все получалось до пункта «запись разговора», а именно на команде
    # tar zxvf lame-3.*
    текст ошибки:
    /usr/src# tar zxvf lame-3.*
    tar (child): lame-3.98.4: Функция read завершилась с ошибкой: Это каталог
    tar (child): Начало ленты, завершение работы
    tar (child): Error is not recoverable: exiting now

    gzip: stdin: unexpected end of file
    tar: Child returned status 2
    tar: Error is not recoverable: exiting now

    Я новичок и в основном делаю все по вашим командам, большинство не понимая. но все таки пытаюсь разобраться.
    Не могли бы вы мне помочь, что пошло не так?
    и если не трудно можете привести пример файла extensions.conf в варианте, если звонки будут просто писаться в какую-то папку, без конвертирования в mp3 и без заморочек с БД.

    • tar (child): lame-3.98.4: Функция read завершилась с ошибкой: Это каталог

      Эта ошибка говорит о том, что имя файла с маской «lame-3.*» возвращает имя каталога, а не файл архива. Вместо lame-3.* напишите полностью имя скачанного файла.

      • Спасибо помогло.
        но теперь ошибка на команде #make

        Makefile:306: ошибка выполнения рецепта для цели «xmm_quantize_sub.lo»
        make[3]: *** [xmm_quantize_sub.lo] Ошибка 1
        make[3]: выход из каталога «/usr/src/lame-3.98.4/libmp3lame/vector»
        Makefile:489: ошибка выполнения рецепта для цели «all-recursive»
        make[2]: *** [all-recursive] Ошибка 1
        make[2]: выход из каталога «/usr/src/lame-3.98.4/libmp3lame»
        Makefile:312: ошибка выполнения рецепта для цели «all-recursive»
        make[1]: *** [all-recursive] Ошибка 1
        make[1]: выход из каталога «/usr/src/lame-3.98.4»
        Makefile:240: ошибка выполнения рецепта для цели «all»
        make: *** [all] Ошибка 2

        • Возможно файл скачался не полностью. В принципе, можно не ставить lame и либо вообще отключить запись разговоров, либо оставить их несжатыми в wav. Потом уже, после настройки основного, вернуться к этому вопросу.

          • В любом случае спасибо. в остальном проблем не возникло.
            Для таких новичков как я, не хватает пояснений по каждой команде. Но тогда статья удвоится в объеме…
            Успехов Вам.

  39. tar -xjvf pjproject-2.*
    у меня не отрабатывает, не подскажите что это?
    пишет
    [root@MiWiFi-R1CL-srv src]# wget http://www.pjsip.org/release/2.4/pjproject-2.4.tar.bz2
    —2017-09-15 18:25:41— http://www.pjsip.org/release/2.4/pjproject-2.4.tar.bz2
    Resolving http://www.pjsip.org (www.pjsip.org)… 207.38.94.48
    Connecting to http://www.pjsip.org (www.pjsip.org)|207.38.94.48|:80… connected.
    HTTP request sent, awaiting response… 200 OK
    Length: 4631778 (4.4M) [application/x-bzip2]
    Saving to: ‘pjproject-2.4.tar.bz2.4’

    100%[======================================>] 4,631,778 853KB/s in 5.9s

    2017-09-15 18:25:47 (763 KB/s) — ‘pjproject-2.4.tar.bz2.4’ saved [4631778/4631778]

    [root@MiWiFi-R1CL-srv src]# tar -xjvf pjproject-2.* tar (child): bzip2: Cannot exec: No such file or directory
    tar (child): Error is not recoverable: exiting now
    tar: Child returned status 2
    tar: Error is not recoverable: exiting now

    • Напишите полностью имя файла — pjproject-2.4.tar.bz2.4. Не понял только, почему на конце .4, скорее всего вы этот файл скачали уже 4 раза, поэтому команда tar -xjvf pjproject-2.* не понимает, какой из этих файлов нужно распаковать.

      • таже беда, переустановил cent
        php-pdo.x86_64 0:5.4.16-42.el7
        php-php-gettext.noarch 0:1.0.12-1.el7
        php-tcpdf.noarch 0:6.2.13-1.el7
        php-tcpdf-dejavu-sans-fonts.noarch 0:6.2.13-1.el7
        php-tidy.x86_64 0:5.4.16-7.el7
        pixman.x86_64 0:0.34.0-1.el7
        pixman-devel.x86_64 0:0.34.0-1.el7
        procmail.x86_64 0:3.22-36.el7
        pulseaudio-libs.x86_64 0:10.0-3.el7
        rsync.x86_64 0:3.0.9-18.el7
        slang-devel.x86_64 0:2.2.4-11.el7
        subversion-libs.x86_64 0:1.7.14-11.el7_4
        t1lib.x86_64 0:5.1.2-14.el7
        trousers.x86_64 0:0.3.14-2.el7
        unbound-libs.x86_64 0:1.4.20-34.el7
        uuid.x86_64 0:1.6.2-26.el7
        vim-common.x86_64 2:7.4.160-2.el7
        vim-filesystem.x86_64 2:7.4.160-2.el7
        wavpack.x86_64 0:4.60.1-9.el7
        xorg-x11-proto-devel.noarch 0:7.7-20.el7
        xz-devel.x86_64 0:5.2.2-1.el7
        zlib-devel.x86_64 0:1.2.7-17.el7

        Complete!
        [root@MiWiFi-R1CL-srv ~]# cd /usr/src
        [root@MiWiFi-R1CL-srv src]# wget http://www.pjsip.org/release/2.4/pjproject-2.4.tar.bz2
        —2017-09-15 12:56:00— http://www.pjsip.org/release/2.4/pjproject-2.4.tar.bz2
        Resolving http://www.pjsip.org (www.pjsip.org)… 207.38.94.48
        Connecting to http://www.pjsip.org (www.pjsip.org)|207.38.94.48|:80… connected.
        HTTP request sent, awaiting response… 200 OK
        Length: 4631778 (4.4M) [application/x-bzip2]
        Saving to: ‘pjproject-2.4.tar.bz2’

        100%[======================================>] 4,631,778 1.27MB/s in 3.6s

        2017-09-15 12:56:04 (1.22 MB/s) — ‘pjproject-2.4.tar.bz2’ saved [4631778/4631778]

        [root@MiWiFi-R1CL-srv src]# tar -xjvf pjproject-2.*
        tar (child): bzip2: Cannot exec: No such file or directory
        tar (child): Error is not recoverable: exiting now
        tar: Child returned status 2
        tar: Error is not recoverable: exiting now
        [root@MiWiFi-R1CL-srv src]# tar xjvf pjproject-2.*
        tar (child): bzip2: Cannot exec: No such file or directory
        tar (child): Error is not recoverable: exiting now
        tar: Child returned status 2
        tar: Error is not recoverable: exiting now
        [root@MiWiFi-R1CL-srv src]#

        на 6.4 отрабатывали следующие
        wget http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/dahdi-linux-complete-current.tar.gz
        wget http://downloads.asterisk.org/pub/telephony/libpri/old/libpri-1.4.15.tar.gz
        wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-11-current.tar.gz
        d) Распаковываем скаченные архивы:
        tar zxvf dahdi-linux-complete*
        tar zxvf libpri*
        tar zxvf asterisk*

        • Я же написал, используйте полное имя файла в команде распаковки, а не маску со звездочкой на конце.

          • да, но перед этим советую проделать следующее, тогда точно будет работать
            yum install -y gcc gcc-c++ lynx bison mariadb-devel mariadb-server mariadb gmime-devel psmisc php php-mysql php-pear php-mbstring yum install tftp-server httpd make ncurses-devel libtermcap-devel sendmail sendmail-cf caching-nameserver sox newt-devel libxml2-devel libtiff-devel audiofile-devel gtk2-devel subversion kernel-devel yum install kernel-devel-$(uname -r) git subversion kernel-devel php-process crontabs cronie cronie-anacron wget vim php-xml uuid-devel libtool sqlite-devel libuuid-devel bzip2
            systemctl enable mariadb.service systemctl start mariadb.service

  40. Добрый день. Вы можете подсказать, как должны выглядеть настройки sip.conf, если я не подключаюсь к провайдеру, а внешние номера прокидываю на sip-шлюз (плата TM.IP) в нашей АТС. Для одного номера (2055) работает, а вот как сделать чтобы и на другие номера можно было звонить? номера серии 7XXX — sip, 2055 — номер УПАТС. конфиг выглядит так:
    Extensions.conf

    [general]
    static=yes
    writeprotect=no
    [globals]
    [default]

    [handup-sip]
    exten => _XX!,1,HangUp()

    [call-out]

    exten => _XXXX,1,Dial(SIP/${EXTEN})
    include => handup-sip
    exten => _XXXX.,1,Dial(SIP/${EXTEN}@2055)

    [call-in]
    exten => 2055,1,Dial(SIP/7000)

    sip.conf

    [general]
    externaddr=192.168.0.140:5060
    language=ru
    context=default
    allowoverlap=no
    udpbindaddr=0.0.0.0
    tcpenable=no
    tcpbindaddr=0.0.0.0
    transport=udp
    srvlookup=yes
    allowguest=no
    limitonpeers=yes

    [authentication]

    [managers-phones](!)
    type=friend
    context=call-out
    secret=123
    host=dynamic
    nat=no
    qualify=yes
    canreinvite=no
    callgroup=1
    pickupgroup=1
    call-limit=1
    dtmfmode=auto
    disallow=all
    allow=alaw
    allow=ulaw
    allow=g729
    allow=g723
    allow=g722

    [7000](managers-phones)
    callerid=»Number 7000″
    [7001](managers-phones)
    callerid=»Number 7001″
    [7002](managers-phones)
    callerid=»Number 7002″

    [2055]
    host=192.168.0.140
    insecure=invite,port
    type=friend
    fromdomain=192.168.0.140
    disallow=all
    allow=alaw
    dtmfmode=auto
    secret=123
    defaultuser=2055
    trunkname=2055
    fromuser=2055
    callbackextensions=2055

  41. сама разобралась. все ок.

  42. Михаил

    Здравствуйте, спасибо за статью, на многое открыли глаза.
    Единственное что: не показывает сохраненный звонок на web интерфейсе.
    в config.php изменил на свою папку и все равно без изменений.

    • Михаил

      Если ввести ip Сервера/records то файлы видны хоть и в wav.
      А вот через веб сервер их не видно

      • Михаил

        заработало. теперь проблема осталась только в том, что не конвертирует из wav в mp3

  43. Алексей

    Наткнулся на вашу инструкцию, и прочитав подумал, в старых инструкциях везде был пак такой — астер + libpri + dahdi, тут у вас иначе…объясните, что давал libpri и dahdi и почему сейчас он не используется для работы в новых версиях астера (например как в вашем случае 13) и зачем pjproject с jansson? (p.s. только начал изучать VOIP телефонию и поэтому от стольких мануалов, что я пересмотрел, голова кругом)

    • Алексей

      Кстати в предыдущей статье про астер и pbx libpri и dahdi использовался

    • libpri и dahdi используются для подключения к астериску плат расширения. Лично мне все это уже не нужно. Я стараюсь всю телефонию настраивать исключительно на sip. Подобные платы были популярны раньше, в переходный период, когда астериск стыковали с аналоговой и цифровой телефонией. Сейчас все в основном переходят на IP.

      • Алексей

        получается если я буду использовать аналоговые устройства мне данные пакеты пригодятся? в принципе понял зачем jansson — во время компиляции астера версии 13/14 он нужен был :))

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

  44. Владимир

    Автору огромнейший респект, такой подробной и внятно написанной статьи я еще не встречал!!!
    Не нашел правда ответа на один вопросик, а как нибудь можно с консоли или еще как создать 3cxconfig для android 3CX? Все мне известные методы это прикручивать веб морду, чего я честно не очень хочу.

  45. Добрый день.

    Ситуация такая, если мне звонят снаружи, если не вводить добавочный номер, то входящий звонок переводится на секретаря, в логах вместо номера на кого переведен входящий вызов указан символ «t», как сделать что бы указывался конечный номер?

    В остальных случаях все корректно фиксируется.

    • Так а какой номер вы хотите увидеть? Они же номер не вводят, звонок уходит на секретаря, номер которого и так известен. Если нужно изменить вывод вместо «t» на номер секретаря, то тут простого решения я не вижу. В данном случае «t» это направление звонка, которое и фиксируется в статистике, ведь звонок на самом деле на «t» и уходит.

  46. Если у меня 3 секретаря, хотелось бы знать кто из них трубку взял. В принципе в базе там можно вычислить кто взял. А вот в имени файла записи разговора стоит t, не удобно, думал как тотпросто можно поправить, что бы корректно имя файла было

    • А как на разных секретарей идет перенаправление? Через очередь? Или они просто перечислены один за другим в диалплане? Тут я не знаю, как подсказать, надо пробовать. Думаю, это можно как-то исправить, но надо разбираться.

    • Кстати, если вопрос только в имени файла, то для него можно указывать маску. Надо посмотреть все параметры, которые можно задавать и выбрать подходящие.

  47. Через очереди.

  48. И кстати вопрос ещё. 🙂 я использую ms sql server туда заливаю статистику звонков. У меня не получилось добавлять имя файла записи, это нельзя сделать или я не смог разобраться?

    • Думаю можно, просто не так, как у меня описано в статье. Я с mssql никогда не снюхивал ничего из линукс, так что не подскажу. Да я и смысла не вижу использовать какую-то внешнюю БД. Тут нагрузки никакой нет, но зато удобно, когда и сам сервер астера и бд находятся на одной виртуалке. Забэкапил и развернул всю систему, она сразу же готова к работе. А какой смысл во внешней базе mssql, кроме лишних проблем? Я бы установил локально mysql и не мучался.

  49. Имелся установленный mssql, решил задействовать. Для меня пока линукс новое…😀 надо попробовать mysql

    • Если настройку астериска осилили, то уж поставить и подключить его к mysql дело несложное. К тому же на сайте все есть, да даже в этой статье.

Добавить комментарий

Ваш e-mail не будет опубликован.