Asterisk на Debian и SIP-транк к Zadarma: как мы поднимали офисную телефонию
Пошагово: собираем Asterisk 1.4 из исходников на Debian Lenny, заводим SIP-транк к Zadarma, пишем диалплан и чиним односторонний звук из-за NAT. Реальная установка, а не пересказ мануала.
IP-телефония на открытом Asterisk дешевеет и доходит до малого бизнеса, а SIP-операторы вроде Zadarma дают городской номер без железной АТС
К нам пришёл клиент с типовой задачей: пять менеджеров, один городской номер, и желание, чтобы звонки распределялись по людям, а не по принципу «кто первый добежал до трубки». Ставить коробочную АТС дорого и негибко. Значит, собираем IP-АТС сами на Asterisk, а городской номер и выход в город берём у SIP-оператора.
Сразу оговоримся: телефония - область, где «вроде работает» и «работает» разделяет пропасть. Звонок либо идёт с нормальным звуком, либо нет, и клиент это слышит немедленно. Поэтому здесь мы не спешим и не доверяем автоматике на слово.
Что берём
- Debian 5.0 Lenny - свежая стабильная ветка. Берём именно stable: пакеты в ней заморожены, прилетают только заплатки безопасности, а не внезапные мажорные обновления посреди рабочего дня.
- Asterisk из ветки 1.4 - проверенная стабильная линейка. Ставим не из репозитория, а собираем из исходников: так мы держим конкретную версию под контролем и не завязаны на то, что заморожено в пакетах Lenny.
- Никаких плат расширения и аналоговых линий: связь с городом - только через SIP-транк к оператору, всё по сети.
Собираем Asterisk из исходников
Ставим то, чем собирать (сам Asterisk из пакетов не тянем):
apt-get update
apt-get install build-essential libncurses5-dev libssl-dev libxml2-dev wget
Качаем исходники ветки 1.4, распаковываем и собираем:
cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.4.24.tar.gz
tar xzf asterisk-1.4.24.tar.gz
cd asterisk-1.4.24
./configure
make menuselect
make
make install
make samples
make config
make menuselect - это меню сборки: тут проверяем, что включены нужные кодеки и модуль chan_sip. make samples кладёт в /etc/asterisk конфиги с примерами, make config ставит init-скрипт. Запускаем и заходим в консоль:
/etc/init.d/asterisk start
asterisk -rvvv
Если консоль открылась и не сыплет ошибками - основа живёт. Дефолтные примеры конфигов мы на боевом сервере не оставляем: они щедро открывают то, что открывать не надо, поэтому sip.conf и extensions.conf пишем с нуля под себя.
Заводим SIP-транк к Zadarma
Логин, пароль и адрес SIP-сервера берём в личном кабинете оператора. Общие настройки и регистрацию описываем в sip.conf:
[general]
context=default
bindaddr=0.0.0.0
bindport=5060
disallow=all
allow=alaw
allow=ulaw
nat=yes
externip=НАШ.БЕЛЫЙ.IP
localnet=192.168.10.0/255.255.255.0
register => SIP-ЛОГИН:ПАРОЛЬ@sip.zadarma.com
Дальше - сам транк отдельной секцией:
[zadarma]
type=peer
host=sip.zadarma.com
fromdomain=sip.zadarma.com
username=SIP-ЛОГИН
fromuser=SIP-ЛОГИН
secret=ПАРОЛЬ
insecure=port,invite
context=from-zadarma
qualify=yes
nat=yes
disallow=all
allow=alaw
Перечитываем конфиг и смотрим, зарегистрировались ли мы у оператора:
asterisk -rx "sip reload"
asterisk -rx "sip show registry"
В выводе напротив sip.zadarma.com должно стоять Registered. Если висит Request Sent или Auth. Sent - значит, оператор нас не пускает: чаще всего перепутан логин, пароль или наш внешний адрес ещё не прописан у него в кабинете, и мы полчаса смотрим в лог, где английским по чёрному написано 403 Forbidden.
Внутренние телефоны
Каждому менеджеру - свой внутренний номер. В тот же sip.conf:
[1001]
type=friend
host=dynamic
secret=СЛОЖНЫЙ_ПАРОЛЬ
context=office
nat=yes
qualify=yes
[1002]
type=friend
host=dynamic
secret=ДРУГОЙ_ПАРОЛЬ
context=office
nat=yes
qualify=yes
host=dynamic означает, что телефон сам регистрируется на сервере с того адреса, где стоит. Пароли ставим длинные и разные: открытый в интернет SIP-порт сканируют перебором постоянно, и слабый пароль внутреннего номера - это чужие звонки за наш счёт.
Диалплан: кто куда звонит
Логику звонков пишем в extensions.conf. Один контекст для внутренних и исходящих, другой - для входящих с города.
[office]
; внутренние: набрал номер коллеги - позвонил коллеге
exten => 1001,1,Dial(SIP/1001,20)
exten => 1002,1,Dial(SIP/1002,20)
; выход в город: 9 и городской номер
exten => _9.,1,Dial(SIP/zadarma/${EXTEN:1},60)
exten => _9.,n,Hangup()
[from-zadarma]
; входящий с города звонит сразу всем менеджерам
exten => s,1,Dial(SIP/1001&SIP/1002,25)
exten => s,n,Hangup()
Разберём ключевое. Шаблон _9. ловит всё, что начинается с девятки, а ${EXTEN:1} отрезает эту девятку и отдаёт оператору чистый номер. Входящий звонок в контексте from-zadarma через Dial(SIP/1001&SIP/1002,25) звонит на оба телефона сразу - кто снял, тот и говорит. Перечитываем диалплан и проверяем:
asterisk -rx "dialplan reload"
asterisk -rx "sip show peers"
SIP-телефоны] --> B[Asterisk 1.4
Debian Lenny] B -->|SIP-транк| C[Zadarma] C --> D[Городская
телефонная сеть]
Где встряли на день: односторонний звук
Вечер ушёл на сборку и настройку. День - на одну проблему: звонок соединяется, гудки идут, трубку снимают, а дальше в одну сторону тишина. Один слышит, второй нет. Классика.
Дело в том, что SIP только договаривается о звонке, а сам голос идёт отдельным потоком (RTP) напрямую между точками. И если между Asterisk и оператором стоит трансляция адресов, этот голосовой поток упирается в наш шлюз и умирает, хотя сигнализация прошла. Лечится тремя вещами:
- Явно указать серверу его внешний адрес - это
externipиlocalnetв[general], которые мы уже прописали. Без них Asterisk сообщает оператору внутренний адрес вида192.168.x.x, и обратный голосовой поток уходит в никуда. - Задать диапазон RTP-портов в
rtp.conf(по умолчаниюrtpstart=10000,rtpend=20000) и пробросить этот диапазон UDP на шлюзе на машину с Asterisk. - Не надеяться на автоопределение адреса. Ровно из-за этой надежды мы и потеряли полдня: казалось, что сервер сам разберётся, кто он снаружи. Не разберётся.
К вечеру второго дня телефония работала: входящие распределялись по менеджерам, исходящие уходили через оператора, звук был чистым в обе стороны. Отдельно мы свели телефонию с их системой учёта, чтобы карточка клиента открывалась на входящем - такие стыковки разных систем и превращают «телефонию» в рабочий инструмент, а не просто в звонящий ящик.
Вывод без пафоса: поднять Asterisk - это вечер. Заставить голос ходить чисто через NAT - это отдельный навык, который окупается ровно один раз, когда клиент не слышит бульканья в трубке. К слову, привычку сразу фиксировать, за что отвечаем мы, а за что канал и оператор, мы завели ещё на одном сервере в подсобке несколькими годами раньше.
- Первый выделенный сервер клиента и чему он нас научил · 15 сентября 2003