Как установить и обезопасить брокера обмена сообщениями Mosquitto MQTT на CentOS 7

Вступление

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. Вы увидите следующее:

mqtt-admin’s initial screen

Заполните информацию о соединении следующим образом:

  • 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. Получайте удовольствие, разговаривая друг с другом своими «вещами»!

Related