MQTT – это протокол сообщений machine-to-machine, предназначенный для коммуникации между устройствами интернета вещей. Он используется для отслеживания перемещения транспортных средств, настройки сенсорных сетей, домашней автоматизации и сбора данных.
Mosquitto – это популярный MQTT-сервер (на языке MQTT это называется брокер). Его несложно установить и настроить, а еще он активно поддерживается сообществом.
Этот мануал поможет установить Mosquitto, настроить поддержку SSL и безопасное взаимодействие устройств по протоколу MQTT.
Требования
- Сервер Debian 10, настроенный по этому мануалу.
- Домен, направленный на ваш сервер (здесь используется условный домен mqtt.example.com).
- Автоматически обновляемый сертификат Let’s Encrypt, сгенерированный с помощью Certbot. Получить такой сертификат вам поможет мануал Автоматическое извлечение SSL-сертификатов Let’s Encrypt с помощью Certbot в Debian 10. Вы также можете добавить systemctl restart mosquitto как renew_hook в разделе 4.
1: Установка Mosquitto
В репозитории Debian 10 можно найти относительно новую версию Mosquitto.
Для начала обновите индекс пакетов:
apt update
Чтобы установить Mosquitto, введите:
apt install mosquitto mosquitto-clients
По умолчанию в Debian сервис 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, но не прерывайте подключения (оно понадобится нам позже).
Теперь нужно настроить парольную аутентификацию.
2: Настройка пароля MQTT
Mosquitto предоставляет утилиту mosquitto_passwd для создания файла паролей. Эта команда предложит ввести пароль для указанного пользователя и поместит его в файл /etc/mosquitto/passwd.
mosquitto_passwd -c /etc/mosquitto/passwd 8host
Откройте конфигурации Mosquitto и добавьте в них информацию о новом файле:
nano /etc/mosquitto/conf.d/default.conf
На экране появится пустой файл. Введите в него:
allow_anonymous false
listener 1883 0.0.0.0
password_file /etc/mosquitto/passwd
В конце файла нужно обязательно оставить пустую строку.
Строка allow_anonymous false блокирует анонимных пользователей. Строка password_file задает путь к файлу паролей. Сохраните и закройте файл.
Теперь нужно перезапустить Mosquitto и проверить новые настройки:
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-шифрования.
3: Настройка поддержки SSL
Чтобы настроить SSL-шифрование, нужно показать Mosquitto, где хранятся сертификаты Let’s Encrypt. Откройте конфигурационный файл.
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:
systemctl restart mosquitto
Откройте порт 8883 в брандмауэре.
ufw allow 8883
Rule added
Rule added (v6)
Создайте ещё одно тестовое сообщение с помощью 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-сервер полностью готов к работе.
Если вы хотите расширить функции MQTT поддержкой веб-сокетов, следуйте инструкциям раздела 4.
4: Поддержка веб-сокетов (опционально)
Для взаимодействия с jаvascript в браузерах протокол MQTT предоставляет поддержку стандартных веб-сокетов. Если эта функция вам не нужна, можете просто не включать ее.
Чтобы включить ее, нужно добавить новый блок listener в настройки Mosqiutto:
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.
Сохраните и закройте файл. Перезапустите сервер:
systemctl restart mosquitto
Откройте порт 8083 в брандмауэре:
ufw allow 8083
Чтобы протестировать новые настройки, используйте открытый MQTT-клиент для браузера (например, Eclipse Paho jаvascript Client). Откройте клиент Paho jаvascript Client в браузере.
На экране появится окно настроек.
Заполните эту форму:
- Host: домен сервера (mqtt.example.com).
- Port: 8083.
- ClientId: можно оставить значение по умолчанию (js-utility-DI1m6).
- Path: можно оставить по умолчанию, /mqtt.
- Username: имя пользователя Mosquitto (в нашем случае 8host).
- Password: ваш пароль.
В остальных полях можно оставить значения по умолчанию.
Нажмите кнопку Connect, после чего клиент Paho подключится к серверу Mosquitto.
Чтобы опубликовать сообщение, перейдите в раздел Publish Message, в Topic введите test, а затем введите любое сообщение в поле Message. Нажмите кнопку Publish. Сообщение появится в терминале mosquitto_sub.