При разработке АТС Askozia мы столкнулись с задачей по автоматической настройке телефонов и решили ее по-своему.
Autoprovisioning Plug & Play (PnP), эту технологию поддерживают многие производители — Yealink, Snom, Fanvil.
Основные достоинства автоматической настройки телефонов:
Опишем как же работает Autoprovisioning Plug & Play. В конце статьи ссылка на исходники небольшого PHP скрипта, реализующего функционал PnP сервера.
У нас был интересный кейс при внедрении телефонии одному из наших клиентов. Основная проблема заключалась в том, что клиент находился в другом городе. При этом, одним из требований значилось то, что распаковав посылку с телефонами и включив их в сеть телефония должна сразу работать.
Решена задача была относительно просто. Клиент зарезервировал для нас ряд IP адресов. Мы настроили оборудование у себя в офисе и упаковав в коробку выслали курьерской службой.
При использовании автоматической настройки аппаратов задача стала бы намного проще.
Телефонный аппарат при начале работы отправляет широковещательный SIP запрос SUBSCRIBE на адрес 224.0.1.75 multicast IP.
В ответ ожидает получить ответ NOTIFY с инструкциями по настройке.
Как только сервер PnP получил такой запрос, он должен ответить
В NOTIFY сообщении наиболее ценная информация находится в теле сообщения. Как правило, в теле необходимо передать ссылку на получение конфигурационного файла:
Если в сети работает несколько PnP серверов, то кто первый кто ответит устройству, будет его настраивать.
Телефон при получении NOTIFY пытается выполнить запрос по указанному адресу.
Пример реализации сервера доступен на github https://github.com/boffart/MikoServerPnP
Для работы этого сервера PnP необходимо:
Допустим мы отдаем файл по ссылке:
Обычная прямая ссылка на файл. Очевидно, что это НЕ безопасно. Зная MAC адрес телефона и адрес сервера можно попробовать получить конфиг с логинами и паролями.
При работе с PnP сервером возможно для каждого SUBSCRIBE запроса отдавать уникальную ссылку:
Пример формулы для расчета хэш:
PID — это ID процесса PnP сервера. Его узнать может только root.
Подобрать такой hash практически не реально.
Если происходит обращение по недействительной ссылке, то баним вредителя.
Да, да, именно без авторизации.
От такой возможности не смог закрыть устройство на актуальной версии прошивки.
Достаточно выполнить команду
И телефон уйдет в ребут. Повесив такую команду в cron можно добиться ужасающего эффекта. Конечно это возможно если мы знаем IP адрес и SIP порт телефона.
Располагаются в settings/settings.json
Можно описать в settings/mac_white.conf. Разделитель — перевод строки.
Можно описать в settings/mac_black.conf. Разделитель — перевод строки.
Необходимо поместить в каталог configs.
Средствами PnP сервера есть возможность создать простейшие конфиги для Yeakink и Snom:
Autoprovisioning Plug & Play (PnP), эту технологию поддерживают многие производители — Yealink, Snom, Fanvil.
Основные достоинства автоматической настройки телефонов:
- Облегчает первичную настройку — не требуется заходить в web интерфейс каждого устройства. Достаточно на сервере автонастройки указать соответствие MAC адреса устройства и акканута.
- Упрощает поддержку — действительно становится легче при необходимости изменить настройки устройства. Управляем настройками опять же на сервере
- Возможно свести настройку к набору старкода «*911*<SIP_ACC>» — в ряде случаев этой функции просто цены нет. Не каждый офисный работник сможет настроить IP телефон, а вот набрать комбинацию цифр задача простая.
Опишем как же работает Autoprovisioning Plug & Play. В конце статьи ссылка на исходники небольшого PHP скрипта, реализующего функционал PnP сервера.
Пример из опыта
У нас был интересный кейс при внедрении телефонии одному из наших клиентов. Основная проблема заключалась в том, что клиент находился в другом городе. При этом, одним из требований значилось то, что распаковав посылку с телефонами и включив их в сеть телефония должна сразу работать.
Решена задача была относительно просто. Клиент зарезервировал для нас ряд IP адресов. Мы настроили оборудование у себя в офисе и упаковав в коробку выслали курьерской службой.
При использовании автоматической настройки аппаратов задача стала бы намного проще.
Упрощенная схема работы PnP
Телефонный аппарат при начале работы отправляет широковещательный SIP запрос SUBSCRIBE на адрес 224.0.1.75 multicast IP.
Подробнее о 224.0.1.75
224.0.1.75 — это multicast IP (для многоадресной рассылки) «зарезервирован» для SIP серверов.
см. networksorcery.com/Enp/protocol/sip.htm
224.0.1.75 SIP, Session Initiation Protocol (all servers).
см. networksorcery.com/Enp/protocol/sip.htm
224.0.1.75 SIP, Session Initiation Protocol (all servers).
В ответ ожидает получить ответ NOTIFY с инструкциями по настройке.
Пример SUBSCRIBE
2019/09/02 09:26:41.543856 172.16.32.148:5059 -> 224.0.1.75:5060
SUBSCRIBE sip:MAC0015657322ff@224.0.1.75 SIP/2.0
Via: SIP/2.0/UDP 172.16.32.148:5059;branch=z9hG4bK42032775
From: <sip:MAC0015657322ff@224.0.1.75>;tag=42032772
To: <sip:MAC0015657322ff@224.0.1.75>
Call-ID: 42032772@172.16.32.148
CSeq: 1 SUBSCRIBE
Contact: <sip:MAC0015657322ff@172.16.32.148:5059>
Max-Forwards: 70
User-Agent: Yealink SIP-T21P 34.72.14.6
Expires: 0
Event: ua-profile;profile-type="device";vendor="Yealink";model="T21D";version="34.72.14.6"
Accept: application/url
Content-Length: 0
Наиболее важные и интересные заголовки
- From — передается мак адрес устройства 0015657322ff
- Event — исчерпывающе описывает устройство, Производитель, модель, версия прошивки
- Contact — адрес устройства
- Call-ID — этот заголовок интересен при настройке DECT устройств от Yealink, в нем передается идентификатор линии (порядковый номер трубки), разделитель "_"
Как только сервер PnP получил такой запрос, он должен ответить
Пример NOTIFY
2019/09/02 09:26:41.550125 172.16.32.153:57593 -> 172.16.32.148:5059
NOTIFY sip:172.16.32.148:5059 SIP/2.0
Via: SIP/2.0/UDP 172.16.32.148:5059;branch=z9hG4bK42032775
Max-Forwards: 20
Contact: <sip:172.16.32.148:5059;transport=UDP;handler=dum>
From: <sip:MAC0015657322ff@224.0.1.75>;tag=42032772
To: <sip:MAC0015657322ff@224.0.1.75>
Call-ID: 42032772@172.16.32.148
CSeq: 3 NOTIFY
Content-Type: application/url
Subscription-State: terminated;reason=timeout
Event: ua-profile;profile-type="device";vendor="MIKO";model="MikoServerPnP";version="1.8"
Content-Length: 40
http://172.16.32.153:84/0015657322ff.cfg
В NOTIFY сообщении наиболее ценная информация находится в теле сообщения. Как правило, в теле необходимо передать ссылку на получение конфигурационного файла:
http://172.16.32.153:84/0015657322ff.cfg
Если в сети работает несколько PnP серверов, то кто первый кто ответит устройству, будет его настраивать.
Телефон при получении NOTIFY пытается выполнить запрос по указанному адресу.
Пример запроса и ответа сервера
# curl -i http://172.16.32.153:84/0015657322ff.cfg
HTTP/1.0 200 OK
Content-type: text/plain
Date: Mon, 02 Sep 2019 06:52:23 GMT
Connection: close
Accept-Ranges: bytes
Last-Modified: Mon, 02 Sep 2019 06:25:02 GMT
Content-length: 769
#!version:1.0.0.1
account.1.enable = 1
account.1.label = PnP (203)
...
Пример реализации сервера доступен на github https://github.com/boffart/MikoServerPnP
Для работы этого сервера PnP необходимо:
- PHP 7.1.9
- PHP sockets
- BusyBox v1.26.2
- В сети должны быть разрешены широковещательные запросы
Возможности сервера PnP
- Слушает запросы, отправленные на адрес ‘224.0.1.75:5060’
- При начале работы запускает web серевер (busybox httpd)
- Позволяет создать упрощенный конфиг телефона
- Позволяет отправить на Yealink NOTIFY для перезагрузки
Использование PnP сервера позволяет использовать «Одноразовые ссылки».
Допустим мы отдаем файл по ссылке:
http://172.16.32.153:84/0015657322ff.cfg
Обычная прямая ссылка на файл. Очевидно, что это НЕ безопасно. Зная MAC адрес телефона и адрес сервера можно попробовать получить конфиг с логинами и паролями.
При работе с PnP сервером возможно для каждого SUBSCRIBE запроса отдавать уникальную ссылку:
http://172.16.32.153:84/?mac=0015657322ff&hash=0a67f5290
Пример формулы для расчета хэш:
hash = md5(MAC + DATE + PID)
PID — это ID процесса PnP сервера. Его узнать может только root.
Подобрать такой hash практически не реально.
Если происходит обращение по недействительной ссылке, то баним вредителя.
Reboot Yealink средствами NOTIFY без авторизации
Да, да, именно без авторизации.
От такой возможности не смог закрыть устройство на актуальной версии прошивки.
Достаточно выполнить команду
php -f MikoServerPnP.php socket_client_notify <IP_PBX> <PORT_SIP_PBX> <IP_PHONE> <PORT_PHONE>
И телефон уйдет в ребут. Повесив такую команду в cron можно добиться ужасающего эффекта. Конечно это возможно если мы знаем IP адрес и SIP порт телефона.
Пример PHP функции на отправку NOTIFY
public static function socket_client_notify($ip_pbx, $port_pbx, $ip_phone, $port_phone):void {
$phone_user = 'autoprovision_user';
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$msg = "NOTIFY sip:{$phone_user}@{$ip_phone}:{$port_phone};ob SIP/2.0\r\n".
"Via: SIP/2.0/UDP {$ip_pbx}:{$port_pbx};branch=z9hG4bK12fd4e5c;rport\r\n".
"Max-Forwards: 70\r\n".
"From: \"asterisk\" <sip:asterisk@{$ip_pbx}>;tag=as54cd2be9\r\n".
"To: <sip:{$phone_user}@{$ip_phone}:{$port_phone};ob>\r\n".
"Contact: <sip:asterisk@{$ip_pbx}:{$port_pbx}>\r\n".
"Call-ID: 4afab6ce2bff0be11a4af41064340242@{$ip_pbx}:{$port_pbx}\r\n".
"CSeq: 102 NOTIFY\r\n".
"User-Agent: mikopbx\r\n".
"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE\r\n".
"Supported: replaces, timer\r\n".
"Subscription-State: terminated\r\n".
"Event: check-sync;reboot=true\r\n".
"Content-Length: 0\r\n\n";
$len = strlen($msg);
socket_sendto($sock, $msg, $len, 0, $ip_phone, $port_phone);
socket_close($sock);
}
Настройка сервера PnP
Располагаются в settings/settings.json
{
"url": "http://<pbx_host>:<http_port>/",
"http_port": 84,
"pbx_host": "172.16.32.153",
"pbx_sip_port": "5060",
"vm_extension": "*001",
"feature_transfer": "**"
}
Белый список MAC
Можно описать в settings/mac_white.conf. Разделитель — перевод строки.
Черный список MAC
Можно описать в settings/mac_black.conf. Разделитель — перевод строки.
Конфигурационные файлы телефонов
Необходимо поместить в каталог configs.
Средствами PnP сервера есть возможность создать простейшие конфиги для Yeakink и Snom:
php -f MikoServerPnP.php mk_config SIP_ACCAUNT SECRET MAC
sergarcada
Технология работы не донца ясна.
1. Что за адрес 224.0.1.75, откуда про него знает телефон? Телефоны получают свой ip через DHCP?
2. В заголовке статьи сказано про Askozia, но из статьи не видно, как весь этот PnP настраивается из ее интерфейса. Или его пока там нет?
boffart Автор
Спасибо за поправку. Действительно не описал про IP адрес.
224.0.1.75 — это multicast IP (для многоадресной рассылки) «зарезервирован» для SIP серверов
см. networksorcery.com/Enp/protocol/ip/multicast.htm
224.0.1.75 SIP, Session Initiation Protocol (all servers).
networksorcery.com/Enp/protocol/sip.htm
Интерфейса для Askozia пока нет. Не допилили. В ближайшее время постараемся опубликовать рабочую версию с интерфейсом, тогда дополню статью.
sergarcada
Задумка интересная. Раньше я вообще не знал про такую возможность именно через широковещательную рассылку. Я так понимаю, что про автоматическую генерацию конфига/привязки номера к mac сейчас тоже речи нет?
boffart Автор
Да, пока нет, но тот, проект, что я выложил, можно немного допилив реализовать нужный функционал. В итоговом модуле для Askozia это будет.