Вступление
MQTT - это протокол обмена сообщениями между машинами, предназначенный для облегчения обмена данными по публикации / подписке с устройствами «Интернета вещей». Он обычно используется для геотрекинга транспортных средств, домашней автоматизации, сетей датчиков окружающей среды и сбора данных в масштабах предприятия.
Mosquitto - популярный сервер MQTT (илиbroker, на языке MQTT), который имеет отличную поддержку сообщества и прост в установке и настройке.
В этом руководстве мы установим Mosquitto, получим SSL-сертификаты из Let's Encrypt и настроим нашего брокера на использование SSL для защиты наших защищенных паролем сообщений MQTT.
Предпосылки
Перед началом этого урока вам понадобится:
-
Сервер CentOS 7 с некорневым пользователем с поддержкой sudo и базовым настройкой брандмауэра. Все это (и многое другое) описано вNew CentOS 7 Server Checklist.
-
Доменное имя, указывающее на ваш сервер, согласноHow to Set Up a Host Name with DigitalOcean. В этом руководстве будет использоваться
mqtt.example.com
. -
При желании текстовый редактор
nano
. В этом руководстве будет использоватьсяnano
, и вы можете установить его в любое время с помощьюsudo yum -y install nano
или заменить свой любимый текстовый редактор.
[[step-1 -—- install-mosquitto]] == Шаг 1 - Установка Mosquitto
CentOS 7 по умолчанию не имеет пакетаmosquitto
. Чтобы установить его, мы сначала установим дополнительный репозиторий программного обеспечения, который называется Extra Packages for Enterprise Linux или EPEL. Этот репозиторий полон дополнительного программного обеспечения, которое хорошо устанавливается в CentOS, Red Hat и других корпоративных Linux-дистрибутивах.
Войдите в систему под своим пользователем без полномочий root и используйте менеджер пакетовyum
, чтобы установить пакетepel-release
.
sudo yum -y install epel-release
Это добавляет информацию о репозитории EPEL в нашу систему. Параметр-y
автоматически отвечает на несколько запросов на протяжении всего процесса. Теперь мы можем установить пакетmosquitto
.
sudo yum -y install mosquitto
Пакет поставляется с простой конфигурацией по умолчанию, поэтому давайте запустим его, чтобы проверить нашу установку.
sudo systemctl start mosquitto
Нам также необходимо включить службу, чтобы она запускалась при перезагрузке системы:
sudo systemctl enable mosquitto
Теперь давайте проверим конфигурацию по умолчанию. Пакетmosquitto
поставляется с некоторыми клиентами MQTT командной строки. Мы будем использовать один из них, чтобы подписаться на тему нашего брокера.
Topics - это ярлыки, на которые вы публикуете сообщения и на которые подписываетесь. Они организованы в виде иерархии, например, у вас могут бытьsensors/outside/temp
иsensors/outside/humidity
. Как вы организуете темы, зависит от вас и ваших потребностей. В этом уроке мы будем использовать простой тестовый раздел для проверки изменений конфигурации.
Войдите на свой сервер второй раз, чтобы у вас было два терминала рядом. В новом терминале используйтеmosquitto_sub
, чтобы подписаться на тестовую тему:
mosquitto_sub -h localhost -t test
-h
используется для указания имени хоста сервера MQTT, а-t
- это имя темы. Вы не увидите вывода после нажатияENTER
, потому чтоmosquitto_sub
ожидает прибытия сообщений. Вернитесь к другому терминалу и опубликуйте сообщение:
mosquitto_pub -h localhost -t test -m "hello world"
Параметры дляmosquitto_pub
такие же, как дляmosquitto_sub
, хотя на этот раз мы используем дополнительную опцию-m
для указания нашего сообщения. НажмитеENTER
, и вы должны увидеть всплывающее окноhello world в другом терминале. Вы отправили свое первое сообщение MQTT!
ВведитеCTRL+C
во втором терминале, чтобы выйти изmosquitto_sub
, но оставьте соединение с сервером открытым. Мы будем использовать его снова для другого теста в Шаге 5.
Затем мы защитим нашу установку с помощью SSL с помощью Certbot, нового клиента Let Encrypt.
[[step-2 -—- install-and-running-certbot-for-let-39-s-encrypt-Certific]] == Шаг 2. Установка и запуск Certbot для сертификатов Let's Encrypt
Let’s Encrypt - это новый сервис, предлагающий бесплатные SSL-сертификаты через автоматизированный API. Официальный клиент Let Encrypt называется Certbot и включен в репозиторий EPEL, который мы установили на предыдущем шаге.
Установите Certbot сyum
.
sudo yum -y install certbot
Certbot должен ответить на криптографический вызов, выпущенный API Let Encrypt, чтобы доказать, что мы контролируем наш домен. Для этого используются порты80
(HTTP) и / или443
(HTTPS). Мы будем использовать только порт80
, поэтому давайте разрешим входящий трафик на этот порт сейчас.
Используйтеfirewall-cmd
, чтобы добавить службу HTTP.
sudo firewall-cmd --permanent --add-service=http
Перезагрузите брандмауэр, чтобы изменения вступили в силу.
sudo firewall-cmd --reload
Теперь мы можем запустить Certbot, чтобы получить наш сертификат. Мы будем использовать опцию--standalone
, чтобы сообщить Certbot, что нужно самостоятельно обрабатывать HTTP-запрос вызова, а--standalone-supported-challenges http-01
ограничивает связь портом80
. -d
используется для указания домена, для которого вы хотите получить сертификат, аcertonly
сообщает Certbot, чтобы он просто получил сертификат, не выполняя никаких других действий по настройке.
sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com
При запуске команды вам будет предложено ввести адрес электронной почты и принять условия обслуживания. После этого вы должны увидеть сообщение о том, что процесс прошел успешно и где хранятся ваши сертификаты.
Мы получили наши сертификаты. Теперь нам нужно убедиться, что Certbot обновляет их автоматически, когда срок их действия истекает.
[[step-3 -—- setting-up-certbot-automatic-Renewals]] == Шаг 3 - Настройка автоматического продления Certbot
Сертификаты Let's Encrypt действительны только в течение девяноста дней. Это должно стимулировать пользователей автоматизировать процесс обновления их сертификатов. Нам нужно настроить регулярно запускаемую команду, чтобы проверять срок действия сертификатов и обновлять их автоматически.
Чтобы выполнять проверку обновлений ежедневно, мы будем использоватьcron
, стандартную системную службу для выполнения периодических заданий. Мы сообщаемcron
, что делать, открывая и редактируя файл с именемcrontab
.
sudo EDITOR=nano crontab -e
EDITOR=nano
откроет файл crontab в редактореnano
. Если вы предпочитаете редакторvi
по умолчанию, оставьте его.
Теперь вам должен быть представлен пустой файл по умолчаниюcrontab
. Вставьте следующую строку, затем сохраните и закройте файл.
кронтаб
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"
Часть15 3 * * *
в этой строке означает «запускать следующую команду в 3:15 каждый день». Командаrenew
для Certbot проверит все сертификаты, установленные в системе, и обновит все сертификаты, срок действия которых истекает менее чем через тридцать дней. --noninteractive
сообщает Certbot не ждать ввода данных пользователем.
--post-hook "systemctl restart mosquitto"
перезапустит Mosquitto, чтобы получить новый сертификат, но только если сертификат был продлен.
Теперь, когда автоматическое обновление сертификатов настроено, мы вернемся к настройке Mosquitto для обеспечения большей безопасности.
[[step-4 -—- configuring-mqtt-passwords]] == Шаг 4. Настройка паролей MQTT
Давайте настроим Mosquitto для использования паролей. Mosquitto включает утилиту для создания специального файла паролей с именемmosquitto_passwd
. Эта команда предложит вам ввести пароль для указанного имени пользователя и поместить результаты в/etc/mosquitto/passwd
.
sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy
Теперь мы заменим файл конфигурации по умолчанию и скажем Mosquitto использовать этот файл паролей, чтобы требовать входа в систему для всех подключений. Сначала удалите существующийmosquitto.conf
.
sudo rm /etc/mosquitto/mosquitto.conf
А теперь откройте новый пустой конфиг.
sudo nano /etc/mosquitto/mosquitto.conf
Вставьте в следующее.
/etc/mosquitto/mosquitto.conf
allow_anonymous false
password_file /etc/mosquitto/passwd
allow_anonymous false
отключит все неаутентифицированные соединения, а строкаpassword_file
сообщает Mosquitto, где искать информацию о пользователе и пароле. Сохраните и выйдите из файла.
Теперь нам нужно перезапустить Mosquitto и проверить наши изменения.
sudo systemctl restart mosquitto
Попробуйте опубликовать сообщение без пароля.
mosquitto_pub -h localhost -t "test" -m "hello world"
Сообщение должно быть отклонено:
OutputConnection Refused: not authorised.
Error: The connection was refused.
Прежде чем мы попытаемся снова с паролем, снова переключитесь на второе окно терминала и подпишитесь на тему «test», используя на этот раз имя пользователя и пароль:
mosquitto_sub -h localhost -t test -u "sammy" -P "password"
Стоит подключиться и сидеть, ждать сообщений. Вы можете оставить этот терминал открытым и подключенным до конца учебника, так как мы будем периодически отправлять ему тестовые сообщения.
Теперь опубликуйте сообщение на другом терминале, снова используя имя пользователя и пароль:
mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"
Сообщение должно пройти как в Шаге 1. Мы успешно добавили защиту паролем в Mosquitto. К сожалению, мы отправляем незашифрованные пароли через Интернет. Мы исправим это дальше, добавив SSL-шифрование в Mosquitto.
[[step-5 -—- configuring-mqtt-ssl]] == Шаг 5. Настройка MQTT SSL
Чтобы включить шифрование SSL, мы должны сообщить Mosquitto, где хранятся наши сертификаты Let Encrypt. Откройте файл конфигурации, который мы ранее запустили.
sudo nano /etc/mosquitto/mosquitto.conf
Вставьте следующее в конец файла, оставив две строки, которые мы уже добавили:
/etc/mosquitto/mosquitto.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
, к которому мы до сих пор подключались. 1883
- стандартный незашифрованный порт MQTT. Часть строкиlocalhost
указывает Mosquitto привязать этот порт только к интерфейсу localhost, поэтому он недоступен извне. Внешние запросы были бы заблокированы нашим брандмауэром в любом случае, но это хорошо, чтобы быть явным.
listener 8883
устанавливает зашифрованный прослушиватель на порт8883
. Это стандартный порт для MQTT + SSL, часто называемый MQTTS. Следующие три строки,certfile
,cafile
иkeyfile
, указывают Mosquitto на соответствующие файлы Let’s Encrypt для установки зашифрованных соединений.
Сохраните и выйдите из файла.
Прежде чем перезапустить Mosquitto для загрузки новой конфигурации, нам нужно исправить одну вещь в служебном файлеmosquitto
по умолчанию. Это файл, которыйsystemd
использует для определения того, как запускатьmosquitto
. Откройте его в своем любимом редакторе.
sudo nano /etc/systemd/system/multi-user.target.wants/mosquitto.service
Найдите строку с надписьюUser=mosquitto
и удалите ее, затем сохраните и выйдите из файла.
Mosquitto по-прежнему будет работать как пользовательmosquitto, но при первом запуске он будет иметь праваroot и сможет загружать наши сертификаты Let's Encrypt (которые ограниченыroot доступ в целях безопасности). После загрузки сертификатов он перейдет к пользователюmosquitto.
Нам нужно перезагрузить самsystemd
, чтобы он заметил изменения, которые мы внесли в служебный файл.
sudo systemctl daemon-reload
И теперь мы можем перезапустить Mosquitto, чтобы обновить настройки.
sudo systemctl restart mosquitto
Обновите брандмауэр, чтобы разрешить подключения к порту8883
.
sudo firewall-cmd --permanent --add-port=8883/tcp
И перезагрузите брандмауэр.
sudo firewall-cmd --reload
Теперь мы снова тестируем, используяmosquitto_pub
, с несколькими различными вариантами SSL.
mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --cafile /etc/ssl/certs/ca-bundle.crt -u "sammy" -P "password"
Обратите внимание, что мы используем полное имя хоста вместоlocalhost
. Поскольку наш SSL-сертификат выпущен дляmqtt.example.com
, если мы попытаемся установить безопасное соединение сlocalhost
, мы получим ошибку о том, что имя хоста не соответствует имени хоста сертификата (даже если они оба указывают на один и тот же Mosquitto). сервер).
--cafile /etc/ssl/certs/ca-bundle.crt
включает SSL дляmosquitto_pub
и сообщает ему, где искать корневые сертификаты. Обычно они устанавливаются вашей операционной системой, поэтому путь для Mac OS, Windows и т. Д. Отличается. mosquitto_pub
использует корневой сертификат для проверки того, что сертификат сервера Mosquitto был правильно подписан центром сертификации Let’s Encrypt. Важно отметить, чтоmosquitto_pub
иmosquitto_sub
не будут пытаться установить SSL-соединение без этой опции (или аналогичной опции--capath
), даже если вы подключаетесь к стандартному безопасному порту8883
с.
Если все пройдет успешно, мы увидим, чтоhello again появится в другом терминалеmosquitto_sub
. Это означает, что ваш сервер полностью настроен! Если вы хотите расширить протокол MQTT для работы с веб-сокетами, вы можете выполнить последний шаг.
[[step-6 -—- configuring-mqtt-over-websockets-optional]] == Шаг 6. Настройка MQTT через веб-сокеты (необязательно)
Чтобы говорить на MQTT с использованием JavaScript из веб-браузеров, протокол был адаптирован для работы над стандартными веб-сокетами. Если вам не нужны эти функции, вы можете пропустить этот шаг.
Нам нужно добавить еще один блокlistener
в нашу конфигурацию Mosquitto.
sudo nano /etc/mosquitto/mosquitto.conf
В конце файла добавьте следующее:
/etc/mosquitto/mosquitto.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
является наиболее распространенным.
Сохраните и выйдите из файла, затем перезапустите Mosquitto.
sudo systemctl restart mosquitto
Теперь откройте порт8083
в брандмауэре.
sudo firewall-cmd --permanent --add-port=8083/tcp
И перезагрузите брандмауэр в последний раз.
sudo firewall-cmd --reload
Чтобы протестировать эту функцию, мы будем использовать общедоступный клиент MQTT на основе браузера. Их несколько, ноmqtt-admin прост и понятен. Open mqtt-admin in your browser. Вы увидите следующее:
Заполните информацию о соединении следующим образом:
-
Protocol должно бытьwss (что означаетwebsocketsecure).
-
Host должен быть доменом вашего сервера Mosquitto,
mqtt.example.com
. -
Port должно быть
8083
. -
User должно быть вашим именем пользователя Mosquitto; здесь мы использовалиsammy.
-
Password должен быть выбранным вами паролем.
-
ДляClientId можно оставить значение по умолчаниюmqtt-admin.
После нажатияSave Settingsmqtt-admin
подключится к вашему серверу Mosquitto. На следующем экране введитеTopic какtest, введите любое сообщение дляPayload, затем нажмитеPublish. Сообщение появится в терминалеmosquitto_sub
.
Заключение
Теперь мы настроили защищенный, защищенный паролем MQTT-сервер с автоматическим обновлением SSL-сертификатов от службы Let Encrypt. Это послужит надежной и безопасной платформой обмена сообщениями для любых проектов, о которых вы мечтаете. Некоторые популярные программные и аппаратные средства, которые хорошо работают с протоколом MQTT, включают в себя:
-
OwnTracks, приложение с открытым исходным кодом для гео-отслеживания, которое вы можете установить на свой телефон. OwnTracks будет периодически сообщать информацию о местоположении на ваш MQTT-сервер, который вы затем сможете хранить и отображать на карте, или создавать оповещения и активировать оборудование IoT в зависимости от вашего местоположения.
-
Node-RED - это графический интерфейс на основе браузера для «связывания» Интернета вещей. Вы перетаскиваете выходные данные одного узла на вход другого и можете направлять информацию через фильтры, между различными протоколами, в базы данных и т. Д. MQTT очень хорошо поддерживается Node-RED.
-
ESP8266 - недорогой микроконтроллер Wi-Fi с возможностями MQTT. Вы можете подключить один из них, чтобы опубликовать данные о температуре в теме, или, возможно, подписаться на тему атмосферного давления и подать звуковой сигнал, когда надвигается гроза!
Это всего лишь несколько популярных примеров из экосистемы MQTT. Существует гораздо больше аппаратного и программного обеспечения, которое говорит на протоколе. Если у вас уже есть любимая аппаратная платформа или программный язык, возможно, у него есть возможности MQTT. Получайте удовольствие, разговаривая друг с другом своими «вещами»!