Часть 2. Об организации доступа платформы умного дома Яндекс к домашнему серверу MajorDoMo посредством вебхуков.
Механизм взаимодействия платформы умного дома Яндекс со сторонними системами (провайдерами) реализуется посредством вебхуков (webhook). Облако Яндекс для запроса состояния устройств и управления ими посылает POST- и GET-запросы на конечные точки (endpoint) вебхуков и получает ответы от них. Таким образом, для корректной работы этого механизма необходимо обеспечить постоянную доступность вебхуков из сети Интернет со стороны облака Яндекс.
Согласно API платформы умного дома Яндекс требуется реализовать три типа конечных точек:
В модуле Yandex Home все три типа конечных точек реализованы в виде отдельных файлов: authorize.php, token.php и smarthome.php, размещаемых в директории /modules/yandexhome.
# | Назначение вебхука | URL вебхука |
---|---|---|
1 | URL авторизации | /modules/yandexhome/authorize.php |
2 | URL для получения и обновления токена | /modules/yandexhome/token.php |
3 | URL обработчика навыка | /modules/yandexhome/smarthome.php |
Чтобы опубликовать эти три вебхука в сеть Интернет и обеспечить тем самым их доступность со стороны облака Яндекс, необходимо выполнить ряд условий, о которых уже говорилось в предыдущей статье. Рассмотрим их подробнее.
Условие №1. Публичный (глобальный, белый) IP-адрес, выдаваемый интернет-провадером.
Белый IP-адрес при этом может быть как статическим, так и динамическим. В случаях, когда невозможно получить белый адрес у интернет-провайдера, возможны варианты использования сторонних сервисов. Например, некоторые производители роутеров предоставляют их владельцам сервис по доступу к ресурсам домашней локальной сети (KeenDNS от Keenetic и др). Либо использовать VPN-сервисы на подобие vpnki.ru или собственный VPN-сервер, развернутый на VPS.
Условие №2. Доменное имя (DNS), привязанное к публичному IP-адресу.
Это требование в большинстве случаев закрывается классическими сервисами динамических DNS, которых представлено в сети в большом ассортименте, как платных, так и бесплатных. Большинство современных роутеров уже имеют встроенную поддержку сервисов Dynamic DNS. При использовании сервисов удаленного доступа типа KeenDNS или VPNKI это условие выполняется автоматически - доменное имя выбирается и присвается в ходе регистрации и подключения услуги.
Условие №3. Валидный SSL-сертификат на DNS-имя.
По требованиям платформы умного дома Яндекс весь обмен трафиком между их облаком и MajorDoMo должен идти в зашифрованном виде по протоколу HTTPS, что обеспечивается либо установкой SSL-сертификата на веб-сервер с MajorDoMo, либо услугами сервисов удаленного доступа (см. выше). Бесплатный SSL-сертификат можно получить у удостоверяющего центра Let’s Encrypt сроком на 3 месяца, затем его нужно будет регулярно обновлять. Сертификат устанавливается либо на тот же виртуальный сервер Apache, который обслуживает MajorDoMo, либо на отдельный виртуальный сервер (Apache или Nginx), выступающий в роли обратного прокси (reverse proxy) для MajorDoMo. Корректность установки сертификата и доступность вашего сервера из сети Интернет по HTTPS можно проверить с помощью специализированных сервисов, например:
Детально расписывать все пункты не буду, т. к. в сети и так огромное количество материалов по данной тематике и все прекрасно ищется. Остановлюсь лишь на своем конкретном кейсе в качестве практического примера.
Исходные данные:
Дополнительные условия:
Реализация:
Первым делом активируем модули Apache - ssl, proxy и proxy_http.
sudo a2enmod ssl proxy proxy_http
Рестартуем Apache
sudo systemctl restart apache2
и проверяем, что модули загрузились
sudo apachectl -M | grep 'ssl\|proxy'
В ответе должно быть три строки.
proxy_module (shared)
proxy_http_module (shared)
ssl_module (shared)
Создаем конфигурационный файл нового виртуального сервера. Я назвал его webhooks.
sudo nano /etc/apache2/sites-available/webhooks.conf
Содержимое файла (с комментариями).
<IfModule mod_ssl.c>
<VirtualHost *:443>
# e-mail
ServerAdmin skysilver.da@gmail.com
# Доменное имя
ServerName majordomo.keenetic.pro
# Рабочая директория
DocumentRoot /var/www/webhooks
# Разграничение доступа
<Directory *>
Options All -Indexes
Order deny,allow
deny from all
</Directory>
# Определяем, что и куда нужно перенаправить.
# URL авторизации (authorize.php)
<Location /modules/yandexhome/authorize.php>
ProxyPass http://127.0.0.1/modules/yandexhome/authorize.php
ProxyPassReverse http://127.0.0.1/modules/yandexhome/authorize.php
</Location>
# URL для получения и обновления токена (token.php)
<Location /modules/yandexhome/token.php>
ProxyPass http://127.0.0.1/modules/yandexhome/token.php
ProxyPassReverse http://127.0.0.1/modules/yandexhome/token.php
</Location>
# URL обработчика навыка (smarthome.php)
<Location /modules/yandexhome/smarthome.php>
ProxyPass http://127.0.0.1/modules/yandexhome/smarthome.php
ProxyPassReverse http://127.0.0.1/modules/yandexhome/smarthome.php
</Location>
# URL на директорию с картинками для формы авторизации
<Location /modules/yandexhome/img>
ProxyPass http://127.0.0.1/modules/yandexhome/img
ProxyPassReverse http://127.0.0.1/modules/yandexhome/img
</Location>
# URL на директорию со стилями для формы авторизации
<Location /modules/yandexhome/css>
ProxyPass http://127.0.0.1/modules/yandexhome/css
ProxyPassReverse http://127.0.0.1/modules/yandexhome/css
</Location>
# Включаем логи
ErrorLog ${APACHE_LOG_DIR}/error.webhooks.log
CustomLog ${APACHE_LOG_DIR}/access.webhooks.log combined
# Указываем пути к файлам SSL-сертификата
SSLCertificateFile /etc/apache2/ssl/webhooks/fullchain.pem
SSLCertificateKeyFile /etc/apache2/ssl/webhooks/privkey.pem
SSLCertificateChainFile /etc/apache2/ssl/webhooks/chain.pem
# АктивируемSSL
SSLEngine on
</VirtualHost>
</IfModule>
Здесь ключевые моменты это активация SSL и секции Location, в которых определются правила перенаправления входящего трафика.
Сохраняем и закрываем конфигурационный файл, затем создаем пустую рабочую директорию.
sudo mkdir /var/www/webhooks
Активируем новый виртуальный сервер
sudo a2ensite webhooks.conf
и обновляем конфигурацию Apache для применения изменений.
sudo systemctl reload apache2