Поиск по сайту:

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


На этой странице

  1. Предпосылки
  2. Шаг 1. Установите сервер и клиент Mosquitto
  3. Шаг 2. Настройка аутентификации по паролю MQTT
  4. Шаг 3. Тестирование клиента Mosquitto
  5. Шаг 4. Установите SSL
  6. Шаг 5. Настройка MQTT SSL
  7. Шаг 6. Настройка продления SSL
  8. Шаг 7. Настройка веб-сокетов
  9. Заключение

Mosquitto — это брокер сообщений с открытым исходным кодом, который использует протокол передачи телеметрии очереди сообщений (MQTT). Протокол предназначен для облегчения связи с устройствами Интернета вещей (IoT). Он обычно используется для GPS-слежения за транспортными средствами, домашней автоматизацией, датчиками окружающей среды и крупномасштабным сбором данных.

Протокол MQTT работает поверх модели TCP/IP. Будучи легким, его небольшой объем кода позволяет создавать приложения для устройств с минимальными ресурсами. Он основан на модели публикации/подписки. В этой модели клиент подключается к серверу Mosquitto, который действует как посредник для отправки информации другим клиентам, подписавшимся на канал.

В этом руководстве вы установите Mosquitto и настроите брокера для использования SSL для защиты связи.

Предпосылки

  • Сервер Ubuntu 20.04 с пользователем без полномочий root с привилегиями sudo.
  • Доменное имя (myqtt.example.com), указывающее на ваш сервер.

Шаг 1. Установите сервер и клиент Mosquitto.

Ubuntu поставляется со старой версией Mosquitto 1.6. Чтобы установить последнюю версию, добавьте официальный репозиторий Mosquitto.

$ sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa

Установите сервер Mosquitto и клиент.

$ sudo apt install mosquitto mosquitto-clients

Проверьте состояние сервера.

$ sudo systemctl status mosquitto
? mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2022-01-25 09:18:40 UTC; 25s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 119694 (mosquitto)
      Tasks: 1 (limit: 2274)
     Memory: 1.0M
     CGroup: /system.slice/mosquitto.service
             ??119694 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 25 09:18:39 <userid> systemd[1]: Starting Mosquitto MQTT Broker...
Jan 25 09:18:40 <userid> systemd[1]: Started Mosquitto MQTT Broker.

Шаг 2. Настройте аутентификацию по паролю MQTT

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

Выполните следующую команду, чтобы сгенерировать зашифрованный файл паролей в /etc/mosquitto/passwd для имени пользователя username. Введите пароль по вашему выбору.

$ sudo mosquitto_passwd -c /etc/mosquitto/passwd username
Password:
Reenter password:

Затем создайте файл default.conf в каталоге /etc/mosquitto/conf.d и откройте его для редактирования.

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

Вставьте следующие строки, чтобы указать расположение файла паролей. Если вы опустите поле прослушивателя, он всегда будет подключаться анонимно, независимо от конфигурации.

listener 1883
password_file /etc/mosquitto/passwd

Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.

Перезапустите сервер Mosquitto, чтобы изменения вступили в силу.

$ sudo systemctl restart mosquitto

Шаг 3. Тестирование клиента Mosquitto

В зависимости от варианта использования вы можете использовать клиент Mosquitto для отправки и получения сообщений на разные темы. Клиент является либо подписчиком, либо издателем.

Следующим шагом является подписка на тему. В протоколе MQTT тема относится к строке, используемой сервером/брокером для фильтрации сообщений для подключенных клиентов. Вот несколько примеров тем, которые вы можете использовать в приложении домашней автоматизации.

  • дом/освещение/гостиная_комната
  • дом/освещение/кухня
  • home/lights/master_bedroom
  • дом/свет/детская_спальня

Чтобы подписаться на тему, выполните команду mosquitto_sub -t, а затем укажите тему. Например, чтобы подписаться на тему home/lights/kitchen, выполните следующую команду.

$ mosquitto_sub -u username -P YOUR_PASSWORD -t "home/lights/kitchen"

Не закрывайте существующее окно. Откройте новое окно терминала, чтобы опубликовать сообщение в теме home/lights/kitchen с помощью следующей команды.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "ON" -t "home/lights/kitchen"

Вернитесь к первому окну терминала, и вы получите полезную нагрузку ON.

ON

Затем отправьте сообщение OFF на ту же тему со второго терминала.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "OFF" -t "home/lights/kitchen"

Первый терминал покажет только что опубликованное сообщение.

ON
OFF

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

$ mosquitto_sub -t "home/lights/sitting_room"
Connection error: Connection Refused: not authorised.

Это не рекомендуется, но вам нужно добавить следующую строку в файл /etc/mosquitto/conf.d/default.conf, если вы хотите запускать команды без аутентификации.

allow_anonymous true

Шаг 4 — Установите SSL

Чтобы установить SSL-сертификат с помощью Lets Encrypt, нам нужно загрузить инструмент Certbot. Для этого мы будем использовать установщик пакета Snapd.

Установите установщик снапа.

$ sudo apt install snapd

Убедитесь, что ваша версия Snapd обновлена.

$ sudo snap install core 
$ sudo snap refresh core

Установите Сертбот.

$ sudo snap install --classic certbot

Используйте следующую команду, чтобы убедиться, что команда Certbot выполняется, создав символическую ссылку на каталог /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Создайте SSL-сертификат.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m  -d mqtt.example.com

Приведенная выше команда загрузит сертификат в каталог /etc/letsencrypt/live/mqtt.example.com на вашем сервере.

Создайте групповой сертификат Диффи-Хеллмана.

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Создайте корневую веб-директорию для автоматического обновления Lets Encrypt.

$ sudo mkdir -p /var/lib/letsencrypt

Создайте задание Cron для обновления SSL. Он будет запускаться каждый день для проверки сертификата и его обновления при необходимости. Для этого сначала создайте файл /etc/cron.daily/certbot-renew и откройте его для редактирования.

$ sudo nano /etc/cron.daily/certbot-renew

Вставьте следующий код.

#!/bin/sh
certbot renew --cert-name mqtt.example.com --webroot -w /var/lib/letsencrypt/

Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.

Измените права доступа к файлу задачи, чтобы сделать его исполняемым.

$ sudo chmod +x /etc/cron.daily/certbot-renew

Шаг 5. Настройте MQTT SSL

Теперь, когда у нас есть готовые SSL-сертификаты, нам нужно предоставить Mosquitto доступ к ним. Для этого нам нужно скопировать сертификаты в место, откуда Mosquitto может получить к ним доступ.

$ sudo cp /etc/letsencrypt/live/mqtt.example.com/fullchain.pem /etc/mosquitto/certs/server.pem
$ sudo cp /etc/letsencrypt/live/mqtt.example.com/privkey.pem /etc/mosquitto/certs/server.key

Измените владельца каталога /etc/mosquitto/certs на пользователя mosquitto, созданного во время установки.

$ sudo chown mosquitto: /etc/mosquitto/certs

Следующим шагом для включения шифрования SSL для Mosquitto является указание местоположения сертификатов SSL. Откройте файл конфигурации для редактирования.

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

Вставьте следующий код в конец файла.

. . .
listener 8883
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса. Обязательно оставьте завершающую новую строку в конце файла.

Часть listener 8883 настраивает зашифрованный прослушиватель. Это стандартный порт для MQTT + SSL, называемый MQTTS. Следующие четыре строки определяют расположение файлов SSL.

Перезапустите Mosquitto, чтобы обновить настройки.

$ sudo systemctl restart mosquitto

Вам нужно будет обновить брандмауэр, чтобы разрешить подключения к порту 8883.

$ sudo ufw allow 8883

Далее нам нужно протестировать функциональность с помощью команды mosquitto_pub.

$ mosquitto_pub -h mqtt.example.com -t "home/lights/kitchen" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u username -P YOUR_PASSWORD

Как видите, мы включили некоторые дополнительные параметры, в том числе номер порта и путь к SSL-сертификатам. Всякий раз, когда вам нужно использовать SSL, вам всегда нужно указывать полное имя хоста, т. е. mqtt.example.com вместо localhost, в противном случае выдало бы ошибку.

Вам также потребуется каждый раз добавлять директиву --capath. Он говорит клиенту Mosquitto искать корневые сертификаты, установленные операционной системой.

Шаг 6. Настройте обновление SSL

Certbot автоматически обновит ваш сертификат до истечения срока его действия. Но ему нужно указать скопировать обновленные сертификаты в каталог /etc/mosquitto/certs и перезапустить службу Mosquitto.

Мы собираемся сделать это, создав сценарий оболочки. Создайте файл mosquitto-copy.sh в каталоге /etc/letsencrypt/renewal-hooks/deploy.

$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

Вставьте в него следующий код. Замените значение переменной MY_DOMAIN своим доменом. Переменная $ {RENEWED_LINEAGE} указывает на каталог /etc/letsencrypt/live/mqtt.example.com во время обновления.

# Set which domain this script will be run for
MY_DOMAIN=mqtt.example.com
# Set the directory that the certificates will be copied to.
CERTIFICATE_DIR=/etc/mosquitto/certs

if [ "${RENEWED_DOMAINS}" = "${MY_DOMAIN}" ]; then
	# Copy new certificate to Mosquitto directory
	cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
	cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key

	# Set ownership to Mosquitto
	chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Ensure permissions are restrictive
	chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Tell Mosquitto to reload certificates and configuration
	pkill -HUP -x mosquitto
fi

Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.

Сделайте файл исполняемым.

$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

Этот сценарий будет автоматически запускаться при каждом успешном обновлении сертификата.

Если вы используете Mosquitto и веб-сервер, такой как Nginx, вам необходимо указать Certbot остановить сервер перед обновлением и запустить его снова после завершения. Для этого откройте файл etc/letsencrypt/renewal/mqtt.example.com.conf.

$ sudo nano /etc/letsencrypt/renewal/mqtt.example.com.conf

Добавьте следующие строки в конец файла. Измените команды в соответствии с используемым веб-сервером.

pre_hook = systemctl stop nginx
post_hook = systemctl start nginx

Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.

Запустите тестовый прогон Certbot для проверки.

$ sudo certbot renew --dry-run

Если вы не видите ошибок, значит, все настроено.

Шаг 7 — Настройте веб-сокеты

Вы можете настроить Mosquitto для использования протокола MQTT из браузеров, используя Javascript, используя функциональные возможности веб-сокетов. Чтобы включить его, откройте файл конфигурации.

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

Вставьте следующие строки в конец файла.

. . .
listener 8083
protocol websockets
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.

Если вы заметили, это тот же блок, который мы использовали для включения SSL, за исключением полей номера порта и протокола. 8083 — наиболее распространенный порт, используемый MQTT для общения с использованием WebSockets.

Перезапустите службу Mosquitto.

$ sudo systemctl restart mosquitto

Откройте порт 8083.

$ sudo ufw allow 8083

Нам нужно использовать клиент MQTT на основе браузера, чтобы протестировать функциональность WebSockets. Доступно множество клиентов, но для наших целей мы будем использовать клиент HiveMQ Websocket. Запустите клиент в браузере, и вы увидите следующее.

Как показано на скриншоте выше, заполните поля, как показано.

  • Хостом должен быть домен вашего сервера Mosquitto, mqtt.example.com.
  • Порт должен быть 8083.
  • Поле ClientID можно оставить без изменений.
  • Имя пользователя должно быть вашим именем пользователя Mosquitto.
  • Пароль должен быть паролем, который вы создали выше.
  • Установите флажок SSL.

Нажмите кнопку Connect, и клиент HiveMQ подключится к вашему серверу Mosquitto.

После подключения введите home/lights/kitchen в качестве темы, введите любое сообщение и нажмите «Опубликовать».

В окне терминала mosquitto_sub появится сообщение, подтверждающее успешное подключение.

Это показывает, что реализация Websockets выполнена успешно.

Заключение

На этом мы завершаем настройку безопасного, защищенного паролем и зашифрованного с помощью SSL сервера MQTT на компьютере с Ubuntu 20.04. Если у вас есть какие-либо вопросы, задайте их в комментариях ниже.