iaxmodem, hylafax и LDAP

Во многих случаях Asterisk используется для расширения функционала существующей системы связи, например, для экономии на междугородных разговорах, организации аудио конференций или в роли call центра. Операционная система Windows чрезвычайно распространена в нашей стране, у многих администраторов возникает вопрос интеграции Asterisk со службой каталогов Active Directory. Рассмотрим работу с LDAP на примере факс-сервера.

Подключение оборудования

В самом простом случае задача факс-сервера сводится к приему сообщения в сетевой каталог в виде файла формата PDF или TIFF, однако намного удобнее, если принимаемые факсы попадали бы персонально в электронный почтовый ящик пользователя. Рассмотрим типичную схему подключения Asterisk в большой компании:

В этой схеме все звонки пользователей по потоку Е1 пропускаются через сервер. Такой подход наиболее выгоден из-за низкой стоимости платы на два потока для Asterisk и дает наибольшее преимуществ благодаря цифровой передачи голоса, номеров и имен (в случае QSIG).

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

Общение с Active Directory

По номеру переводящего в Active Directory можно найти адрес почтового ящика пользователя. Для Asterisk есть функция LDAPget, но нам не удалось заставить работать ее с версией 1.6.0.9, поэтому решено было реализовать ее самостоятельно с помощью phpAGI. Язык PHP хорош тем, что в его составе имеется очень много функций для работы со всевозможными протоколами, в том числе и с LDAP. Вариант phpAGI скрипта для запроса параметров в ctive Directory в процессе вызова:

 #!/usr/bin/php -q
 <?php
 ///var/lib/asterisk/agi-bin/ldap-get.php: LDAP query 

$ldap_host = “ldap://domain.controller.ru”; $ldap_port = “389”; $base_dn = “ou=CO,dc=controller,dc=ru”; //$justthese = array(‘ou’,‘sn’,‘givenName’,‘mail’); $ldap_user =“controller\user”; $ldap_pass = “password”; include(“phpagi.php”); $agi = new AGI; //первый параметр: номер телефона для поиска if (!isset($argv[1])) { $agi->verbose("Missing phone number"); exit(1); } //второй параметр: искомое значение if (!isset($argv[2])) { $agi->verbose("Missing justthese type"); exit(1); } //третий параметр: имя переменной для возврата результата if (!isset($argv[3])) { $agi->verbose("Missing return var name"); exit(1); }
$number = $argv[1]; $justthese= array($argv[2]); $argvarname = $argv[3];
// фильтр определяет типы объектов, по которым производится поиск // возможно придется уточнить/изменить фильтр в соответствии с вашей схемой AD $filter = "( & (objectclass=person) (!(objectclass=computer)) (!(userAccountControl=66050)) (!(description=hidden)) (telephonenumber=".$number."))";
$connect = ldap_connect( $ldap_host, $ldap_port); ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); $agi->verbose("LDAP connect: ".$connect); ldap_set_option($connect, LDAP_OPT_REFERRALS, 0); $bind = ldap_bind($connect, $ldap_user, $ldap_pass); $agi->verbose("LDAP bind: ".$bind); $read = ldap_search($connect, $base_dn, $filter,$justthese); $agi->verbose("LDAP query: ".$read); $info = ldap_get_entries($connect, $read); $agi->verbose("LDAP result: ".$info[0][$justthese[0]][0]);
ldap_close($connect);
$agi->set_variable($argvarname, $info[0][$justthese[0]][0]); ?>

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

Обработка вызова

Для приема факса нужно настроить диалплан так, чтобы переведенный с АТС вызов попадал в такой макрос:

 [macro-fax-ldap]
 exten => s,1,answer()
 exten => s,n(start),Background(custom/start-fax)
 exten => s,n,AGI(ldap-get.php,${CALLERID(num)},mail,faxemail)
 exten => s,n,Set(faxemail=${IF($["${faxemail}" = ""]? ${FAX_RX_EMAIL}:${faxemail})})
 exten => s,n,Goto(in_fax,1)

 exten => in_fax,1,StopPlayTones  
 exten => in_fax,n,Set(FAXFILE=/tmp/${UNIQUEID}.tif)
 exten => in_fax,n,set(__call-from=${CALLERID(number)})
 exten => in_fax,n,set(CALLERID(number)=${UNIQUEID})
 exten => in_fax,n,Dial(IAX2/iaxmodem1/${UNIQUEID})
 exten => in_fax,n,Dial(IAX2/iaxmodem2/${UNIQUEID})
 exten => in_fax,n,Dial(IAX2/iaxmodem3/${UNIQUEID})
 exten => in_fax,n,Dial(IAX2/iaxmodem4/${UNIQUEID})
 exten => in_fax,n,wait(3)
 exten => in_fax,n,Hangup

 exten => h,1,system(/var/lib/asterisk/bin/fax-process.pl --to ${faxemail} 
--from ${FAX_RX_FROM} --subject "Fax from ${call-from} ${CALLERID(name)}" 
--attachment ${CALLERID(number)}.pdf --type application/pdf --file ${FAXFILE});
 

В нашем случае прием факса осуществляется с помощью связки iaxmodem+hylafax, однако hylafax имеет собственный механизм рассылки факсов, который нам, по сути, ни к чему. Проблема усугубляется тем, что hylafax принимает факсы в каталог /var/spool/hylafax/recvq и имя факса никак не отражает его связь с каким либо вызовом. Однако широкие возможности в маршрутизации факсовых сообщений с помощью файла FaxDispatch позволят переименовывать файлы так, как нужно:

##	 /var/spool/hylafax/etc/FaxDispatch	
TEMPLATE=en
SENDTO=FaxMaster;				# by default email to FaxMaster
FILETYPE=pdf;					# in PDF format
FOLDER="/var/spool/hylafax/recvq/"
FULLPATH="${FOLDER}${FILENAME}.tif"
## переименовываем файлы и меняем права доступа
mv $FULLPATH /tmp/$CIDNUMBER.tif
chmod a+rw /tmp/$CIDNUMBER.tif    # all faxes received on ttyS14

Этот скрипт запускается после приема факса, и, так как мы присваиваем в качестве имени отправителя переменную ${UNIQUEID}, то имя файла однозначно определяет соответствие какому-либо вызову. После того, как факс принят и перемещен в каталог /tmp, скрипт fax-process.pl, запускаемый из asterisk, отправляет файл на почту абоненту.

Файлы и ссылки

Скрипт обработки факсов: http://lynks.ru/file_download/20/FaxDispatch

AGI скрипт для запроса в AD: http://lynks.ru/file_download/21/ldap-get.php

Макрос для Asterisk: http://lynks.ru/file_download/22/macro-fax-ldap.conf

Обсуждение статьи: http://asterisk-support.ru/forum/topics/5527



  • 09/11/09
  • 18
  • Оценка: 2.59/5, голосов: 486

Комментарии

iaxmodem, hylafax и LDAP 2009-11-10 18:49 / #

> однако hylafax имеет собственный механизм рассылки факсов, который нам, по сути, ни к чем
Это потому что ты используешь диалплан :-)
Все это можно реализовать в скрипте FaxDispatch, а номера доступны в переменных CALLID1, CALLID2, CALLID3, CALLID4.

Все что надо сделать, это
exten => _X.,1,NoOp
exten => _X.,n(one),Dial(IAX2/FaxDSP1/${EXTEN},2,gj)
exten => _X.,n,ChannelRedirect(${CHANNEL},users,${EXTEN},1)

iaxmodem, hylafax и LDAP 2009-11-28 11:35 / #

Да, использую диалплан. Файл FaxDispatch часто не работает как надо,не имеет механизмов отладки. Почему – хз, причем факсы принимаются нормально.
Самый простой способ – работать непосредственно с хилафаксовыми файлами:
1) дать право доступа на чтение для файла /var/spool/hylafax/recvq/seqf
2) добавить в конец /etc/sudoers строки
asterisk ALL = NOPASSWD: /var/lib/asterisk/bin/fax2ftp.php
asterisk ALL = NOPASSWD: /var/lib/asterisk/bin/fax-process.pl

и не забыть вставить перенос строки
3) В файле seqf хранится номер имени следующего факса, его можно читать командой readfile
4) добавить sudo в обработку:

exten => in_fax,n,ReadFile(hylafax_num='/var/spool/hylafax/recvq/seqf',20)
exten => in_fax,n,Set(FAXFILE=/var/spool/hylafax/recvq/fax*${hylafax_num}.tif)
exten => in_fax,n,Dial(IAX2/iaxmodem1/${UNIQUEID})

exten => h,1,system(sudo /var/lib/asterisk/bin/fax2ftp.php -h 192.168.123.221 -u ftpuser -p ang.pth -l ${FAXFILE} -d ${EXT} -r "${call-from}-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${UNIQUEID}.tiff")
exten => h,n,system(sudo /var/lib/asterisk/bin/fax-process.pl --to ${faxemail} --from ${FAX_RX_FROM} --subject "Fax from ${call-from} ${CALLERID(name)}" --attachment ${CALLERID(number)}.pdf --type application/pdf --file ${FAXFILE});

iaxmodem, hylafax и LDAP 2009-12-01 11:56 / #

А не проще ли не писать такие могущие скрипты,а реализовать все запросы к LDAP через “ldapsearch”!

iaxmodem, hylafax и LDAP 2009-12-06 00:37 / #

модуля LDAP нету, он сторонний, RPM нету, у триксбокса нет компилятора.
А PHP – есть. Вот и воспользовались. К тому же неплохой пример agi получился.

iaxmodem, hylafax и LDAP 2009-12-07 14:58 / #

В чем проблема поставить openldap-clients?

iaxmodem, hylafax и LDAP 2009-12-08 14:17 / #

Ну так он и стоит. Но для астера модуля нету. А раз нету, то никак и не прикрутишь. Потому и написал на ПХП

iaxmodem, hylafax и LDAP 2009-12-08 16:31 / #

Так через команду System() или через shell script.
И спросить по атрибуту (внутренний номер) email.
Вот реальный пример
FaxDispath:

SENDTO=`ldapsearch -x -LLL -D “cn=user,dc=domain,dc=com” -w “password” telephoneNumber=$CALLID1 mail | grep mail | cut -f 2 -d “ “`; – получение email.

iaxmodem, hylafax и LDAP 2009-12-10 00:16 / #

Это понятно
но:
1) вызов приложения требует больше ресурсов, чем системной функции PHP
2) email нужен не только для отправки факсов, но и, к примеру, сообщений о пропущенных вызовах, голосовой почте, записей конференций и т.п.
3) помимо email извлекается также имя пользователя (при транзитных вызовах, при исходящих вызовах click-2-call, при приглашении в конференцию для подстановки имени и т.п.)

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

И потом: ну не работает FaxDispatch по-людски, непредсказуемо перестает работать и хоть тресни. Потому и решили все проблемы разом, причем средствами, удобными в отладке.

iaxmodem, hylafax и LDAP 2009-12-10 12:57 / #

извлечь “имя пользователя” нет особого на то труда. таким же способом.
А вот насчет “требует больше ресурсов” я пожалуй соглашусь.
И еще,у меня не разу не дал сбой FaxDispatch.

iaxmodem, hylafax и LDAP 2009-12-10 14:11 / #

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

iaxmodem, hylafax и LDAP 2009-12-11 13:41 / #

делать не скриптом, а командой System().

iaxmodem, hylafax и LDAP 2009-12-11 15:30 / #

ладно. пишем так:

exten => s,1,System(ldapsearch -x -LLL -D “cn=user,dc=domain,dc=com” -w “password” telephoneNumber=$CALLID1 mail | grep mail | cut -f 2 -d “ “)

И как узнать, какое значение вернула команда?

iaxmodem, hylafax и LDAP 2009-12-14 14:04 / #

пардон,не через System,а чезер функцию SHELL.

iaxmodem, hylafax и LDAP 2009-12-14 22:15 / #

Эта функция появилась совсем недавно, нет даже описания на voip-info.org и на voip.rus.net

Тем более что появилась она только в ветке 1.6, а мы используем не то, что 1.4 , а иногда даже 1.2. Функции нет, а работать надо. Бакпортировать – глупая возня, так как производительность вызова внешней программы будет низкой. Возможно, если на 50 абонентов поставить сервер с двухъядерным ксеоном тормоза не будут заметны.

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

Кстати, вызвать внешнюю программу и сохранить результат ее работы в переменную можно и альтернативным способом, этот способ будет работать и в 1.4

iaxmodem, hylafax и LDAP 2009-12-15 11:52 / #

знаю,что можно.
Данный пример на ветке 1.6.
У меня 1.6.0.15 все работает отлично!
Мать Intel Pentium 4 CPU 3.06GHz

iaxmodem, hylafax и LDAP 2009-12-15 12:25 / #

никто не сомневается, что у вас работает отлично, но что делать тем, у которых не 1.6.0.15???
Одно дело на Intel Pentium 4 CPU 3.06GHz повесить 20 абонентов. Другое – маршрутизировать 4 потока E1.

iaxmodem, hylafax и LDAP 2009-12-15 20:27 / #

ну на этой системе у меня 2 потока PRI, и поболее 20 абонентов.
Я предлагал вариант при версии 1.6.

iaxmodem, hylafax и LDAP 2009-12-15 22:58 / #

Ну что мы спорим? каждому – свое. Этим и хорош астериск, что есть множество способов решения задачи.

Еще хотел добавить, что и в elastix и в trixbox надо установить

yum install openldap-clients
yum install php-ldap

Оставить комментарий

Статьи

Корзина (0)

Корзина

Корзина пуста

Последние новости

X

Мы перезвоним Вам
за 60 секунд

Бесплатный звонок