Подключаем Asterisk к IAX и SIP серверам
Сергей «grinder» Яремчук (grinder@ua.fm, tux.in.ua)
Часто компания имеет несколько офисов, удаленных друг от друга. Использовать только один сервер телефонии в таком случае очень накладно. Кроме того, нельзя забывать о том, что в настоящее время существует достаточно сервисов, предлагающих выход в телефонную сеть по приемлемым тарифам (например, ). Подключаясь к ним, можно существенно сэкономить на междугородних телефонных переговорах и получить прямой номер. Так что давай попробуем подружить наш Asterisk с VoIP-серверами, работающими по протоколам IAX и SIP.
Содержание:
- Проблемы и протоколы
- Подключаемся к другому серверу
- Настройка диалплана
- Подключаемся к sipnet.ru
- Врезка: Правила iptables
Значок * (астериск), который у программистов и администраторов ассоциируется с любой возможной последовательностью, полностью отражает подход разработчиков при создании одноименного сервера IP-телефонии. Как результат, IP-PBX Asterisk действительно может быть применен практически в любом случае, где уместно упоминание о VoIP. Он может работать как автономный сервер, обслуживая абонентов своей сети, так и как шлюз в обычную телефонную или удаленную VoIP-сеть.
Итак, будем считать, сервер Asterisk успешно установлен, и абоненты уже звонят друг другу (см. статью «Строим телефонную сеть» в X_11_2007), поэтому сразу переходим к настройке связки двух серверов. Первым делом следует побеспокоиться о наличии хорошего канала в Интернет, обладающего достаточной пропускной способностью. Несмотря на то, что VoIP трафик спокойно относится к потерям отдельных пакетов, он очень критичен к задержкам пакетов в сети, поэтому спутниковые каналы не подойдут. Кроме того, желательно иметь хотя бы с одной стороны постоянный IP-адрес, в этом случае проблем с настройками точно не будет.
Процедура установления связи в VoIP (и используемые термины тоже) зависят от протокола. Для связи двух серверов Asterisk можно использовать протоколы H.323, SIP или IAX/IAX2 (был еще MGCP, но о нем вряд ли стоит сегодня говорить). Первая версия H.323, благодаря стараниям ITU (International Telecommunications Union), появилась в 1996 году. И хотя его совершенствование идет постоянно, большинство провайдеров перешли на протокол управления сессиями SIP, изначально ориентированный на работу в Интернет. Предлагаемый разработчиками новый стандарт позволяет устанавливать пользовательские сеансы, включающие передачу голоса, видео, мгновенные сообщения и даже онлайн игры. По сравнению с H.323, он более прост в реализации, независим от транспортного уровня (может работать по UDP, TCP, ATM и другим). Правда, в нумерации версий SIP есть небольшая путаница. Первая версия стандарта, получившая обозначение SIP 2.0, определена в RFC 2543. В RFC 3261 () он был уточнен, но номер версии так и остался 2.0. Многие текущие решения основаны на промежуточных версиях стандарта. Протокол SIP чаще всего используется провайдерами VoIP, поэтому при подключении к сервисам вроде придется использовать именно этот протокол.
Протокол IAX (Inter-Asterisk eXchange) разработан как альтернативный протокол обмена VoIP данными между Asterisk. Первая версия протокола уже устарела и практически не применяется, поэтому обычно термины IAX и IAX2 обозначают именно вторую версию. IAX2 позволяет совмещать множество голосовых потоков и передавать их внутри одного канала (транка), что уменьшает накладные расходы, связанные с передачей заголовков IP-пакетов, что особенно ощутимо при большом количестве звонков. В отличие от H.323 и SIP, он лучше приспособлен к работе через NAT. Чтобы связать два сервера Asterisk, это наиболее простой и поэтому рекомендуемый вариант.
Протоколы H.323 и IAX2 стандартизированы полностью, а в SIP только сигнализирующая часть, сервисы же могут использовать свои стандарты и развиваться любыми группами разработчиков. Более полное описание и сравнение этих протоколов можно найти на сайте .
Подключаемся к другому серверу
Так как у нас два сервера Asterisk, для организации соединения между ними будем использовать протокол IAX2. Все настройки работы Asterisk по этому протоколу производятся в файле iax.conf. Один сервер настраивается для исходящих звонков — peer, а другой принимает звонки – user. Если вызовы предполагается совершать с обоих направлениях, то в конфигурационном файле следует создать две соответствующие учетные записи. Можно использовать и тип пользователя friend, то есть разрешить совершать звонки в обоих направлениях, но тогда созданная учетная запись сможет принимать вызов только с указанного узла (см. директиву host), а такой вариант не всегда приемлем. В том случае, когда один из хостов имеет динамический адрес или работает из-за NAT, он должен зарегистрироваться на втором сервере. Параметры, определенные в секции general, будут действительны для всех клиентов, хотя большую часть из них при необходимости можно переопределить в индивидуальных секциях.
$ sudo mcedit /etc/asterisk/iax.conf [general] ; порт, на котором принимаются звонки ;bindport=4569 ; IP-адрес интерфейса, принимающего звонки, иначе прослушиваются все ;bindaddr=192.168.0.1 ; полезный параметр, снижающий задержки при сложных диалпланах ;iaxcompat=yes ; отключение проверки контрольных сумм UDP пакетов ;nochecksums=no ; вводим задержки при ошибочном вводе пароля, чтобы затруднить их подбор delayreject=yes ; включаем поддержку великого и могучего language=ru ; мелодия при ожидании mohinterpret=default mohsuggest=default ; полоса пропускания low, medium или high, будет влиять на используемые кодеки bandwidth=high ; при помощи директив "allow" и "disallow" указываем разрешенные ; и запрещенные кодеки, значение "all" соответствует всем форматам disallow=g723.1 disallow=lpc10 ; установка бита Type of Service (TOS) в исходящих IP-пакетах ; для IAX, в отличие от SIP, значение устанавливается для всех видов связи ; все варианты можно подсмотреть в файле doc/ip_tos.txt tos=lowdelay ; если в течение 2000 мс не получаем ответ, соединение прерывается ; вместо yes или no можно указать свое значение в мс autokill=yes ; пользователь, принимающий звонки [incominguser] type=user auth=md5,plaintext,rsa secret=password ; для type=user можно использовать несколько записей secret context=incoming ; пользователь для исходящих звонков [outgoinguser] type=peer host=hostname.com ; host=dynamic ; в этом случае требуется команда register auth=md5 secret=secret_word username=username ; последние два параметра могут быть включены в команду Dial
Теперь небольшое пояснение по поводу auth. В IAX авторизация пользователей возможна одним из трех методов. При значениях md5 и plaintext пароль в файле хранится в открытом виде, но в первом случае по сети передается его хэш, что препятствует перехвату. Вариант plaintext является самым незащищенным, поэтому стоит исключить его применение в продакшн-системах. При rsa для авторизации используется связка публичного и приватного ключа. Хотя это и более сложный в настройке, но зато самый защищенный вариант, так как расшифровать информацию можно только получив приватный ключ. Список известных публичных ключей с расширением pub приводится через двоеточие в параметре inkeys, а приватных — в outkey. Если с абонентами выбранного узла требуется одновременно вести нескольких разговоров, следует установить значение параметра trunk в yes.
Здесь нужно сделать небольшое замечание по безопасности, а именно по поводу использования контекстов, к которым будут иметь доступ пользователи «извне». Если все пользователи определены в одном контексте, в том числе и с использованием директивы include, то любой звонящий сможет получить доступ не только к внутренним номерам и серверу голосовой почты, но и к другим сервисам, например, у него появится возможность совершать исходящие междугородние звонки. Не всем и не всегда это необходимо или положено, поэтому лучше все правила, относящиеся к звонкам извне или наружу, вынести в отдельный контекст, например, incoming.
Теперь переходим к настройке плана набора. В самом простом случае в файле extensions.conf можно создать контекст incoming, где просто вписать пользователя, принимающего звонки:
[incoming] exten => grinder,1,Dial(IAX2/grinder)
А для исходящих создать свой контекст, вроде:
[outgoing] exten => 4000,1,Dial(IAX2/outgoinguser/4000)
Но такой подход можно использовать при небольшом количестве номеров. Иначе проще заставить сервер Asterisk автоматически получать контекст с удаленного сервера или перенаправлять вызовы к нему. Соответственно и реализовать это можно несколькими вариантами. Например, чтобы передать свой диалплан на удаленный сервер, используем конструкцию вроде:
switch => IAX2/<username>:[<password>]@<myserver>/<mycontext>
При этом параметры username, password должны быть прописаны в контексте «mycontext» iax.conf на удаленном сервере (myserver). Экстеншены могут быть выражены цифрами и буквами или заданы при помощи шаблона. Если экстеншен начинается с подчеркивания ‘_’, то он воспринимается как шаблон. В шаблоне можно использовать некоторые специальные символы. Например, X – соответствует числам от 0 до 9, Z – 1-9, N — 2-9, точка ‘.’ соответствует одному или нескольким числам, а ‘!’ – нулю или более символам, если числа заключены в скобки [1237], то будет принято лишь одно из них. Теперь, когда все пояснения даны, приведу рабочий пример:
$ sudo mcedit /etc/asterisk/extensions.conf
[general]
static=yes
writeprotect=no
; при такой конфигурации можно сохранить диалплан командой «save dialplan»
[default]
exten => _5XXXХ,1,Goto,out|${EXTEN}|1
; описываем план набора для удаленного сервера
; цифра 5 вначале - нечто вроде выхода на межгород
[out]
exten => _5XXXХ,1,StripMSD,3
; StripMSD удаляет 1 символ (по умолчанию) с начала номера
exten => _XXXХ,2,Goto,1
switch => IAX2/outgoinguser: secretword@hostname.com/incominguser
[incoming]
exten => grinder,1,Dial(IAX2/grinder)
Чтобы проверить регистрацию на другом сервере, необходимо ввести в CLI Asterisk команду «iax2 show registry».
Очень полезной при организации связки двух удаленных серверов является возможность ограничения по времени при помощи timing list. Для этого следует, используя инструкцию include, указать промежуток времени в формате:
<диапазон времени>|<день недели>|<дни месяца>|<месяц>
Например, рабочее время с понедельника по пятницу будет выглядеть так:
include => daytime|9:00-18:00|mon-fri|*|*
Сегодня доступно большое количество сервисов, которые позволяют совершать звонки на стационарные и мобильные телефоны, находящиеся в любой стране мира. Стоимость таких услуг на порядок меньше, чем предоставляемые операторами местной проводной связи. Кроме того, компания, подключившись к одной из таких VoIP-сетей, как правило, получает прямой номер во многих городах России и других странах, что очень удобно для ее клиентов. Для примера научим сервер Asterisk подключаться к сети sipnet.ru.
Перед настройкой сервера следует создать учетную запись. Заходим на сайт и заводим себе аккаунт. Для этого необходимо заполнить все поля в появившемся окне, ввести контрольное число и нажать кнопку «Продолжить регистрацию». После подтверждения регистрации в письме, которое придет на указанный e-mail, активируется учетная запись со статусом «Тестовый доступ». Выбранным логином можно пользоваться в течение 30 дней, после чего следует пополнить счет, или запись будет удалена. Тестовый доступ позволяет совершать звонки по бесплатным направлениям (стационарные телефоны в Москве и Петербурге) и абонентам sipnet, последним можно отсылать мгновенные сообщения. Чтобы перейти на тарифный план «Абонентский доступ» и звонить за пределы России и на мобильные телефоны, достаточно положить на счет всего 3 у.е.
При регистрации тебе будет выдан 7-ми значный номер SIP ID, плюс понадобятся указанные тобой логин и пароль. Предположим, это 1234567, grinder и password. Теперь в файл sip.conf дописываем такие строки:
$ sudo mcedit /etc/asterisk/sip.conf [general] videosupport=yes useragent=SipPhone register=grinder:password@sipnet.ru/1234567 [sipnet] type=friend username=grinder secret=password callerid=sipnet host=sipnet.ru nat=no fromuser=sipnet fromdomain=sipnet.ru dtmfmode=rfc2833 insecure=invite context=sipnet disallow=all allow=alaw
Большая часть параметров тебе уже должна быть знакома. Поэтому пару слов об остальных. Параметр «insecure=invite» позволяет подключаться извне без ввода пароля. Для обозначения типа тонального набора DTMF (Dual Tone Multi Frequency) используется dtmfmode с возможными значениями rfc2833, info, inband и auto. Параметр fromdomain указывает, какой домен будет использоваться в заголовках (по умолчанию локальный — domain). Этот параметр не обязателен, но некоторые сервисы его требуют.
Теперь переходим к настройке диалплана. Все городские номера, используемые в , можно просмотреть в . Следует выбрать нужные и прописать их в extensions.conf.
$ sudo mcedit /etc/asterisk/extensions.conf
[Moscow]
exten => _7495XXXXXXX,1,SetCallerID("SipPhone" <1234567>)
exten => _7495XXXXXXX,2,Dial(SIP/sipnet/${EXTEN},120)
exten => _7495XXXXXXX,3,HangUp
И подключаем этот экстеншен в выбранные группы абонентов при помощи записи:
include => Moscow
Аналогичным образом прописываются планы набора для других городов. Закончив с редактирование файлов, вводим в CLI команду «reload». После перезапуска Asterisk в верхнем углу меню «Персональные данные» должна появиться информация о подключенном клиенте Asterisk PBX (или что написано в useragent файла sip.conf). Команда «sip show registry» также покажет, что подключение выполнено:
CLI> sip show registry Host Username Refresh State Reg.Time sipnet.ru:5060 grinder 105 Registered Tue, 16 Oct 2007 23:10:04
Теперь можно звонить, используя .
Не лишним будет указать некоторые полезные правила iptables. Чтобы пакеты беспрепятственно проходили через фильтр, пишем:
Для протокола SIP:
iptables -A INPUT -p udp -m udp --dport 5004:5082 -j ACCEPT
Для протокола IAX2:
iptables -A INPUT -p udp -m udp --dport 4569 -j ACCEPT
Медиапотоки RTP:
iptables -A INPUT -p udp -m udp --dport 10000:20000 -j ACCEPT
Некоторые используют протокол MGCP (media gateway control protocol):
iptables -A INPUT -p udp -m udp --dport 2727 -j ACCEPT
Для установки TOS в исходящих пакетах используем (для SIP) такое правило:
iptables -A OUTPUT -t mangle -p udp -m udp --dport 5060
-j DSCP --set-dscp 0x28
iptables -A OUTPUT -t mangle -p udp -m udp --sport 10000:20000
-j DSCP --set-dscp 0x28
Статья опубликована в ноябрьском номере журнала «Xakep» за 2007 год.





