воскресенье, 3 апреля 2016 г.

Соединение двух Asterisk через SIP

В прошлой заметке Шаблоны и настройка звонков между SIP-клиентами в Asterisk мы научились соединять между собой абонентов одной станции. В этот раз попробуем настроить связь между двумя станциями Asterisk, чтобы дать возможность общаться между собой их абонентам. Для этого я воспользовался настольным компьютером и ноутбуком. Соответственно, в описании ниже они называются desktop и notebook.

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

1. Контекст для тестовых номеров

В прошлых заметках были настроены тестовые номера 5XX. Выделим их в отдельную секцию с именем test. Откроем файл номерного плана /etc/asterisk/extensions.conf на телефонной станции desktop и сформируем такую секцию:
[test]

exten => 500,1,Playback(demo-echotest)
same  =>     n,Echo()
same  =>     n,Playback(demo-echodone)

exten => 501,1,MusicOnHold()

exten => 502,1,SayDigits(${CALLERID(num)})

exten => 503,1,SayNumber(${CALLERID(num)})

exten => 504,1,SayNumber(${CALLERID(num)})
same  =>     n,Wait(1)
same  =>     n,SayDigits(${CALLERID(num)})
Чтобы с телефонов, подключенных к станции desktop, по-прежнему можно было позвонить на тестовые номера, добавим в контекст internal строчку, подключающую контекст test:
[internal]
include => test

exten => _1XXX,1,Dial(SIP/${EXTEN})
На станции notebook в файле номерного плана /etc/asterisk/extensions.conf контекст internal при этом выглядит так:
[internal]

exten => _2XXX,1,Dial(SIP/${EXTEN})
Как обычно, чтобы новый номерной план вступил в силу, выполним команду:
# asterisk -rx 'dialplan reload'
2. Создание учётных записей

Откроем файл /etc/asterisk/sip.conf на станции desktop и добавим туда шаблон учётных записей SIP для телефонных станций и саму учётную запись SIP на основе этого шаблона, через которую телефонная станция desktop будет принимать звонки от телефонной станции notebook:
[asterisk_sip](!)
language=ru
type=friend
context=stations
host=dynamic
insecure=invite,port
trunk=yes

[notebook](asterisk_sip)
secret=notebook_password
deny=0.0.0.0/0.0.0.0
permit=169.254.254.4
Телефонная станция notebook сможет зарегистрироваться только с IP-адреса 169.254.254.4. Входящие звонки будут попадать в контекст stations. Звонящей телефонной станции нужно будет авторизоваться только при регистрации, а авторизация при поступлении запросов invite проверяться не будет (insecure=invite,port). Это значит, что с удалённой телефонной станции могут поступать звонки от телефонов, отсутствующих на локальной телефонной станции. Эта настройка очень важная. Если её пропустить, входящие звонки будут отбрасываться как неавторизованные, поскольку будут поступать не от имени удалённой телефонной станции, для которой создана учётная запись, а от имени телефона, подключенного к ней.

Теперь откроем файл /etc/asterisk/sip.conf на станции notebook и впишем туда следующие симметричные настройки:
[asterisk_sip](!)
language=ru
type=friend
context=stations
host=dynamic
insecure=invite,port
trunk=yes

[desktop](asterisk_sip)
secret=desktop_password
deny=0.0.0.0/0.0.0.0
permit=169.254.254.1
Теперь выполним на обеих телефонных станциях следующую команду, чтобы на них появились учётные записи SIP:
# asterisk -rx 'sip reload'
3. Входящие звонки с удалённых станций

Звонки, поступающие от удалённых станций будут попадать в контексты stations. Удалённые станции должны иметь возможность дозвониться на номера местной станции. Впишем в файл /etc/asterisk/extensions.conf на станции desktop соответствующий контекст:
[stations]
include => test

exten => _1XXX,1,Dial(SIP/${EXTEN})
Соответственно, чтобы абоненты удалённых станций могли позвонить абонентам станции notebook, впишем в файл /etc/asterisk/extensions.conf на станции notebook симметричный контекст:
[stations]

exten => _2XXX,1,Dial(SIP/${EXTEN})
Как можно увидеть, тестовые номера 5XX будут обслуживаться станцией desktop.

Выполним на обеих станциях команды, которые создадут на них контексты stations:
# asterisk -rx 'dialplan reload'
4. Взаимная регистрация телефонных станций

Теперь заставим обе телефонные станции подключиться друг к другу. Для этого впишем в секцию globals в файле /etc/asterisk/sip.conf на станции desktop такие настройки:
register => desktop:desktop_password@169.254.254.4/notebook
Эта строчка предписывает зарегистрироваться на станции notebook под именем desktop и с паролем desktop_password. Установленное SIP-подключение будет называться notebook. Это название в дальнейшем можно будет использовать в номерном плане для вызова абонентов, подключенных к станции notebook.

Теперь впишем в секцию globals в файле /etc/asterisk/sip.conf на станции notebook симметричные настройки:
register => notebook:notebook_password@169.254.254.1/desktop
Выполним на обеих телефонных станциях команду, после которой станции должны будут зарегистрироваться друг на друге:
# asterisk -rx 'sip reload'
Чтобы проверить, зарегистрировалась ли эта станция на удалённой, можно воспользоваться такой командой:
# asterisk -rx 'sip show registry'
Чтобы проверить, зарегистрировалась ли удалённая станция на этой, пригодится такая команда:
# asterisk -rx 'sip show peers'
5. Исходящие звонки на удалённые станции

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

Откроем файл /etc/asterisk/extensions.conf на станции desktop и приведём контекст internal к следующему виду:
[internal]
include => test

exten => _1XXX,1,Dial(SIP/${EXTEN})

exten => _2XXX,1,Dial(SIP/notebook/${EXTEN})
Из этого контекста видно, что звонки на тестовые номера и номера 1XXX будут обрабатываться самой станцией desktop, а звонки на номера 2XXX будут направляться через SIP-подключение, помеченное как notebook. Там они попадут в контекст stations, в котором предписывается направлять вызовы SIP-абонентам самой станции notebook.

Откроем файл /etc/asterisk/extensions.conf на станции notebook и приведём контекст internal к такому виду:
[internal]
exten => _5XX,1,Dial(SIP/desktop/${EXTEN})

exten => _1XXX,1,Dial(SIP/desktop/${EXTEN})

exten => _2XXX,1,Dial(SIP/${EXTEN})
Звонки на номера 2XXX будут обрабатываться внутри самой станции notebook, а звонки на тестовые номера 5XX и номера 1XXX будут направляться через SIP-подключение, названное desktop. То есть - будут отправляться на станцию desktop, где так же попадут в контекст stations. Там же уже прописано, как нужно обрабатывать входящие звонки на эти номера.

Осталось перезагрузить номерные планы на обеих станциях:
# asterisk -rx 'dialplan reload'

Теперь можно пробовать звонить.
6. Возможные проблемы

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

Первая проблема заключалась в том, что при поступлении звонка с удалённой станции, звонок отклонялся как неавторизованный. Выглядело это как отказ станции desktop принимать звонок с номера 2000, принадлежащего станции notebook (и наоборот):
[Mar 15 20:33:41] NOTICE[17686][C-00000077] chan_sip.c: Failed to authenticate device <sip:2000@169.254.254.4>;tag=as6c5edf7c
Со стороны звонящей станции (notebook) эта же ошибка выглядела следующим образом:
[Mar 15 20:33:41] WARNING[1146][C-00000000] chan_sip.c: Received response: "Forbidden" from '<sip:2000@169.254.254.4>;tag=as6c5edf7c'
Решается эта проблема прописыванием опции insecure=invite,port в настройки SIP-подключения для удалённой станции в файле /etc/asterisk/sip.conf

Вторая проблема была довольно специфичной. При удачном звонке с телефонного аппарата, обслуживаемого одной станцией, на телефонный аппарат, обслуживаемый другой станцией, напрочь отсутствовал звук. Я сразу подумал, что не проходит трафик RTP и проверил, на всякий случай, настройки фаерволлов на обеих станциях. Но с фаерволлом оказалось всё в порядке. Потом попытался поймать RTP-трафик сниффером, но не смог. И уже только потом сообразил, что телефонные шлюзы отправляют голосовой трафик другу напрямую. Такая особенность была мне известна, но в тот момент она вылетела у меня из головы. Я вспомнил, что на коммутаторе настроена изоляция портов. Несмотря на то, что оба голосовых шлюза были в одной VLAN на соседних портах, трафик напрямую между портами не ходил, пока я не разрешил портам общаться между собой.

Комментариев нет: