Ноя 122017
 

MQTT – это легковесный протокол сообщений, предназначенный для общения между устройствами (machine-to-machine) интернета вещей. Он используется для отслеживания перемещения транспортных средств, домашней автоматизации и сбора данных.

Mosquitto – это популярный MQTT-сервер (или брокер). Он прост в установке и настройке и активно поддерживается сообществом.

Данное руководство поможет установить Mosquitto, получить для него сертификат SSL от сервиса Let’s Encrypt и настроить безопасное взаимодействие устройств по MQTT.

Требования

1: Установка Mosquitto

В репозитории Ubuntu 16.04 можно найти сравнительно недавнюю версию Mosquitto. Чтобы установить Mosquitto, введите:

sudo apt-get install mosquitto mosquitto-clients

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

Темы – это метки, которые присваиваются опубликованным заметкам. Они расположены в виде иерархии (например, sensors/outside/temp или sensors/outside/humidity). Упорядочивание тем полностью зависит от ваших потребностей.

Откройте ещё одну сессию терминала, в результате у вас должно быть два терминала. Запустите в новом терминале команду mosquitto_sub, чтобы подписаться:

mosquitto_sub -h localhost -t test

Флаг –h указывает имя хоста сервера MQTT, -t – тему. После запуска команды на экране не появится вывода, поскольку команда mosquitto_sub ждет получения сообщений. Вернитесь в первый терминал и опубликуйте сообщение:

mosquitto_pub -h localhost -t test -m "hello world"

Команда mosquitto_pub использует те же опции, что и mosquitto_sub, однако в этот раз используется дополнительный флаг –m (он позволяет ввести текст сообщения). Нажмите Enter, и вы увидите в другом терминале MQTT-сообщение hello world.

Введите во втором терминале CTRL+C, чтобы остановить mosquitto_sub, но не прерывайте подключения к серверу (оно понадобится позже).

Теперь нужно защитить трафик с помощью SSL-сертификата. Используйте Certbot, новый клиент Let’s Encrypt.

2: Установка Certbot

Let’s Encrypt – это новый сервис, предоставляющий бесплатные SSL-сертификаты при помощи автоматического API. Для взаимодействия с API существует несколько клиентов. Официальный клиент можно найти в репозитории Ubuntu, но он немного устарел и не предоставляет всех необходимых функций.

Вместо него мы используем официальный клиент из PPA Ubuntu, где можно найти более новые версии программ.

Добавьте репозиторий:

sudo add-apt-repository ppa:certbot/certbot

Нажмите Enter, чтобы продолжить. После этого обновите индекс пакетов.

sudo apt-get update

Установите Certbot:

sudo apt-get install certbot

3: Запуск Certbot

Чтобы подтвердить права на домен, Certbot должен пройти криптографический тест интерфейса Let’s Encrypt. Для этого используются порты 80 (HTTP) и/или 443 (HTTPS). В руководстве используется только порт 80. Разблокируйте его в брандмауэре.

sudo ufw allow http
Rule added

Теперь можно запустить Certbot, чтобы получить сертификат. Используйте опцию –standalone, чтобы Certbot самостоятельно обрабатывал тестовый запрос HTTP. Опция —standalone-supported-challenges http-01 ограничивает взаимодействие с интерфейсом портом 80. Опция -d позволяет указать домен, для которого предназначен сертификат, а certonly извлекает сертификат.

sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com

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

4: Автоматическое обновление сертификата

Сертификаты Let’s Encrypt действительны в течение 90 дней. По истечении этого срока пользователь должен обновить сертификат. Вы можете настроить автоматическое обновление сертификатов.

Чтобы ежедневно запускать команду для проверки и обновления сертификата, используйте cron. Откройте crontab в редакторе:

sudo crontab -e

Выберите текстовый редактор. На экране появится crontab по умолчанию. Вставьте следующую строку в конец файла:

. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

Часть строки «15 3 * * *» значит, что команду нужно запускать в 3:15 утра каждый день. Команда renew будет проверять все существующие сертификаты и обновлять их по мере необходимости (если до окончания срока действия остается меньше 30 дней). Флаг –noninteractive запускает процесс в немом режиме.

Флаг —post-hook «systemctl restart mosquitto» перезапустит Mosquitto, чтобы загрузить новый сертификат (только если сертификат был обновлен). Опции post-hook нет ни в одном клиенте Let’s Encrypt, кроме Certbot. Без неё вам пришлось бы самостоятельно перезапускать Mosquitto каждый день.

5: Настройка пароля MQTT

Теперь настройте пароль для Mosquitto.

Mosquitto предоставляет утилиту mosquitto_passwd для генерирования файла паролей. Эта команда предложит ввести пароль для указанного пользователя и поместит результат в /etc/mosquitto/passwd.

sudo mosquitto_passwd -c /etc/mosquitto/passwd 8host

Откройте конфигурационный файл Mosquitto и добавьте информацию о новом файле паролей:

sudo nano /etc/mosquitto/conf.d/default.conf

На экране появится пустой файл. Введите:

allow_anonymous false
password_file /etc/mosquitto/passwd

Строка allow_anonymous false блокирует доступ анонимных пользователей. Строка password_file указывает путь к файлу паролей. Сохраните и закройте файл.

Перезапустите Mosquitto:

sudo systemctl restart mosquitto

Теперь нужно протестировать новые настройки. Попробуйте опубликовать сообщение без пароля:

mosquitto_pub -h localhost -t "test" -m "hello world"

Сервер должен отклонить сообщение:

Connection Refused: not authorised.
Error: The connection was refused.

Перейдите во второй терминал и подпишитесь на тему test.

mosquitto_sub -h localhost -t test -u "8host" -P "password"

Оставьте этот терминал открытым до конца руководства, чтобы периодически отправлять в него тестовые сообщения.

Вернитесь в первый терминал и опубликуйте сообщение:

mosquitto_pub -h localhost -t "test" -m "hello world" -u "8host" -P "password"

Сообщение появится во втором терминале. Если это так, то настройка пароля Mosquitto прошла успешно.

Пока что пароли передаются в незашифрованном виде. Чтобы исправить это, нужно настроить Mosquitto для поддержки SSL-шифрования.

6: Настройка поддержки SSL

Чтобы настроить шифрование, нужно изменить права на сертификаты Let’s Encrypt.

Процесс mosquitto запускается не через root, а через пользователя mosquitto из соображений безопасности. Но для чтения сертификатов SSL нужны права root.

Чтобы не изменять владельца файлов, добавьте сертификаты в группу mosquitto:

sudo chgrp -R mosquitto /etc/letsencrypt/archive/mqtt.example.com/

Команда chgrp -R обновит группу указанного каталога и всех файлов в нём. Однако Certbot, обновляя сертификаты, будет создавать новые файлы, которые будут принадлежать root, а при перезапуске Mosquitto будет возникать ошибка.

Чтобы исправить это, нужно установить SGID на каталог сертификатов. SGID – это параметр прав доступа, который передаёт права root другой группе (в данном случае mosquitto).

sudo chmod g+s /etc/letsencrypt/archive/mqtt.example.com/

Убедитесь, что изменения вступили в силу:

sudo ls -al /etc/letsencrypt/archive/mqtt.example.com/

В каталоге должен быть установлен бит SGID.

drwxr-sr-x 2 root mosquitto 4096 Oct 5 17:48 .

В привилегиях (последовательности drwxr-sr-x) есть символ s. Каталог должен принадлежать группе mosquitto.

Попробуйте также запросить права группы mosquitto на сертификаты.

-rw-r--r-- 1 root mosquitto 1809 Oct 1 16:42 cert1.pem

Если все установлено верно, можно обновить конфигурации Mosquitto. Откройте конфигурационный файл:

sudo nano /etc/mosquitto/conf.d/default.conf

Добавьте в него:

. . .
listener 1883 localhost
listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

Теперь файл содержит два отдельных блока listener. Первый, listener 1883 localhost, обновляет прослушиватель MQTT
на порте 1883 (это стандартный нешифрованный порт MQTT). Часть строки localhost привязывает этот порт к интерфейсу локального хоста, потому к нему не будет внешнего доступа (в любом случае, внешние запросы заблокировал бы брандмауэр).

Строка listener 8883 настраивает зашифрованный прослушиватель на порт 8883. Это стандартный порт MQTT + SSL (также называется MQTTS). Следующие три строки, certfile, cafile и keyfile указывают Mosquitto путь к файлам сертификата Let’s Encrypt.

Сохраните и закройте файл. Перезапустите Mosquitto:

sudo systemctl restart mosquitto

Откройте порт 8883 в брандмауэре.

sudo ufw allow 8883
Rule added

Создайте ещё одно тестовое сообщение с помощью mosquitto_pub, добавив несколько опций для SSL:

mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --capath /etc/ssl/certs/ -u "8host" -P "password"

Обратите внимание: вместо localhost используется полное имя хоста. Поскольку сертификат SSL предназначен для домена (в данном случае для mqtt.example.com), при попытке подключиться к localhost вы получите ошибку: имя хоста не совпадает с именем хоста сертификата (несмотря на то, что оба они указывают на один сервер Mosquitto).

Опция —capath /etc/ssl/certs/ включает SSL для mosquitto_pub и сообщает, где найти root-сертификаты. Путь зависит от операционной системы. Команда mosquitto_pub проверяет подпись сертификата сервера Mosquitto. Команды mosquitto_pub и mosquitto_sub не смогут создать SSL-соединение без этой опции (или её аналога, —cafile) даже с помощью стандартного порта 8883.

Если настройка выполнена правильно, во втором терминале появится сообщение «hello again». MQTT-сервер полностью готов к работе.

7: Поддержка веб-сокетов (опционально)

Для взаимодействия с JavaScript в браузерах в протокол MQTT была добавлена поддержка стандартных веб-сокетов.

Чтобы включить эту функцию, нужно добавить ещё один блок listener в настройки Mosqiutto:

sudo nano /etc/mosquitto/conf.d/default.conf

Добавьте в конец файла:

. . .
listener 8083
protocol websockets
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

Этот блок почти такой же, как предыдущие, он отличается толлько номером порта и строкой protocol websockets. У MQTT нет стандартного порта для поддержки веб-сокетов, обычно для этого используется 8083.

Сохраните и закройте файл. Перезапустите сервер:

sudo systemctl restart mosquitto

Откройте этот порт в брандмауэре:

sudo ufw allow 8083

Чтобы протестировать эту настройку, используйте открытый MQTT-клиент для браузера (например, mqtt-admin). Откройте mqtt-admin в браузере.

На экране появится окно настроек.

Заполните предложенные поля:

  • Protocol: wss (что значит websocket secure).
  • Host: домен сервера Mosquitto.
  • Port: 8083.
  • User: имя пользователя Mosquitto (в данном случае 8host).
  • Password: пароль.
  • ClientId: можно оставить по умолчанию (mqtt-admin).

Нажмите Save Settings, после чего mqtt-admin подключится к серверу Mosquitto. В следующем окне укажите:

  • Topic: test
  • Payload: введите любое сообщение

Нажмите Publish. Сообщение должно появиться в терминале mosquitto_sub.

Заключение

Сервер MQTT установлен, защищен паролем и готов к работе. SSL-сертификат Let’s Encrypt шифрует трафик и автоматически обновляется. Теперь у вас есть надёжная платформа для обмена сообщениями.

С протоколом MQTT хорошо работают следующие программы:

  • OwnTracks – открытое приложение геолокации, которое можно установить на телефон. Полученные данные можно переносить на карту, на их основе можно создавать предупреждения и настроить запуск компонентов интернета вещей.
  • Node-RED – графический веб-интерфейс для настройки интернета вещей. Инструмент позволяет перенаправлять вывод одной ноды на ввод другой, фильтровать данные, применять разные протоколы и базы данных и многое другое.
  • ESP8266 – недорогой wifi микроконтроллер с поддержкой MQTT. С его помощью вы можете следить за температурой, атмосферным давлением и т.п.
QR Code - Take this post Mobile!
Use this unique QR (Quick Response) code with your smart device. The code will save the url of this webpage to the device for mobile sharing and storage.
Понравилось? Поделитесь:

:

Sorry, the comment form is closed at this time.