Ограничение внутренних вызовов через AstDB
В данной статье будет рассмотрен способ настройки ограничения внутренней связи по группам. Реализация задач Для решения поставленных задач нам понадобится создать отдельный custom-context для целевого внутреннего номера. Создаём новый connectivity->custom-context->Add context Выставляем необходимые внешние маршруты, как входящие так и исходящие, при этом запрещая все внутренние. После чего назначаем внутреннему номеру новый контекст: И приступаем непосредственно […]
В данной статье будет рассмотрен способ настройки ограничения внутренней связи по группам.
Реализация задач
Для решения поставленных задач нам понадобится создать отдельный custom-context для целевого внутреннего номера. Создаём новый connectivity->custom-context->Add context
Выставляем необходимые внешние маршруты, как входящие так и исходящие, при этом запрещая все внутренние.
После чего назначаем внутреннему номеру новый контекст:
И приступаем непосредственно к обработке логики диалпланом. Допустим нам необходимо разрешить вызов номера директора только от заместителя и представителей руководства. Номер первого: 771. Группа разрешенных номеров: 117, 131, 136, 169, 186, 194, 501, 508, 514, 540, 701, 702, 736, 901, 908, 921.
Небольшое отступление: причина использовать базу, не воспользовавшись стандартными возможностями диалплана asterisk вида:
exten => 771/_[1579][0-4689][ 1246-9],1,...
Очень проста. Во-первых чтобы поменять допустимое значение потребуется переписывать конфигурационный файл extensions_custom.conf и контекст [from-internal-custom], в частности. После чего будет необходимо выполнить применение настроек командой: dialplan reload. Что не всегда возможно и удобно. В тоже время добавив один раз небольшие правки в диалплан и AstDB мы получим гибкую систему настройки. Помимо прочего, которой можно будет управлять извне, какими-либо средствами.
Приступим к заполнению базы нашими номерами. Для этого потребуются следующие команды CLI-консоли:
- добавление одной записи:
# asterisk -rx 'database put 771_ALLOW 115 1'
- удаление одной записи:
asterisk -rx 'database del 771_ALLOW 115'
- удаление древа записей:
# asterisk -rx 'database deltree 771_ALLOW'
- просмотр текущего древа:
# asterisk -rx 'database show 771_ALLOW'
Подробнее о работе с AstDB рассказано в статье.
И наконец обработчик в диалплане будет выглядеть следующим образом:
; ------------------ Inbount calls ------------------
exten => 771,1,GotoIf(${DB_EXISTS(${EXTEN}_ALLOW/${CALLERID(num)})}?from-internal-additional,${EXTEN},1)
same => n,Busy(5)
same => n,Hangup
Здесь мы разрешаем вызов номера 771 только номерам разрешенным в базе.
; ------------------ Outbound calls ------------------
[for-771-custom]
exten => _X.,1,GotoIf(${DB_EXISTS(771_ALLOW/${EXTEN})}?from-internal,${EXTEN},1)
same => n,Busy(5)
same => n,Hangup
Здесь разрешаем самому внутреннему номеру 771 вызывать только номера указанные в базе. Остальным будет выдан сигнал «занято» и вызов завершится.
Как уже говорилось ранее, добавить в файл extensions_custom.conf, контекст [from-internal-custom]
Web-интерфейс
Упростим эксплуатацию так, чтобы она была доступна пользователям без прямого доступа в терминал сервера. Для этого понадобится редактор и некоторый интерфейс, который будет переписывать значения в базе. Его можно написать самостоятельно или воспользоваться кодом ниже. Используем возможность гибридизации html и php для сокращения размера кода и наглядности. Подробных пояснений к разметке давать не будем, пройдёмся лишь по скриптам-обработчикам. Первый фрагмент:
$exec_out_1=[];
exec('mysql -u freepbxuser -pd45c7ea6a5460b03300977b1cd61f148 -D asterisk -N -e "select id from devices"',$exec_out_1);
foreach($exec_out_1 as $element){
$check=($_POST['for_exten']==$element)?'checked':'';
echo '<label><input type="radio" name="for_exten" value="'.$element.'" '.$check.' />'.$element.'</label>';
};
Объявляем массив для хранения переменных, запрашиваем у системы список внутренних номеров и сохраняем в нём. После чего выполняем проход по массиву и генерируем html-элементы соответствующие типу radio (для однозначного выбора).
Второй:
if(isset($_POST['give'],$_POST['for_exten'])){
$exec_out_2=[];
exec('asterisk -rx "database show IN_ALLOW_'.$_POST['for_exten'].'" | grep IN_ALLOW_',$exec_out_2);
foreach($exec_out_1 as $element){
$check=(in_array('/IN_ALLOW_'.$_POST['for_exten'].'/'.$element.' : 1',$exec_out_2))?'checked':'';
echo '<label><input type="checkbox" name="granted_in[]" value="'.$element.'" '.$check.' />'.$element.'</label>';
};
}
if(isset($_POST['send'],$_POST['for_exten'],$_POST['granted_in'])){
exec('asterisk -rx "database deltree IN_ALLOW_'.$_POST['for_exten'].'"',$null);
foreach($_POST['granted_in'] as $element){
exec('asterisk -rx "database put IN_ALLOW_'.$_POST['for_exten'].' '.$element.' 1"',$null);
}
}
elseif(isset($_POST['send'],$_POST['for_exten'])){
exec('asterisk -rx "database deltree IN_ALLOW_'.$_POST['for_exten'].'"',$null);
}
Здесь возможно три развития событий в зависимости от аргументов POST-запроса:
- Внутренний номер «for_exten» и параметр запроса «give».
Получаем в массив все разрешения, выполнив запрос в AstDB, для текущего выбранного номера. После чего перебираем все внутренние номера и в зависимости от наличия в новом массиве строки разрешения генерируем html-элементы checkbox (для множественного выбора) в активном или пассивном состоянии. - Внутренний номер «for_exten» и параметр сохранения «send».
Удаляем древо базы AstDB по текущему выбранному номеру. Таким образом реализована очистка базы если не выбран ни один разрешенный номер. - Внутренний номер «for_exten», параметр запроса «give» и массив новых правил «granted_in»
Выполняем перебор всех переданных правил и вносим их в AstDB под соответствующее древо и внутренний номер.
Третий:
if(isset($_POST['give'],$_POST['for_exten'])){
$exec_out_3=[];
exec('asterisk -rx "database show OUT_ALLOW_'.$_POST['for_exten'].'" | grep OUT_ALLOW_',$exec_out_3);
foreach($exec_out_1 as $element){
$check=(in_array('/OUT_ALLOW_'.$_POST['for_exten'].'/'.$element.' : 1',$exec_out_3))?'checked':'';
echo '<label><input type="checkbox" name="granted_out[]" value="'.$element.'" '.$check.' />'.$element.'</label>';
};
}
if(isset($_POST['send'],$_POST['for_exten'],$_POST['granted_out'])){
exec('asterisk -rx "database deltree OUT_ALLOW_'.$_POST['for_exten'].'"',$null);
foreach($_POST['granted_out'] as $element){
exec('asterisk -rx "database put OUT_ALLOW_'.$_POST['for_exten'].' '.$element.' 1"',$null);
}
}
elseif(isset($_POST['send'],$_POST['for_exten'])){
exec('asterisk -rx "database deltree OUT_ALLOW_'.$_POST['for_exten'].'"',$null);
}
Выполняется аналогично трём пунктам предыдущего фрагмента с заменой наименования древа: с IN_ALLOW_<номер> на OUT_ALLOW_<номер>.
Совместив это всё с разметкой получим следующий скрипт:
<html>
<head>
<title>CallLimit</title>
<link rel="shortcut icon" href="favicon.png" type="image/png">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<form action="" method="post">
<fieldset>
<legend>Ограничения вызовов</legend>
<fieldset class="subfield">
<legend>Внутренний номер</legend>
<?php
$exec_out_1=[];
exec('mysql -u freepbxuser -pd45c7ea6a5460b03300977b1cd61f148 -D asterisk -N -e "select id from devices"',$exec_out_1);
foreach($exec_out_1 as $element){
$check=($_POST['for_exten']==$element)?'checked':'';
echo '<label><input type="radio" name="for_exten" value="'.$element.'" '.$check.' />'.$element.'</label>';
};
?>
</fieldset>
<fieldset class="subfield">
<legend>Входящие</legend>
<?php
if(isset($_POST['give'],$_POST['for_exten'])){
$exec_out_2=[];
exec('asterisk -rx "database show IN_ALLOW_'.$_POST['for_exten'].'" | grep IN_ALLOW_',$exec_out_2);
foreach($exec_out_1 as $element){
$check=(in_array('/IN_ALLOW_'.$_POST['for_exten'].'/'.$element.' : 1',$exec_out_2))?'checked':'';
echo '<label><input type="checkbox" name="granted_in[]" value="'.$element.'" '.$check.' />'.$element.'</label>';
};
}
if(isset($_POST['send'],$_POST['for_exten'],$_POST['granted_in'])){
exec('asterisk -rx "database deltree IN_ALLOW_'.$_POST['for_exten'].'"',$null);
foreach($_POST['granted_in'] as $element){
exec('asterisk -rx "database put IN_ALLOW_'.$_POST['for_exten'].' '.$element.' 1"',$null);
}
}
elseif(isset($_POST['send'],$_POST['for_exten'])){
exec('asterisk -rx "database deltree IN_ALLOW_'.$_POST['for_exten'].'"',$null);
}
?>
</fieldset>
<fieldset class="subfield">
<legend>Исходящие</legend>
<?php
if(isset($_POST['give'],$_POST['for_exten'])){
$exec_out_3=[];
exec('asterisk -rx "database show OUT_ALLOW_'.$_POST['for_exten'].'" | grep OUT_ALLOW_',$exec_out_3);
foreach($exec_out_1 as $element){
$check=(in_array('/OUT_ALLOW_'.$_POST['for_exten'].'/'.$element.' : 1',$exec_out_3))?'checked':'';
echo '<label><input type="checkbox" name="granted_out[]" value="'.$element.'" '.$check.' />'.$element.'</label>';
};
}
if(isset($_POST['send'],$_POST['for_exten'],$_POST['granted_out'])){
exec('asterisk -rx "database deltree OUT_ALLOW_'.$_POST['for_exten'].'"',$null);
foreach($_POST['granted_out'] as $element){
exec('asterisk -rx "database put OUT_ALLOW_'.$_POST['for_exten'].' '.$element.' 1"',$null);
}
}
elseif(isset($_POST['send'],$_POST['for_exten'])){
exec('asterisk -rx "database deltree OUT_ALLOW_'.$_POST['for_exten'].'"',$null);
}
?>
</fieldset>
<div>
<button name="give" value="ok">Получить</button>
<button name="send" value="ok">Сохранить</button>
</div>
</fieldset>
</form>
</body>
</html>
Дополнительно в архиве есть закреплённый файл CSS-стилей и иконка.
Таким образом у нас есть интерфейс редактирования разрешений дозвона средствами внутренней базы asterisk AstDB.
Остаётся лишь подкорректировать диалплан для работы с новыми записями. В файл
# nano /etc/asterisk/extensions_custom.conf
Внести следующте изменения в контекст [from-internal-custom]
exten => _XXX,1,GotoIf(${DB_EXISTS(IN_ALLOW_${EXTEN}/${CALLERID(num)})}?from-internal-additional,${EXTEN},1)
same => n,GotoIf(${DB_EXISTS(OUT_ALLOW_${CALLERID(num)}/${EXTEN})}?from-internal-additional,${EXTEN},1)
same => n,Busy(5)
same => n,Hangup
Из приведённых примеров видно, что на 200ый могут звонить 101,103,105,107,109. В то же время номер 200 может вызывать номера: 101-108. Таким образом реализовано ограничение внутренних звонков по номеру звонящего средствами внутренней базы AstDB.
Остались вопросы?
Я - Першин Артём, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.
категории
- DECT
- Linux
- Вспомогательный софт при работе с Asterisk
- Интеграция с CRM и другими системами
- Интеграция с другими АТС
- Использование Elastix
- Использование FreePBX
- Книга
- Мониторинг и траблшутинг
- Настройка Asterisk
- Настройка IP-телефонов
- Настройка VoIP-оборудования
- Новости и Статьи
- Подключение операторов связи
- Разработка под Asterisk
- Установка Asterisk
VoIP оборудование
ближайшие курсы
Новые статьи
10 доводов в пользу Asterisk
Распространяется бесплатно.
Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.
Безопасен в использовании.
Любое программное обеспечение может стать объектом интереса злоумышленников, в том числе телефонная станция. Однако, сам Asterisk, а также операционная система, на которой он работает, дают множество инструментов защиты от любых атак. При грамотной настройке безопасности у злоумышленников нет никаких шансов попасть на станцию.
Надежен в эксплуатации.
Время работы серверов некоторых наших клиентов исчисляется годами. Это значит, что Asterisk работает несколько лет, ему не требуются никакие перезагрузки или принудительные отключения. А еще это говорит о том, что в районе отличная ситуация с электроэнергией, но это уже не заслуга Asterisk.
Гибкий в настройке.
Зачастую возможности Asterisk ограничивает только фантазия пользователя. Ни один конструктор шаблонов не сравнится с Asterisk по гибкости настройки. Это позволяет решать с помощью Asterisk любые бизнес задачи, даже те, в которых выбор в его пользу не кажется изначально очевидным.
Имеет огромный функционал.
Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.
Интегрируется с любыми системами.
То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.
Позволяет телефонизировать офис за считанные часы.
В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.
Отличная масштабируемость.
Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.
Повышает управляемость бизнеса.
Asterisk дает не просто набор полезных функций, он повышает управляемость организации, качества и комфортности управления, а также увеличивает прозрачность бизнеса для руководства. Достичь этого можно, например, за счет автоматизации отчетов, подключения бота в Telegram, санкционированного доступа к станции из любой точки мира.
Снижает расходы на связь.
Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.