Перейти к содержанию

Подключите Shelly к RabbitMQ через MQTT mTLS.

Материал из База знаний Shelly

Краткое описание

[править]

Это решение обеспечивает безопасное подключение IP-устройства Shelly к RabbitMQ через плагин MQTT с использованием взаимного TLS (mTLS), без паролей, с применением взаимной аутентификации на основе сертификатов. Один скрипт Bash устанавливает и настраивает RabbitMQ, генерирует частный центр сертификации (CA), сертификаты сервера и клиента, а затем отображает таблицу значений конфигурации. После завершения единственного ручного действия на Shelly — это загрузка ca.crt , client.crt и client.key , копирование этих значений в настройки MQTT и сохранение. Поддерживает выбор серий RabbitMQ ( --rmq-series 3.13|4.0|4.1 , по умолчанию 4.1) из репозиториев Ubuntu noble от Team RabbitMQ и принудительно использует только TLS 1.2. В версии 4.x идентификатор клиента MQTT (client_id) определяется на основе сертификата (SAN, URI), в то время как аутентифицированное имя пользователя (username) по-прежнему определяется на основе сертификата (CN); в версии 3.13 привязка SAN->client_id недоступна. Вы можете управлять хостом подключения (и CN/SAN сертификата сервера) с помощью --connect-dns / --connect-ip . Скрипт экспортирует сертификаты устройств в /etc/mqtt-cert

и по умолчанию также выдает сертификат монитора (-mon ) в /etc/mqtt-cert-monitor с архивами в /tmp/. Результат: зашифрованный MQTT с аутентификацией по сертификату и доступом к темам с минимальными привилегиями.

Ссылка на скрипт: здесь

Важно:

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

Архитектура

[править]

СХЕМА

[Устройство Shelly] |

| MQTT через TLS (mTLS) - порт 8883 v [Слушатель RabbitMQ MQTT] ---> [обмен amq.topic] ---> [очереди/подписки] | |

| ‘-- ACL тем, ограниченные вашим префиксом MQTT |

«-- Пользовательский интерфейс управления (HTTPS, 15671)

  • Транспорт: Shelly взаимодействует с RabbitMQ по порту 8883 (MQTTS). Требуется TLS; клиенты должны предоставить действительный сертификат (mTLS), принудительно используется только TLS 1.2.
  • Идентификация: Сертификат устройства CN сопоставляется с пользователем RabbitMQ (в Shelly нет имени пользователя/пароля).
  • Привязка идентификатора клиента: Принудительно осуществляется из SAN сертификата (URI) в RabbitMQ 4.x. Имя пользователя по-прежнему берется из CN; версия 3.13 не поддерживает SAN→client_id.

» * Авторизация: Списки контроля доступа к темам ограничены выбранным вами префиксом MQTT (плюс доступ только для чтения к shellies/command для совместимости).

  • Арендаторство: MQTT не передает виртуальные хосты, поэтому соединения направляются на выделенный виртуальный хост (например, /shelly ) через mqtt.vhost .
  • Управление: HTTPS-интерфейс на 15671.
  • Порты без ограничений: По умолчанию отключено. Вы можете временно сохранить 1883/15672 с помощью --keep-plaintext во время миграции.

Краткая справка

[править]
Внимание! Решение
Порт (данные) 8883 / TCP (MQTTS с mTLS)
Порт (администратор) 15671 / TCP (интерфейс управления HTTPS)
Идентификатор CN сертификата -> пользователь RabbitMQ
Идентификатор клиента Предоставляется пользователем в Shelly; в RabbitMQ 4.x он определяется из SAN сертификата (URI). В версии 3.13 привязка SAN -> client_id недоступна
Vhost /shelly (устанавливается через mqtt.vhost)
Темы Ограничено вашим префиксом MQTT (как в форме косой черты, так и в форме точки), а также shellies/command только для чтения (shellies.command)
Секреты на устройстве Только ключ клиента (без паролей)
Открытый текст По умолчанию отключено; можно включить с помощью --keep-plaintext
Версия TLS Только TLS 1.2

Предварительные условия

[править]
  • Протестированная среда (на момент написания): Ubuntu 24.04 LTS (amd64), RabbitMQ 4.1 (установлен с помощью этого скрипта), прошивка Shelly 1.7.1.
  • Установка: из репозиториев Team RabbitMQ, закрепленных в Ubuntu noble.
  • Доступ: Оболочка на хосте с правами sudo; исходящий интернет для репозиториев apt.
  • Адресация: Стабильный IP-адрес/DNS брокера (скрипт может автоматически определять, фиксированный лучше).
  • Синхронизация времени: NTP включен (действительность сертификата зависит от правильного времени).
  • Необязательно: mosquitto-clients для быстрого сквозного тестирования.

Что делает скрипт

[править]
  1. Установка RabbitMQ (3.13 / 4.0 / 4.1) + соответствующий Erlang на Ubuntu 24.04 Использует репозитории apt Team RabbitMQ (рекомендуемый путь) для получения современного Erlang/RabbitMQ. https://www.rabbitmq.com/docs/install-debian
  2. Настройка через rabbitmq.conf (а не rabbitmq-env.conf) Настройки среды выполнения (слушатели, TLS, плагины) находятся в rabbitmq.conf; rabbitmq-env.conf предназначен только для переменных окружения. https://www.rabbitmq.com/docs/configure
  3. Включить плагины MQTT + управления Включает встроенную поддержку MQTT и управление/пользовательский интерфейс HTTPS, а также активирует rabbitmq_auth_mechanism_ssl. https://www.rabbitmq.com/docs/mqtt Включить флаг функции detailed_queues_endpoint (подробная информация о очередях только в пользовательском интерфейсе).
  1. Принудительное использование взаимного TLS (mTLS) для MQTT Устанавливает ssl_options.verify = verify_peer и ssl_options.fail_if_no_peer_cert = true, поэтому клиенты должны предоставлять действительный сертификат; принудительно использует только TLS 1.2. https://www.rabbitmq.com/docs/mqtt#tls
  2. Вход по сертификату без пароля (CN → пользователь) Включает mqtt.ssl_cert_login = true и ssl_cert_login_from = common_name. Сопоставленный пользователь должен существовать в RabbitMQ (пароль не требуется). https://www.rabbitmq.com/docs/mqtt#tls-certificate-authentication
  3. Привязка client_id MQTT к SAN сертификата (URI) В RabbitMQ 4.1 устанавливает

BASH

mqtt.ssl_cert_client_id_from = subject_alternative_name

таким образом, CONNECT client_id

должен совпадать с SAN сертификата (предотвращает подмену идентификатора).

https://www.rabbitmq.com/docs/mqtt#usage-of-client_id-extraction-from-client-certificates-for-authentication

Это привязывает client_id к сертификату SAN (URI) .

Имя пользователя по-прежнему берется из CN

если вы хотите, чтобы

имя пользователя было из SAN

вместо этого, вам следует изменить ssl_cert_login_from=subject_alternative_name и ssl_cert_login_san_type=uri

в конфигурации.

  1. Выдача двух клиентских сертификатов (один и тот же CN, разные SAN) * устройство: SAN=URI:
  • монитор: SAN=URI: -mon
  • Профили сертификатов : CA RSA-4096; сервер/клиент RSA-2048; срок действия конечного сертификата ≈ 825 дней

Позволяет подписаться на сертификат монитора без отключения устройства (различные идентификаторы клиентов).

  1. Блокировка прослушивателей и портов * MQTTS: 8883
  • Управление (HTTPS): 15671
  • Обычный 1883/15672 отключен по умолчанию; опционально при миграции с помощью --keep-plaintext. https://www.rabbitmq.com/docs/networking
  1. Создание арендатора и разрешений * Направляет MQTT-сессии на /shelly (через mqtt.vhost). https://www.rabbitmq.com/docs/vhosts
  • Применяет разрешения для темы, так что публикация/подписка ограничена вашим префиксом MQTT (плюс shellies/command только для чтения). https://www.rabbitmq.com/docs/man/rabbitmqctl.8#Access_control
  • Удаляет пользователя guest по умолчанию.
  • Если set_topic_permissions недоступен в вашем RabbitMQ, скрипт выдаст предупреждение и оставит более широкий доступ к теме до обновления.
  1. Вывод, используемый на Shelly Создает папку экспорта с файлами ca.crt, client.crt, client.key и выводит таблицу точных значений для копирования в настройки Shelly MQTT.

Реализация

[править]
  1. Запуск скрипта

BASH

./shelly-rmq-mqtt/setup-mqtt-mtls.sh \ --admin-user admin \ --admin-pass 'Sh3lly-i0T!' \ -C 'Shelly-Group' \ --client-id 'test-device' \ --vhost /shelly \ --mqtt-prefix 1pm-mini

Приоритет хоста подключения (и CN сертификата):

--connect-dns > --connect-ip > --ip (автоматически определяется, если нет). Выбранное значение становится сертификатом сервера CN

и тем, на который должны набираться клиенты. Полезные флаги (при необходимости)

BASH

Идентификатор / Целевой адрес подключения (на который набираются клиенты; определяет CN/SAN сертификата) --connect-dns

  1. предпочтительно: клиенты набирают это имя

--connect-ip

  1. клиенты набирают этот IP-адрес (если нет DNS)

Идентификатор хоста (эта машина) -i | --ip | --server-ip

  1. переопределяет обнаруженный основной IP-адрес (используется в сводке и SAN)

MQTT / аренда / темы -V | --vhost

  1. по умолчанию /shelly

--mqtt-prefix

  1. область действия ACL для тем

Сертификаты / выходные данные --tls-dir

  1. по умолчанию /etc/rabbitmq-tls

--export-dir

  1. по умолчанию /etc/mqtt-cert

--monitor-export-dir

  1. по умолчанию /etc/mqtt-cert-monitor

--no-monitor-cert # пропустить -mon bundle --monitor-client-id

  1. по умолчанию

-mon --force-regen # ротация CA/сервера/клиента, даже если присутствует

Версионирование RabbitMQ --rmq-series 3.13|4.0|4.1 # по умолчанию 4.1

Аутентификация / пользователи --admin-user

  1. администратор по умолчанию

-p | --admin-pass

  1. автоматически генерируется по умолчанию, если опущено

-C | --client-cn

  1. Группа Shelly по умолчанию

--client-id

  1. по умолчанию =

Сеть (временная совместимость) --keep-plaintext # оставить открытыми порты 1883/15672 во время миграции

Ведение логов / диагностика -l | --log-level debug|info|warn|error -d | --debug # потоковые логи; без индикатора загрузки --debug-tls | --tls-debug # вывести диагностику сертификата (или DEBUG_TLS=1)

Скрипт будет запущен и будет проходить каждый шаг, отображая индикатор успеха и ошибку, если она возникнет.

Шаги скрипта После завершения обратите внимание на сводную таблицу внизу:

  • IP-адрес/порты брокера
  • ID клиента и префикс MQTT
  • Пути к ca.crt, client.crt, client.key (папка экспорта)
  • Параметры конфигурации Shelly
  • URL управления: https:// :15671 (или https:// :15671, если CN — IP-адрес)
  • Имя пользователя и пароль администратора (пароль генерируется автоматически, если не указан параметр --admin-pass)
  • Путь к файлу журнала: /tmp/rabbitmq-mqtt-setup.log

Сводная таблица скрипта

  1. Загрузка сертификатов в Shelly Откройте Веб-интерфейс Shelly → Настройки → Конфигурация TLS. Загрузите три файла из папки экспорта скрипта: * Сертификат CA: ca.crt
  • Сертификат клиента: client.crt
  • Закрытый ключ клиента: client.key. Загрузите каждый файл по отдельности: выберите файл, нажмите «Загрузить» и дождитесь всплывающего окна с подтверждением успешной загрузки. Повторите для всех трех файлов.

Скрипт конфигурации Shelly

  1. Настройка Shelly MQTT Откройте веб-интерфейс Shelly → Настройки → MQTT. Настройте значения из скрипта:

ТЕКСТ

Включить: Выбрано TLS пользователя: Выбрано Использовать сертификат клиента: Включено Включить «Управление MQTT»: Включено Включить RPC через MQTT: Включено Уведомления о состоянии RPC через MQTT: Включено Общее обновление состояния через MQTT: Включено Сервер: Значение из скрипта Идентификатор клиента: Значение из скрипта Префикс MQTT: Значение из скрипта Имя пользователя / Пароль: Оставьте пустым

  1. Нажмите «Сохранить настройки» и перезагрузите устройство

После завершения настройки устройство должно выглядеть следующим образом: Веб-интерфейс настройки MQTT Shelly

  1. После перезагрузки Shelly выполните команду мониторинга, которая отображается в сводке скрипта. Она автоматически генерируется на основе предоставленных вами значений и использует сертификат монитора (distinct client_id), поэтому устройство не будет отключено. Вы должны увидеть сообщения, поступающие от Shelly к RabbitMQ.

Готовность к выполнению команды мониторинга Вы должны увидеть, как Shelly подключается и публикует сообщения.

Мониторинг сообщений Shelly в RabbitMQ Вы также можете подтвердить успешное подключение в веб-интерфейсе Shelly: значок MQTT в правом верхнем углу показывает две стрелки при подключении. Если вы видите стрелки, устройство активно связано с RabbitMQ по протоколу MQTT/TLS.

Индикатор успешного подключения Shelly MQTT Вы также можете увидеть индикатор в веб-интерфейсе RabbitMQ в разделе «Подключения». Файл:RabbitMQ Web UI Connection info.png Статус подключения в веб-интерфейсе RabbitMQ Информация о подключении в веб-интерфейсе RabbitMQ Скрипт также выводит сводку отладки сертификатов, помогая вам увидеть, какие сертификаты были сгенерированы, чтобы минимизировать возможные проблемы. Пожалуйста, имейте в виду, что вам необходимо использовать --debug-tls флаг .

Шаги отладки сертификата

Устранение неполадок

[править]
  1. Синхронизация времени - Убедитесь, что часы брокера и Shelly установлены правильно (NTP). Искажение времени нарушает работу TLS.
  1. Загружены три файла - ca.crt, client.crt, client.key (каждый загружен отдельно, всплывающее окно об успешной загрузке).
  1. Идентификатор клиента против SAN - В RabbitMQ 4.1 идентификатор клиента MQTT должен совпадать с SAN (URI) сертификата. Если они различаются, соединение отклоняется. * В RabbitMQ 3.13 привязка client_id из SAN не поддерживается; используется только CN->username.
  1. CN user exists - Сертификат CN должен соответствовать существующему пользователю RabbitMQ (пароль не требуется при использовании mTLS).
  1. Ports - Используйте 8883 (MQTTS). Порты 1883/15672 отключены, если вы не запускали скрипт с параметром --keep-plaintext.
  1. Firewall - Если UFW активен, скрипт открывает порты 8883 и 15671; в противном случае он не изменяет правила брандмауэра.
  1. Prefix - Темы должны находиться в пределах вашего префикса MQTT, иначе ACL RabbitMQ заблокируют их.
  1. Совпадение ключа и сертификата: Если соединение не удается, запустите с параметром --debug-tls и проверьте строку «совпадение ключа и сертификата» как для сервера, так и для клиента.