Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk

в 8:12, , рубрики: asterisk

Задача: Настроить телефоны (или любой другой абонентский девайс) автоматически на основе MAC-адреса, желательно не доставая устройство из коробки.

Идея централизованной настройки абонентских устройств давно была у меня и, наконец, нашла свою реализацию в одном из проектов. Видео в конце поста.
Практически все (Cisco, Polycom, D-Link, Escene) IP-телефоны, с которыми мне доводилось встречаться, в том или ином виде поддерживают централизованную настройку с сервера, т.е. Auto-Provisioning по нашему автопровизия. В данном случае рассмотрен пример с телефонами Polycom, но по сути, аналогичный подход позволит настроить любой телефон с определенными корректировками.

Как это работает (про Polycom)?

Телефон по умолчанию настроен на получение IP-адреса по DHCP, помимо самого адреса телефон получает от DHCP ряд опций в числе которых обычно указываются шлюз, маска сети и DNS- сервер, кроме того можно указать SNTP-сервер и еще много чего. Polycom’ы смотрят по умолчанию в опцию 66 и 160, там они пытаются найти адрес/имя сервера автопровизии. Если телефон обнаруживает адрес сервера, он пытается подключиться к нему по уполчанию через FTP (поддерживает еще HTTP, HTTPS, TFTP), используя в качестве логина и пароля:

Username PlcmSpIp
Password PlcmSpIp

Телефон запрашивает у сервера версию (файл sip.ver) и сами файлы прошивки и конфигурационные файлы. Телефон выкачивает новую прошивку, обновляется, затем после перезагрузки снова обращается к серверу, видит, что ПО не требует обновления, скачивает и применяет конфигурационные файлы в формате XML. В общем случае аппарат запрашивает следующие файлы.

Имя файла Описание
0000000000.cfg Общий конфигурационный файл (говорит что и откуда качать)
*.sip.ld (для split)
sip.ld (для combined)*
Прошивка телефона соответствующей модели (задается с 0000000000.cfg),
sip.ver Версия ПО
1234123adba.cfg Конфигурация телефона с MAC-адресом 1234123adba

*- у поликома есть существует две версии ПО combined(много весит)-подходит для всех, split – для каждой линейки телефонов отдельный небольшой *sip.ld файл (уменьшает нагрузку на сеть).
 
Казалось бы, вот и все, телефон готов к работе!  На самом деле для небольших систем так оно и есть, т.е. достаточно:

  1. Скачать прошивку с сайта производителя для своих телефонов support.polycom.com/PolycomService/support/us/support/voice/index.html
  2. В 0000000000.cfg  указать какие именно конфигурационные файлы телефон должен загрузить с сервера (CONFIG_FILES="custom.cfg"), этого достаточно, т.к. по умолчанию.
  3. Создать custom.cfg содержащий настройки общие для всех устройств.
  4. Создать несколько конф-файлов для каждого из аппаратов <МАС-адрес>.cfg в котором будет содержаться информация уникальная для каждого абонента т.е. в общем случае только его SIP-логин и пароль.

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

Поэтому я пошел более изощренным путем:

  1. Через FTP настраиваем телефон чтобы он получал файлы через HTTP:8088
  2. На Asterisk’e с помощью phoneprov динамически формируем конфигурационный файл для каждого телефона на основе файла users.conf.

При таком способе настройки достаточно будет для добавления нового устройства внести его МАС в   users.conf и там же задать ему логин и пароль, остальная настройка происходит автоматически.
Теперь более подробно рассмотрим, что нужно делать:

Настройка DHCP

В данном случае я задаю через конфиг статические адреса для каждого устройства,  т.е. динамический адрес нужен аппарату только в первую и вторую загрузку, после третьей он уже полностью настроен и имеет статический IP. Посему я настроил время аренды – 5 минут, чтобы не занимать пул адресов в пустую. В общем случае адреса можно раздавать и динамически, сделав резервацию для каждого МАС-а. Кроме того нужно добавить опцию 66 или 160 – по вкусу, содержащую адрес сервера провизии. В винде это делается так:

Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
В моем случае Mikrotik:
Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
Итак, нужно чтобы динамически раздавались адреса и опции 66 с адресом сервера провизии. В моем случае диапазон динамических адресов с 20 до 99, а 101-199 диапазон для статических адресов, сделал так, чтобы внутренний номер абонента совпадал с его IP.

Настройка телефона по FTP

Для настройки по FTP нужен FTP, ставим (CentOS):

yum install -y vsftpd
chkconfig vsftpd on
service vsftpd start

Можете конфигурировать через /etc/vsftpd/vsftpd.conf .
Создадим пользователя под которым polycom будет пытаться подключиться:

useradd PlcmSpIp
passwd PlcmSpIp

Учитывая сложность пароля, будет нелишним позаботиться о том, чтобы данный пользователь был настолько бесправен, на сколько это возможно.
Теперь скачиваем архив с прошивкой и распаковываем его в /home/ PlcmSpIp

Когда будете качать прошивку читайте внимательно предупреждения, скорее всего придется скачать еще и обновления загрузчик, их так же распаковываем в директорию   /home/ PlcmSpIp.
Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
На данный момент подключенный к сети телефон должен при включении выкачать новый бутлоадер и прошивку и обновить ПО.

Работа с конфигурационными файлами

Тут я потерял уйму времени пытаясь править XML руками, и я заклинаю тебя, о читатель, не правь конфиги текстовым редактором, если ты не Оби-Ван-Кеноби в мире XML. Для работы с конфигами я использовал XML Notepad 2007.  Если вы скачали прошивку combined-версии, то в папке config будет несколько конфигурационных файлов с расширением *.cfg и XML-схема polycomConfig.xsd. 
*.cfg – примеры конфигурационных файлов тематически сгруппированы

polycomConfig.xsd  Схема
video-integration.cfg  Настройка видео интеграции
video.cfg  Настройка видео звонков
site.cfg  Тут много всего, возможно даже все настройки
sip-interop.cfg  Настройки sip, звонков, тонов
sip-basic.cfg  Настройки sip
region.cfg  Региональные настройки
reg-basic.cfg  SIP-регистрации — базовая
reg-advanced.cfg  SIP-регистрации — Расширенная
H323.cfg  Настройки H323
features.cfg  Настройки переадресации удержания трансфера
device.cfg  Настройки устройства, сетевые системные
applications.cfg  Настройки приложений

В каждом файле есть такая строка:

<polycomConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="polycomConfig.xsd">

Это значит, что если вы откроете конфигурационный файл XML-редактором, он будет искать в той же папке файл схемы polycomConfig.xsd, в нем содержаться все возможные поля конфигурационного файла и перечень доступных значений или краткий комментарий. На данном этапе нам нужно показать устройству, что загрузка должна происходить по протоколу HTTP и указать http-путь к файлам настройки.
Создадим в папке с polycomConfig.xsd текстовый файл custom.cfg следующего содержания.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<polycomConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="polycomConfig.xsd">
</polycomConfig>

Открываем его XML-редактором. Какие поля,  что содержат нужно искать по средствам гугла или воспользоваться 600-страничной инструкцией для администратора по настройке телефонов то производителя.
Но по большей части все интуитивно понятно. Сначала создаем элемент (вероятно следует говорить раздел или еще как-то, но я не знаю и поэтому буду называть так, как они названы XML-редактором т.е. элементом) с помощью контекстного меню polycomConfig или просто ctrl+insert стоя на polycomConfig.
Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
В падающем списке выбираем device т.к. нас интересуют настройки устройства, аналогичным образом создаем элемент device.dhcp  в элементе device.
Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
Теперь в нем создаем атрибут Alt+Insert или из контекстного меню на device.dhcp, открывается падающий список из доступных атрибутов, при наведении выскакивает подсказка с доступными значениями.
Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
Ставим Static – в нашем случае это значит что опции 160 и 66 DHCP следует игнорировать. Аналогичным образом задаем другие параметры, в итоге имеем следующий файл:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<polycomConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="polycomConfig.xsd">
  <device device.set="1">
         <device.dhcp device.dhcp.bootSrvUseOpt="Static" device.dhcp.enabled="1">
      <device.dhcp.enabled device.dhcp.enabled.set="1" />
      <device.dhcp.bootSrvUseOpt device.dhcp.bootSrvUseOpt.set="1" />
    </device.dhcp>
                <device.prov device.prov.serverName="http://192.168.ххх.ххх:8088/phoneprov/" device.prov.serverType="HTTP">
                <device.prov.serverName device.prov.serverName.set="1" />
                <device.prov.serverType device.prov.serverType.set="1" />
    </device.prov>
     </device>
 </polycomConfig>

<device device.set="1"> Задать настройки для устройства
device.dhcp.bootSrvUseOpt="Static" Игнорировать опции 66 и 160 DHCP
device.dhcp.enabled="1" Использовать DHCP
<device.dhcp.enabled device.dhcp.enabled.set="1" /> Задать значение dhcp.enabled
<device.dhcp.bootSrvUseOpt device.dhcp.bootSrvUseOpt.set="1" /> Задать значение bootSrvUseOpt
device.prov.serverName="http://192.168.ххх.ххх:8088/phoneprov/" Путь к файлам
device.prov.serverType="HTTP" Тип сервера провизии
<device.prov.serverName device.prov.serverName.set="1" /> Задать значение serverName
<device.prov.serverType device.prov.serverType.set="1" /> Задать значение serverType

Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
Особое внимание стоит уделить атрибутам, выделенным житным шрифтом, это что-то вроде выключателя, т.е. не достаточно просто ввести значение какого-то параметра нужно еще и сказать конкретно «Да», этот параметр нужно применить. Особенно важно <device device.set="1"> т.к. если этом параметр 0, то все настройки элемента device будут проигнорированы.

Настройки Asterisk

Все, теперь наши телефоны будут просить файлы при загрузке у 192.168.ххх.ххх:8088/phoneprov/. Нужно их там сублимировать из небытия. Для этой цени у Asterisk’a есть специальный модуль, он позволяет автоматически генерировать файлы на основе шаблонов и отдавать их через встроенный HTTP-сервер астериска. Больше можно почерпнуть информации тут и частности там написано:
Удостовериться, что /etc/asterisk/manager.conf содержит:
[general]
enabled = yes; — вероятно так надо, хотя мне не понятно для чего именно
webenabled = yes; — вероятно так надо, хотя мне не понятно для чего именно

Удостовериться, что /etc/asterisk/http.conf содержит:
[general]
enabled = yes; включает встроенный HTTP-сервер
bindaddr = 192.168.ххх.ххх ; IP — на котором будет доступен сервер
bindport = 8088 ; — т.к. 80 порт у нас занят апачем, используем 8088

При запросе файла у http-сервера phoneprov берет шаблон файла и подставляет в него переменные которые берет из users.conf и,  что особенно приятно можно использовать текстовые функции диал-плана. Например ${TOLOWER(${MAC})} в шаблоне будет заменен при формировании конфигурационного файла на МАС-адрес пользователя в нижнем регистре.
В шаблоне можно использовать следующие переменные:

fullname = User Two ; ${DISPLAY_NAME}
secret = test ; ${SECRET}
username = 6001 ; ${USERNAME}
macaddress = deadbeef4dad ; ${MAC}
label = 6001 ; ${LABEL}
cid_number = 6001 ; ${CALLERID}
 
кроме того можно использовать:
${SERVER} – берется из phoneprov.conf если там не задана, то берет значение bindaddr из http.conf
${SERVER_PORT}  - берет значение bindport  из sip.conf, если оно не задано, то 5060

Конфигурационный файл самого res_phoneprov лежит /etc/asterisk/phoneprov.conf, в нем нужно указать директорию статических файлов относительно пути /var/lib/asterisk/phoneprov/, перечень статических файлов, перечень шаблонов и шаблоны имен динамически-формируемых файлов. Вот пример:

[general]
 
serveraddr=192.168.ххх.ххх ; задается переменная ${SERVER}.
serverport=5060        ; задается переменная ${SERVER_PORT}.
default_profile=polycom ; профиль по умолчанию если не задан в users.conf
 
[polycom]
staticdir => configs/ ; Сюда кладете статические файлы, прошивку, фоновые картинки, телефонный справочник и т.п., путь относительно /var/lib/asterisk/phoneprov/
 
mime_type => text/xml
 
static_file => 2345-12345-001.bootrom.ld
static_file => 2345-12360-001.bootrom.ld
static_file => 2345-12365-001.bootrom.ld
static_file => 2345-12365-002.bootrom.ld
static_file => 2345-12375-001.bootrom.ld
static_file => 2345-12375-002.bootrom.ld
static_file => 2345-12450-001.bootrom.ld
static_file => 2345-12450-002.bootrom.ld
static_file => 2345-12500-001.bootrom.ld
static_file => 2345-12560-001.bootrom.ld
static_file => 2345-12600-001.bootrom.ld
static_file => 2345-12600-002.bootrom.ld
static_file => 2345-12670-001.bootrom.ld
static_file => 2345-12670-002.bootrom.ld
static_file => 3111-15600-001.bootrom.ld
static_file => 3111-30900-001.bootrom.ld
static_file => 3111-40000-001.bootrom.ld
static_file => bootrom.ld
 
static_file => sip.ver
static_file => sip.ld
 
static_file => 000000000000-directory.xml ;- это телефонный справочник
 
static_file => languages/Website_dictionary_language_ru-ru.xml
 
static_file => SoundPointIPLocalization/Russian_Russia/SoundPointIP-dictionary.xml
 
 
;------------шаблоны
 
 
${TOLOWER(${MAC})}.cfg => 000000000000.cfg ;Это значит, что при запросе http://192.168.ххх.ххх:8088/phoneprov/111111111111.cfg будет сформирован файл из шаблона 000000000000.cfg с именем 111111111111.cfg,  при этом значения переменных будут взяты из файла users.conf из того юзера у которого macaddress=111111111111
 
${TOLOWER(${MAC})}-custom.cfg => 000000000000-phone.cfg ;При запросе файла http://192.168.ххх.ххх:8088/phoneprov/111111111111-custom.cfg будет сформирован файл 111111111111-custom.cfg при этом значения переменных будут взяты из файла users.conf из того юзера у которого macaddress=111111111111

Со статическими файлами все просто, если файл прописан в phoneprov.conf и находится по соответствующему адресу, то он будет доступен с веб-сервера.
С динамическими вроде немного сложнее, но сейчас все станет понятно. Вот пример шаблонов:
000000000000.cfg

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<APPLICATION APP_FILE_PATH="sip.ld" CONFIG_FILES="${TOLOWER(${MAC})}-custom.cfg" MISC_FILES="" LOG_FILE_DIRECTORY="" OVERRIDES_DIRECTORY="" CONTACTS_DIRECTORY="" LICENSE_DIRECTORY="" USER_PROFILES_DIRECTORY="" CALL_LISTS_DIRECTORY="">
</APPLICATION>

По умолчанию все телефоны запрашивают файл 1234123adba.cfg, где 1234123adba – МАС-адрес телефона, т.е. телефон отправит запрос http://192.168.ххх.ххх:8088/phoneprov/1234123adba.cfg. В данном шаблоне всего одна переменная, и  директива CONFIG_FILES="${TOLOWER(${MAC})}-custom.cfg" превратиться в CONFIG_FILES="1234123adba-custom.cfg", что говорит телефону, что он должен скачать конфигурационный файл 1234123adba-custom.cfg. Телефон отправит запрос http://192.168.ххх.ххх:8088/phoneprov/1234123adba.cfg-custom.cfg в ответ на данный запрос сервер сформирует еще один динамический файл на основе второго шаблона 000000000000-phone.cfg:
000000000000-phone.cfg

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<polycomConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="polycomConfig.xsd">
  <call call.callsPerLineKey="2"></call>
  <reg reg.1.address="${USERNAME}" reg.1.auth.password="${SECRET}" reg.1.auth.userId="${USERNAME}" reg.1.label="${USERNAME}" reg.1.outboundProxy.address="${SERVER}" reg.1.lineKeys="2" reg.1.auth.domain="${SERVER}" reg.1.displayName="${USERNAME}" reg.1.server.1.address="${SERVER}" reg.1.server.1.register="1"></reg>
  <device device.set="1">
    <device.dhcp device.dhcp.bootSrvUseOpt="Static" device.dhcp.enabled="0">
      <device.dhcp.enabled device.dhcp.enabled.set="1" />
      <device.dhcp.bootSrvUseOpt device.dhcp.bootSrvUseOpt.set="1" />
    </device.dhcp>
    <device.dns device.dns.serverAddress="192.168.xxx.1" device.dns.altSrvAddress="8.8.8.8">
      <device.dns.serverAddress device.dns.serverAddress.set="1" />
    </device.dns>
    <device.prov device.prov.serverName="http://192.168.xxx.xxx:8088/phoneprov/" device.prov.serverType="HTTP">
      <device.prov.serverName device.prov.serverName.set="1" />
      <device.prov.serverType device.prov.serverType.set="1" />
    </device.prov>
    <device.net device.net.ipAddress="192.168.XXX.${USERNAME}" device.net.subnetMask="255.255.255.0" device.net.IPgateway="192.168.xxx.1">
      <device.net.ipAddress device.net.ipAddress.set="1" />
      <device.net.subnetMask device.net.subnetMask.set="1" />
      <device.net.IPgateway device.net.IPgateway.set="1" />
    </device.net>
    <device.sntp device.sntp.gmtOffset="14400" device.sntp.serverName="pool.ntp.org">
      <device.sntp.gmtOffset device.sntp.gmtOffset.set="1" />
      <device.sntp.serverName device.sntp.serverName.set="1" />
    </device.sntp>
  </device>
  <dialplan dialplan.1.digitmap="" dialplan.1.digitmap.timeOut="" dialplan.1.impossibleMatchHandling="2" />
  <lcl>
    <lcl.ml lcl.ml.lang="Russian_Russia" />
  </lcl>
  <tcpIpApp>
     <tcpIpApp.sntp.daylightSavings tcpIpApp.sntp.daylightSavings.enable="0" />
    </tcpIpApp.sntp>
  </tcpIpApp>
</polycomConfig>

Тут используется несколько переменных:
${SECRET} подставит значение secret из описания юзера с маком 1234123adba  из users.conf
${USERNAME} подставит значение username из описания юзера с маком 1234123adba  из users.conf.
${SERVER} подставит значение из phoneprov.conf
Обратите внимание! После изменения  phoneprov.conf нужен reloadчтобы настройки подтянулись.
После того как все готово проверьте через консоль:
phoneprov show routes
 
Должны отображаться статические маршруты, динамические будут только если в users.conf есть юзеры у которых  autoprov = yes и задан мас-адрес

Настройка users.conf

Почти все, осталось создать /etc/asterisk/users.conf. Тут тоже нашлась возможность для оптимизации. Приложением zxing для андроида я просканировал все МАС-адреса телефонов, прямо с коробок, и из того-же приложения отправил их себе на почту. Осталось дело за малым сопоставить каждому маку какой-то аккаунт. Руками писать для каждого macaddress=……, как-то не хотелось. Я сделал файл для автоматической генерации конфигов Asterisk на основе табличных данных, в нем же есть генератор паролей.
Автопровизия (Автонастройка) телефонов Polycom с помощью Asterisk
Осталось только скопировать столбец и вставить в users.conf. Телефоны в данном проекте все одинаковые потому есть смысл создать для всех шаблон, а в описании юзера добавить только МАС и пароль.
/etc/asterisk/users.conf

...
 
[def](!) ;- умолчательный шаблон
type=friend
fromuser="CPZ"
host=dynamic 
nat=no
disallow=all
allow=ulaw
allow=alaw
hasvoicemail = no
hassip = yes
hasiax = no
hash323 = no
hasmanager = no
qualify=yes
autoprov = yes ;- включить для этого юзера автопровизию
context=full
 
 
[101](def)
secret=XAHNGNCCXGR
macaddress=0004f24ab859
 
[102](def)
secret=OSANPHVZIEX
macaddress=0004f24abdd6
 
[103](def)
secret=AHUDYLSXFGT
macaddress=0004f24ab766
……

Все готово проверьте через консоль: phoneprov show routes
Должны отображаться и статические маршруты и динамические маршруты. Осталось проверить браузером 192.168.ххх.ххх:8088/phoneprov/1234123adba.cfg например, и можно включать телефоны, дальше все происходит само.

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

Автор: ShakinNN

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js