Показаны сообщения с ярлыком sip. Показать все сообщения
Показаны сообщения с ярлыком sip. Показать все сообщения

воскресенье, 15 мая 2016 г.

Краткий обзор программного телефона SFLphone

Итак, как я и обещал, в этой заметке я сделаю краткий обзор программного телефона SFLphone, который привлёк моё внимание в качестве программы, пригодной для секретарей, диспетчеров и операторов, т.к. умеет работать с несколькими звонками одновременно и соединять абонентов между собой.

Программа имеет несколько разных интерфейсов и разбита на несколько пакетов:
$ apt-cache search sflphone
sflphone-daemon - SIP and IAX2 compatible VoIP phone - core daemon
sflphone-data - SIP and IAX2 compatible VoIP phone - common data
sflphone-evolution - SIP and IAX2 compatible VoIP phone - Evolution plugin
sflphone-gnome - SIP and IAX2 compatible VoIP phone - GNOME client
sflphone-kde - SIP and IAX2 compatible VoIP phone - KDE client
Как видно, имеются варианты интерфейсов для рабочих сред KDE и GNOME, а также плагин для почтового клиента Evolution. Ещё два пакета содержат демон и данные для программы. Демон на самом деле и является программным телефоном: внутри него происходит работа с устройствами компьютера и сетью. Интерфейс программы взаимодействует с демоном через DBUS и занимается лишь передачей команд в демон и отображением его состояния. В этой заметке я рассмотрю только интерфейс для среди GNOME. Установим в систему соответствующий пакет:
# apt-get install sflphone-gnome

Общий вид программы:

Под меню видно имеется окно со списком текущих разговоров, ниже - регуляторы громкости для микрофона и наушников, ещё ниже - номеронабиратель. Справочник контактов спрятан в отдельное окно, что мне показалось несколько неудобным.

Чтобы попасть в настройки программы, нужно выбрать пункт меню "Правка", а в раскрывшемся списке выбрать пункт "Настройки":


Из всех имеющихся настроек особенный интерес представляют настройки звука:

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

Второй интересный пункт, это выбор видеоустройств:

К сожалению, совершить видеозвонок с использованием этого программного телефона мне не удалось. Но это, наверное, не столь важно для рабочего места секретаря.

Чтобы настроить учётные записи, нужно в основном окне программы выбрать пункт "Правка", а в раскрывшемся списке выбрать пункт "Аккаунты":


После этого откроется список учётных записей:

Здесь имеется отдельная учётная запись под названием "IP2IP". В ней хранятся настройки, которые будут использоваться для прямых вызовов, без использования какой-либо учётной записи. Можно добавлять, удалять и редактировать учётные записи, а также временно отключать их, снимая галочку.

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


Во вкладке аудионастроек можно выбрать используемые кодеки, их приоритеты, звук входящего звонка и режим передачи тоновых сигналов:


Во вкладке видеонастроек аналогично, можно выбрать используемые кодеки и их приоритеты, а также включить или выключить использование видео:

Ещё раз скажу, что совершить видеозвонок при использовании этой программы мне не удалось.

Во вкладке дополнительных настроек можно указать номер используемого UDP-порта, внешний IP-адрес и указать STUN-сервер:

В отличие от Ekiga, тут все настройки легко доступны и их можно настраивать для каждой учётной записи отдельно.

В последней вкладке можно указать настройки шифрования для сеансов SIP и для трафика RTP:

Я ни то ни другое настраивать пока не пробовал.

Теперь перейдём к самому интересному - к соединению абонентов друг с другом.

Вот так входящий звонок отображается в правом верхнем углу экрана:

Принят звонок можно щелчком по этому всплывающему окну.

Тот же звонок отображается в списке разговоров. Взять трубку можно либо нажатием на пиктограмму с телефонной трубкой и зелёной стрелкой, либо через меню "Вызов", либо сочетанием горячих клавиш, либо через контекстное меню, как это показано ниже:

Предположим, что в процессе разговора выясняется, что звонящего нужно переключить на специалиста, который более компетентен в обсуждаемом вопросе.

Ставим входящий звонок на паузу:

Опять же - поставить на паузу можно сочетанием горячих клавиш, либо через меню "Вызов".

Стоящий в очереди звонок отображается следующим образом:

При этом телефонная станция воспроизводит ожидающему абоненту музыку.

Пока звонок стоит в очереди, совершаем исходящий звонок:


Этот же исходящий звонок будет отображаться всплывающей надписью в правом верхнем углу экрана:


Дозвонившись до специалиста, объясняем ему суть вопроса, который обсуждался с ожидающим абонентом и предлагаем им поговорить друг с другом.

Соединение абонентов друг с другом:

После соединения абонентов друг с другом, оба звонка исчезают из списка в программе и продолжают общаться между собой уже без нашего участия.

Как вы заметили, кроме передачи звонка другому абоненту, имеется ещё возможность создать конференцию. Во отличие от соединения двух абонентов между собой, когда соединённые звонки пропадают из списка, конференция остаётся в списке. Конференция поддерживается самим демоном sflphone, при этом не используются функции конференций Asterisk. Выглядит конференция следующим образом:

Управляет конференцией абонент, использующий sflphone. Он может поставить конференцию на паузу, в таком случае все абоненты будут находиться в режиме ожидания и слушать музыку. Когда от конференции отключается абонент sflphone, конференция уничтожается, а все другие абоненты отключаются от неё.

В процессе использования перенаправлений звонков обнаружил, что телефонные шлюзы Cisco ATA 186 не поддерживают функцию REINVITE, которая позволяет абоненту с другой стороны попросить согласовать параметры звука с другим абонентом. Именно эта опция используется для перенаправления звонков. На случай подобных телефонных шлюзов в Asterisk имеется опция canreinvite. Чтобы указать, что телефонный шлюз не умеет переключаться на другого абонента, нужно указать в настройках SIP-пользователя опцию canreinvite=no. В этом случае Asterisk будет выступать посредником при трансляции звука. При установлении первого сеанса звук от обоих абонентов будет проходить через Asterisk. Когда нужно будет выполнить переключение, Aterisk самостоятельно выполнит REINVITE с одним из абонентов, продолжая трансляцию звука через себя для другого абонента, который не поддерживает REINVITE.

воскресенье, 8 мая 2016 г.

Настройка видео в Asterisk и Ekiga

В прошлой заметке Краткий обзор программного телефона и клиента обмена мгновенными сообщениями Ekiga я обмолвился о том, что этот программный телефон позволяет, при наличии веб-камеры, в процессе разговора ещё и обмениваться видео. Я заинтересовался этой возможностью и решил попробовать настроить обмен видео через Asterisk.

1. Включение поддержки видео в SIP

Чтобы включить передачу видео через Asterisk, нужно в файле /etc/asterisk/sip.conf в раздел general добавить опцию:
videosupport=yes

2. Настройка кодеков в учётных записях SIP-абонентов

Далее, в том же файле в настройках учётных записей SIP, под которыми на Asterisk регистрируются программы Ekiga, нужно явным образом прописать список поддерживаемых кодеков:
disallow=all
allow=gsm
allow=alaw
allow=ulaw
allow=h264
allow=h261
allow=mpeg4
Как оказалось, по умолчанию были разрешены только аудиокодеки и один видеокодек h261. Здесь я не указал ещё два возможных видеокодека - h263 и h263p, при использовании которых видео почему-то не работало.

3. Настройка кодеков в учётных записях SIP-транков

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

Сразу замечу, что передавать видео между разными станциями по протоколу IAX2 мне не удалось.

4. Применение настроек Asterisk

Далее, чтобы новые настройки вступили в силу, нужно попросить Asterisk перечитать настройки модуля sip:
# asterisk -rx 'sip reload'
5. Настройка кодеков в Ekiga

Открываем меню "Правка", выбираем пункт "Параметры". В открывшемся окне "Настройки Ekiga" разворачиваем ветку "Звук" и выбираем пункт "Кодеки". Отмечаем только кодеки PCMU (соответствует ulaw в Asterisk), PCMA (соответствует alaw в Asterisk) и gsm:


Теперь разворачиваем в том же окне ветку "Видео" и выбираем в ней пункт "Кодеки". Отмечаем только кодеки H264 и MP4V-ES (соответствует mpeg4 в Asterisk). Можно отметить ещё кодек H261, но с помощью стрелок выставить его приоритет ниже кодека H264. По моему опыту, у него ниже качество (разрешение 176x144) и работает он менее стабильно (может рассыпаться на крупные кубики). Кодеки H263 и H263-1998 (соответствует h263p в Asterisk) у меня не заработали, поэтому их использование отключил.


6. Тестовый звонок

Когда всё заработало, выглядело это вот так:

Я сидел за компьютером с ноутбуком на коленях, поэтому в окне меня видно с двух сторон :) Гарнитура была подключена только к одному из компьютеров и лежала на столе.

Стоит приготовиться к тому, что видео не заработает сразу и придётся подбирать кодеки, с которыми оно, наконец, заработает.

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

воскресенье, 1 мая 2016 г.

Краткий обзор программного телефона и клиента обмена мгновенными сообщениями Ekiga

Отвлечёмся ненадолго от Asterisk и обратимся к смежной теме - программным телефонам для Linux.

Ekiga - это программа, сочетающая в себе возможности программного телефона, поддерживающего протоколы SIP и H.323, и клиента обмена мгновенными сообщениями, поддерживающего протокол Jabber/XMPP. Кроме звонков и обмена текстовыми сообщениями, программа при наличии веб-камеры, позволяет также обмениваться с собеседником видео. Программа была создана в рамках одноимённого сервиса - ekiga.net. В некотором роде его можно считать аналогом Skype, но построенном полностью на открытых технологиях. Конечно, не стоит считать Ekiga полным аналогом Skype, т.к. в Skype имеется много других возможностей - создание конференций, "приземление" звонков (то есть звонки на телефонные номера телефонной сети общего пользования) и т.п.

Установить программу можно очень просто, из репозиториев:
# apt-get install ekiga
Главное окно программы выглядит следующим образом.

Здесь можно увидеть список контактов. Между протоколами не делается никаких различий, все контакты, будь то SIP или XMPP, выводятся в общий список. Поддерживается группировка контактов.

При нажатии на соответствующую кнопку можно переключиться в окно номеронабирателя:

Это окно может оказаться полезным, если нужно позвонить на некий телефонный номер однократно. Постоянных собеседников удобнее добавить в список контактов.

Следующая кнопка отображает историю звонков:


Окно переписки с абонентами Jabber/XMPP выглядит следующим образом:

Стоит отметить, что программа обладает весьма ограниченной поддержкой протокола Jabber/XMPP. Фактически можно видеть только статусы собеседников и переписываться с ними. Нельзя посмотреть профиль собеседника, нельзя отправить или принять файл.

Список учётных записей можно открыть через меню "Правка" - "Учётные записи" или нажатием Ctrl-E:


Вот так выглядят настройки учётной записи Jabber/XMPP:

Настройки очень бедные. Нельзя задать прокси или настроить шифрование.

Вот так выглядят настройки учётной записи SIP:

Тоже очень бедные настройки. Нельзя задать STUN-прокси, нельзя выбрать прослушиваемый интерфейс и порт. Программа будет использовать UDP-порт 5060 и сообщать при регистрации на SIP-прокси IP-адрес первого попавшегося интерфейса, кроме lo.

Авторы явно были под влиянием Gnome HIG и убрали все настройки, которые посчитали лишними, в аналог реестра Windows - каталог .gconf/ с XML-файлами. Чтобы получить доступ к остальным настройкам, нужно установить программу gconf-editor из одноимённого пакета. Например, при помощи такой команды:
# apt-get install gconf-editor
При запуске команды gconf-editor от имени обычного пользователя можно исправлять настройки этого пользователя. Например, прослушиваемый порт можно поменять в параметре apps - ekiga - protocols - sip - listen_port:

Мне это понадобилось сделать для того, чтобы запустить Ekiga и Asterisk на одном и том же компьютере. Поскольку порт 5060 уже используется Asterisk, Ekiga должна использовать другой порт. То же самое может потребоваться сделать, если за компьютером работают несколько пользователей одновременно (мало ли в жизни бывает?) и каждому из них нужно использовать свой SIP-телефон (обычно SIP-телефоны по умолчанию прослушивают UDP-порт 5060, так что одного порта на всех не хватает). К сожалению, это не единственный случай, когда разработчики современных программ для Linux забывают, что Linux - это многопользовательская система, в которой одновременно может работать несколько пользователей, а один и тот же пользователь может открыть одновременно несколько сеансов.

Поменять используемый STUN-прокси тоже можно через gconf-editor:

Как видно, отвечают за него параметры enable_stun и stun_server в ветке apps - ekiga - general - nat.

Ещё один полезный раздел настроек - это список используемых программой портов. В ветке apps - ekiga - protocols - ports есть параметры tcp_port_range и udp_port_range:

Если на компьютере настроен пакетный фильтр, следует по крайней мере разрешить доступ к локальным UDP-портам из этого списка снаружи. Эти порты используются для обмена мультимедийным трафиком - аудио и видео. О назначении портов TCP сказать ничего не могу.

В следующей заметке я опишу настройку Asterisk для обмена видео между программными телефонами Ekiga.

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

Соединение двух Asterisk через раздельные учётные записи SIP для входящих и исходящих звонков

Эта заметка является усовершенствованным вариантом заметки Соединение двух Asterisk через SIP. В прошлой заметке я использовал учётные записи типа friend, каждая из которых может использоваться как для входящих, так и для исходящих звонков. В этот раз я воспользуюсь учётными записями типов peer и user. Учётная запись типа peer будет использоваться для совершения исходящих звонков, а учётная запись типа user - для входящих. При этом фактически учётная запись типа peer подключается к учётной записи типа user на другой станции, а для двустороннего обмена звонками используется два отдельных разнонаправленных подключения.

На самом деле учётная запись любого типа может использоваться для входящих и исходящих звонков. Учётная запись user для входящих звонков будет требовать у удалённой стороны пройти процедуру аутентификации, я для получения исходящих звонков удалённая сторона должна зарегистрироваться в системе - указать свой IP-адрес и порт, куда отправлять звонки. Учётная запись типа peer при совершении исходящих звонков готова пройти аутентификацию на удалённой стороне, а для входящих звонков от удалённой стороны проверяет только соответствие IP-адреса и порта удалённой стороны, но не требует аутентификации.

Разделением учётных записей на peer и user мы добьёмся, кроме всего прочего, того, что входящий звонок всегда будет поступать с данными аутентификации, а не будет полагаться на соответствие IP-адреса и порта удалённой стороны. Потенциальный взломщик, сидящий за сервером NAT, не сможет притвориться соседом, воспользовавшись одинаковым с соседом IP-адресом NAT-сервера, и совершить звонок в систему от имени соседа. Также звонки из системы будут всегда уходить в заранее предусмотренном направлении, а не туда, откуда совершена регистрация. Если злоумышленник раздобудет логин и пароль и зарегистрируется в системе, звонки всё равно будут уходить туда, куда указывают настройки из файла конфигурации.

Как и в прошлых заметках, первая станция называется desktop, имеет IP-адрес 169.254.254.1, к ней подключены телефоны с номерами 1XXX. Вторая станция называется notebook и имеет IP-адрес 169.254.254.4, к ней подключены телефоны с номерами 2XXX.

1. Создание учётных записей для входящих звонков

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

[notebook](asterisk_sip_in)
secret=notebook_password
permit=169.254.254.4
Телефонная станция notebook сможет зарегистрироваться только с IP-адреса 169.254.254.4. Входящие звонки будут попадать в контекст stations.

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

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

Откроем файл /etc/asterisk/sip.conf на станции desktop и создадим учётную запись, через которую станция desktop будет направлять звонки на станцию notebook:
[asterisk_sip_out](!)
language=ru
type=peer
trunk=yes

[to_notebook](asterisk_sip_out)
fromuser=desktop
secret=desktop_password
host=169.254.254.4
Откроем файл /etc/asterisk/sip.conf на станции notebook и впишем симметричные настройки - создадим учётную запись, через которую станция notebook будет отправлять звонки на станцию desktop:
[asterisk_sip_out](!)
language=ru
type=peer
trunk=yes

[to_desktop](asterisk_sip_out)
fromuser=notebook
secret=notebook_password
host=169.254.254.1
Теперь выполним на обеих телефонных станциях следующую команду, чтобы на них появились учётные записи SIP:
# asterisk -rx 'sip reload'
В отличие от прошлой статьи, где были настроены учётные записи типа friend, здесь отсутствуют выражения register. Регистрация используется для информирования удалённой стороны о том, в каком направлении нужно отправлять обратные звонки. В прошлой статье регистрация использовалась скорее только для установки подключения и для его именования, но информация о местоположении удалённой стороной реально не использовалась. В этой статье выражения register отсутствуют, поскольку их роль выполняют учётные записи типа peer.

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. Исходящие звонки на удалённые станции

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

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

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

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

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

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

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

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

воскресенье, 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 на соседних портах, трафик напрямую между портами не ходил, пока я не разрешил портам общаться между собой.

воскресенье, 27 марта 2016 г.

Шаблоны и настройка звонков между SIP-клиентами в Asterisk

Как известно, чтобы съесть слона, достаточно есть его по кусочкам. Сегодня рассмотрим ещё несколько простых тем:
  • использование шаблонов для описания SIP-клиентов в файле /etc/asterisk/sip.conf,
  • настройка номерного плана /etc/asterisk/extensions.conf, для соединения абонентов друг с другом,
  • использование в номерном плане шаблонов номеров и встроенных переменных,
  • использование встроенных функций номерного плана и настройку тестовых номеров для проговаривания номер звонящего абонента.
1. Использование шаблонов

В прошлой заметке Настройка SIP-клиента и тестовых номеров в Asterisk у нас получился файл /etc/asterisk/sip.conf со следующим содержимым:
[general]
allowguest=no
alwaysauthreject=yes

[1000]
call-limit=1
type=friend
context=phones
host=dynamic
secret=password
deny=0.0.0.0/0.0.0.0
permit=169.254.254.0/24
Теперь, чтобы добавить новых SIP-клиентов, можно просто скопировать секцию 1000 и отредактировать её. Если подобных клиентов будет много, то при необходимости поменять одну и ту же настройку у всех клиентов, нужно будет потратить некоторое время на правку настроек каждого клиента. Вместо этого можно создать шаблон, в котором будут указываться общие настройки для определённой группы клиентов. Шаблон потом можно назначить каждому из клиентов. Файл /etc/asterisk/sip.conf будет выглядеть следующим образом:
[general]
allowguest=no
alwaysauthreject=yes

[ata](!)
call-limit=1
language=ru
type=friend
context=phones
host=dynamic
deny=0.0.0.0/0.0.0.0
permit=169.254.254.0/24

[1000](ata)
secret=password

[1001](ata)
secret=password2
Восклицательный знак в скобках указывает, что эта секция является шаблоном. Если же в скобках указан какой-то другой текст, то он интерпретируется как название шаблона, который нужно использовать как настройки по умолчанию для этой секции. Каждому клиенту можно назначать и более одного шаблона. В этом случае шаблоны перечисляются в скобках через запятую. Например, один шаблон может указывать настройки клиентов в локальной сети, а другой - настройки кодеков для определённых моделей шлюзов. Если я правильно понимаю, то шаблоны не могут быть иерархическими, а при указании нескольких шаблонов, настройки предыдущих шаблонов перекрываются настройками из последующих.

Как обычно, для вступления новых настроек в силу, выполним соответствующую команду:
# asterisk -rx 'sip reload'
2. Звонки между SIP-клиентами

Для соединения абонентов между собой в Asterisk существует приложение номерного плана Dial. У этого приложения есть множество различных возможностей и настроек, но сейчас нам достаточно знать, что вызов приложения типа Dial(SIP/1000) означает соединение звонящего с SIP-абонентом с идентификатором 1000. Если у нас есть всего два тестовых абонента, то достаточно настроить в номерном плане в файле /etc/asterisk/extensions.conf всего две записи:
exten => 1000,1,Dial(SIP/1000)

exten => 1001,1,Dial(SIP/1001)
После этого можно перезагрузить номерной план такой командой:
# asterisk -rx 'dialplan reload'
Теперь с одного телефона можно позвонить на другой.

3. Шаблоны номеров и переменные

У настроек, рассмотренных в предыдущем разделе, есть один большой недостаток - при появлении нового SIP-клиента для него нужно создавать новую запись в номерном плане. Чтобы исправить этот недостаток, воспользуемся шаблонами и предопределённой переменной ${EXTEN}. Шаблоны позволяют не указывать точный номер телефона, а предопределённая переменная ${EXTEN} позволяет передать номер в приложение:
exten => _1XXX,1,Dial(SIP/${EXTEN})
Шаблоны номеров начинаются с символа подчёркивания. Далее следуют цифры или подстановочные символы:
  • [15-7] - одна из цифр: 1, 5, 6 или 7,
  • X - одна цифра от 0 до 9. Является более короткой записью для [0-9],
  • Z - одна цифра от 1 до 9. Является более короткой записью для [1-9],
  • N - одна цифра от 2 до 9. Является более короткой записью для [2-9],
  • . - одно или более соответствий предыдущему подстановочному символу. Например, шаблон _N. будет совпадать с любым количеством цифр от 2 до 9,
  • ! - ноль и более соответствий предыдущему подстановочному символу. Например, шаблон _1N! будет соответствовать номеру 1 и любым номерам, начинающимися с единицы и продолжающимися цифрами от 2 до 9.
Переменная ${EXTEN} содержит в себе набранный номер. Из этого номера можно вырезать произвольные фрагменты. Например, ${EXTEN:1} вернёт все цифры, кроме первой. ${EXTEN:1:2} вернёт две цифры после первой.

Ещё одна важная деталь номерного плана состоит в том, что Asterisk стремится найти наиболее точно заданный шаблон. Например, если задать в номерном плане два шаблона:
exten => _XXXX,1,Playback(tt-monkeyintro)

exten => _1XXX,1,Dial(SIP/${EXTEN})
То первое соответствие будет срабатывать только для тех номеров, которые не начинаются с 1. То есть Asterisk не обращает внимания на порядок перечисления шаблонов и выбирает для номеров, начинающихся с 1 второе правило, хотя первое для таких номеров тоже подходит.

Итак, осталось перезагрузить номерной план и проверить прохождение звонков с одного номера на другой:
# asterisk -rx 'dialplan reload'
4. Функции и ещё несколько тестовых номеров

Кроме переменных, таких как ${EXTEN}, в Asterisk существуют ещё и функции. Функции вызываются похожим образом, но могут принимать аргументы. Одной из таких функций является функция ${CALLERID()}. Она возвращает информацию о звонящем абоненте. Если указать ей аргумент num, то она вернёт номер звонящего абонента.

Кроме того, в Asterisk существуют приложения SayDigits() и SayNumber(). Первое произносит цифры, переданные ему в аргументе. Второе умеет произносить целые числа от 0 до 99999999 (8 цифр, числа до 100 миллионов), переданные ему в аргументе.

Воспользуемся функцией ${CALLERID()} и приложениями SayDigits() и SayNumber() для создания в номерном плане в /etc/asterisk/extensions.conf ещё двух тестовых номеров, с помощью которых можно узнать номер телефона, с которого вы позвонили на соответствующий тестовый номер:
exten => 502,1,SayDigits(${CALLERID(num)})

exten => 503,1,SayNumber(${CALLERID(num)})
Первое приложение кажется не столь полезным, однако оно, в отличие от второго, позволяет точно воспроизводить номера телефонов, начинающихся с одного и более нулей. В этом случае второй тестовый номер опустит старшие нули и воспроизведёт только число, в то время как первый позволит узнать точное количество нулей в начале номера.

Можно совместить оба приложения в пределах одного тестового номера, так чтобы сначала проговаривался номер, а потом, после небольшой паузы, цифры номера. Заодно воспользуемся сокращением same, которое можно использовать, чтобы не повторять номер в каждой строчке номерного плана:
exten => 504,1,SayNumber(${CALLERID(num)})
same  =>     n,Wait(1)
same  =>     n,SayDigits(${CALLERID(num)})
Как обычно, теперь нужно перезагрузить номерной план:
# asterisk -rx 'dialplan reload'
Эти тестовые номера могут оказаться полезными новым сотрудникам, сотрудникам, временно севшими за чужое рабочее место, и техническому персоналу для диагностики проблем телефонии.

Полезные ссылки:

воскресенье, 20 марта 2016 г.

Настройка SIP-клиента и тестовых номеров в Asterisk

В прошлой заметке Автоматическая настройка голосового шлюза Cisco ATA 186 я рассказал о том, как можно сбросить настройки шлюза, автоматически настроить его при помощи DHCP- и TFTP-серверов, обновить прошивку и продиагностировать проблемы с помощью сетевого сниффера.

В этой заметке я рассмотрю первичную настройку Asterisk, подключение к системе голосового шлюза Cisco ATA 186 по протоколу SIP и настройку тестовых номеров для проверки связи между телефоном и Asterisk. Хочу сразу предупредить, что не имею опыта работы с Asterisk и поэтому приведённая здесь конфигурация может привести ко взлому телефонной системы, что при наличии подключения к сети телефонного оператора может вылиться в большие счета за международную связь.

1. Установка и включение
Установим Asterisk:
# apt-get install asterisk
Включим запуск asterisk при загрузке системы:
# systemctl enable asterisk.service
Запустим asterisk:
# systemctl start asterisk.service
Для подключения к консоли запущенного asterisk можно ввести следующую команду:
# asterisk -r
2. Подключение SIP-телефона

Для начала переименуем все имеющиеся файлы, настраивающие номерной план, чтобы имеющиеся в них настройки не мешали нам:
# cd /etc/asterisk/
# mv extensions.conf extensions.conf.sample
# mv extensions.lua extensions.lua.sample
# mv extensions.ael extensions.ael.sample
Создадим пустой номерной план в файле /etc/asterisk/extensions.conf:
[globals]

[general]

[internal]

[phones]
include => internal
Контексты globals и general являются специальными. Имена остальных контекстов - произвольные, но они могут состоять только из латинских букв и цифр, знаков подчёркивания и минусов. Пробелы в именах контекстов не допускаются. В контексте phones осуществляется включение всех настроек из контекста internal.

Чтобы новые настройки номерного плана вступили в силу, выполним такие команды:
# asterisk -rx 'module unload pbx_lua.so'
# asterisk -rx 'module unload pbx_ael.so'
# asterisk -rx 'module reload pbx_config.so'
# asterisk -rx 'dialplan reload'
Теперь переименуем файл /etc/asterisk/sip.conf, чтобы он не мешал нам:
# mv sip.conf sip.conf.sample
Вместо него создадим тестовый файл /etc/asterisk/sip.conf со следующим содержимым:
[general]
allowguest=no
alwaysauthreject=yes

[1000]
call-limit=1
type=friend
context=phones
host=dynamic
secret=password
deny=0.0.0.0/0.0.0.0
permit=169.254.254.0/24
Этот файл настраивает учётную запись SIP-клиента с идентификатором 1000 и паролем password. Клиент не имеет предопределённого адреса, его IP-адрес будет определяться в момент его регистрации в телефонной системе. При попытке позвонить с этого телефона будет использоваться контекст phones.

Реальный пароль я рекомендую сгенерировать, например, при помощи программы pwgen. Если пароль не будет вводиться человеком вручную, можно сгенерировать сразу длинный пароль. Следующая команда выдаст варианты 16-символьных паролей, один из которых можно выбрать:
$ pwgen 16
Для усиления безопасности в разделе general первой указана настройка allowguest=no, запрещающая Asterisk обрабатывать звонки от незарегистрированных в системе SIP-клиентов. По умолчанию Asterisk выдаёт разные ошибки для случая, когда SIP-клиент использовал несуществующее имя пользователя, и для случая, когда SIP-клиент использовал верное имя пользователя, но указал неправильный пароль. Такая настройка по умолчанию облегчает подбор имени пользователя и его пароля взломщику, поэтому второй настройкой alwaysauthreject=yes в разделе general мы задаём выдачу одинакового сообщения об ошибке в обоих случаях.

Настройка call-limit=1 разрешает клиенту звонить одновременно только на один номер. Позвонить на один номер, а затем в процессе разговора позвонить с использованием той же учётной записи на другой номер не получится. Не смотря на то, что у клиента нет постоянного IP-адреса, опции deny и permit разрешают клиенту регистрироваться только с IP-адресов в сети 169.254.254.0/24.

Чтобы новые настройки модуля sip вступили в силу, выполним команды:
# asterisk -rx 'reload chan_sip.so'
# asterisk -rx 'sip reload'
3. Настройка пакетного фильтра

Портом по умолчанию для SIP-клиентов на Asterisk является UDP-порт 5060. Для голосового трафика между Asterisk и SIP-клиентами используются UDP-порты с 10000 по 20000. В этом можно убедиться, заглянув в файл /etc/asterisk/rtp.conf, содержимое которого, если из него удалить комментарии, сведётся к следующим строчкам:
[general]
rtpstart=10000
rtpend=20000
Таким образом, чтобы клиенты из сети 169.254.254.0/24 через интерфейс br0 смогли работать с Asterisk, нужно выполнить такую команду:
# iptables -A INPUT -i br0 -s 169.254.254.0/24 -d 169.254.254.1 -p udp -m multiport --dports 5060,10000:20000 -j ACCEPT
Предполагается, что iptables настроен в режиме учёта состояния подключений, для чего где-то в начале правил должна быть настроена команда, которая умеет пропускать однажды разрешённый трафик и ответный трафик:
# iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
После этого можно попробовать посмотреть список зарегистрированных на Asterisk SIP-клиентов:
# asterisk -rx 'sip show peers'
Name/username             Host                                    Dyn Forcerport Comedia    ACL Port     Status      Description                      
1000/1000                 169.254.254.8                            D  Auto (No)  No          A  5060     Unmonitored                                  
1 sip peers [Monitored: 0 online, 0 offline Unmonitored: 1 online, 0 offline]
4. Тестовый номер 500. Проигрывание музыки

Наш первый номер в номерном плане будет просто воспроизводить музыку позвонившему абоненту. Для этого сначала установим пакеты, содержащий музыкальные файлы:
# apt-get install asterisk-moh-opsound-gsm asterisk-moh-opsound-g722 asterisk-moh-opsound-wav
Теперь добавим в контекст internal номерного плана в файле /etc/asterisk/extensions.conf следующую строчку:
exten => 500,1,MusicOnHold()
Она предписывает воспроизвести музыку абоненту, позвонившему на номер 500. Чтобы новые настройки вступили в силу, перезагрузим номерной план и модуль moh:
# asterisk -rx 'dialplan reload'
# asterisk -rx 'moh reload'
Теперь можно попробовать поднять трубку телефона и набрать номер 500. Если в трубке начала воспроизводиться музыка, то тест успешно пройден.

4. Тестовый номер 501. Эхо-тест

Второй тестовый номер будет воспроизводить фразу о начале эхо-теста, затем повторять с небольшой задержкой всё произнесённое в трубку. Чтобы завершить эхо-тест, можно сразу повесить трубку, а можно нажать клавишу с решёткой. В этом случае будет воспроизведена фраза о завершении эхо-теста, после чего телефонная станция повесит трубку. Для начала установим пакеты, содержащие голосовые файлы на русском языке:
# apt-get install asterisk-core-sounds-ru-gsm asterisk-core-sounds-ru-g722 asterisk-core-sounds-ru-wav
Теперь добавим в файл /etc/asterisk/sip.conf к настройкам SIP-клиента ещё одну строчку, которая задаёт язык абонента:
language=ru
Добавим в контекст internal номерного плана ещё один тестовый номер:
exten => 501,1,Playback(demo-echotest)
exten => 501,n,Echo()
exten => 501,n,Playback(demo-echodone)
Осталось перезагрузить модули, настройки которых изменялись:
# asterisk -rx 'reload chan_sip.so'
# asterisk -rx 'reload app_playback.so'
# asterisk -rx 'dialplan reload'
# asterisk -rx 'sip reload'
Теперь можно попробовать поднять трубку телефона и набрать номер 501. В трубке должна прозвучать фраза о начале эхо-теста. Потом, если всё настроено правильно, в трубке можно будет услышать эхо собственного голоса. Для завершения теста можно нажать решётку или повесить трубку.

На этом пока всё. Буду рад услышать конструктивную критику, замечания и предложения.