Безопасность MQTT и HTTP: TLS, аутентификация
Введение в безопасность MQTT и HTTP
В современной системе автоматизации, подключенной к сети, вопросы безопасности выходят на первый план. Развертывание контроллеров и IoT-устройств без обеспечения базовых мер защиты — это прямой путь к созданию уязвимостей, которые могут привести к серьезным последствиям: от нарушения работы систем жизнеобеспечения объекта до компрометации всей локальной сети.
> ⚠️ Внимание: Развертывание IoT-устройств без базовых мер безопасности создает серьезные риски не только для объекта, но и для всей сетевой инфраструктуры. Незащищенный контроллер может стать точкой входа для атак на другие устройства в вашей сети.
Для инженера автоматизации важно понимать основные векторы атак, чтобы грамотно им противодействовать:
- Перехват данных (Man-in-the-Middle, MITM): Злоумышленник размещается между двумя легитимными участниками обмена (например, между вашим контроллером и MQTT-брокером) и "прослушивает" весь трафик. В незащищенной сети он может не только читать, но и изменять передаваемые команды. Представьте, что команда на включение полива (`ON`) подменяется на команду на отключение системы безопасности (`OFF`).
- Спуфинг (Spoofing) или подмена устройства: Вредоносное устройство маскируется под легитимное. Например, неавторизованный датчик начинает отправлять ложные данные о высокой температуре, заставляя систему кондиционирования работать без остановки, что приводит к огромным счетам за электроэнергию и износу оборудования.
- Несанкционированный доступ и управление: Это прямая отправка команд на исполнительные устройства злоумышленником, получившим доступ к сети. В простейшем случае это может быть баловство с включением и выключением света, а в худшем — открытие замков, отключение насосов или изменение критических уставок в системе отопления.
Для противодействия этим угрозам применяются два фундаментальных механизма, которые важно различать:
> 📋 Ключевые понятия:
> * Шифрование (Конфиденциальность): Процесс преобразования данных в нечитаемый формат (шифротекст) с помощью ключа. Только тот, у кого есть правильный ключ, может расшифровать данные и прочитать их. Это защищает от атак типа MITM.
> * Аутентификация (Проверка подлинности): Процедура проверки, является ли клиент (или сервер) тем, за кого себя выдает. Это защита от спуфинга. Обычно реализуется через логин/пароль или цифровые сертификаты.
> * Авторизация (Права доступа): Процесс определения, какие действия разрешено выполнять аутентифицированному пользователю. Например, пользователь `sensor_user` может только публиковать данные в топики с телеметрией, но не может управлять реле. Это защищает от несанкционированного управления.
Основой для шифрования и аутентификации в современных сетевых протоколах, включая MQTT и HTTP, является TLS (Transport Layer Security). Это криптографический протокол, который обеспечивает защищенный канал связи между двумя узлами в сети. Он является преемником протокола SSL (Secure Sockets Layer), и сегодня термины TLS и SSL часто используются как синонимы, хотя корректно говорить именно TLS.
---
Защита MQTT с помощью TLS
Как мы рассматривали в предыдущих уроках, стандартный обмен данными по MQTT происходит в открытом виде. Любой, кто имеет доступ к сети, может перехватить и прочитать все ваши сообщения. Чтобы это исправить, MQTT-трафик необходимо "обернуть" в защитный слой TLS.
Принцип работы TLS можно представить как создание зашифрованного "туннеля" между MQTT-клиентом (нашим контроллером HI) и MQTT-брокером. Все сообщения, проходящие внутри этого туннеля, становятся нечитаемыми для посторонних.
Это изменение отражается даже на уровне URI-схемы и стандартных портов:
| Параметр | Незащищенное соединение | Защищенное соединение (TLS) |
| ------------------ | ---------------------------- | ---------------------------- |
| URI схема | `mqtt://` | `mqtts://` |
| Стандартный порт| 1883 | 8883 |
| Шифрование | Нет (открытый текст) | Да (TLS) |
Ключевым элементом для работы TLS являются цифровые сертификаты. Это электронные документы, которые удостоверяют личность участника сети. В нашей экосистеме мы имеем дело с тремя основными типами:
Процесс установления безопасного соединения, известный как TLS Handshake (рукопожатие), выглядит следующим образом (упрощенно):
---
Практика: Настройка TLS-соединения в нодах MQTT
Перейдем к настройке защищенного MQTT-соединения в среде Node-RED на контроллере HI.
> 💡 Подсказка: Рекомендуемое место для хранения сертификатов и ключей на контроллерах HI — директория `/data/secure/`. Этот раздел файловой системы защищен от перезаписи при системных обновлениях и имеет ограниченные права доступа.
Настройка в Node-RED
Процесс состоит из трех шагов: загрузка сертификатов, создание конфигурации TLS и ее применение к брокеру.
Вам понадобятся три файла: сертификат центра сертификации (`ca.crt`), сертификат клиента (`client.crt`) и приватный ключ клиента (`client.key`). Используйте команду `scp` (secure copy) для их загрузки с вашего компьютера на контроллер:
# Загружаем сертификат CA
scp /path/on/my/pc/ca.crt root@:/data/secure/ca.crt
# Загружаем сертификат клиента
scp /path/on/my/pc/client.crt root@:/data/secure/client.crt
# Загружаем приватный ключ клиента
scp /path/on/my/pc/client.key root@:/data/secure/client.key
В интерфейсе Node-RED перейдите в меню `Configuration nodes` (справа вверху) и нажмите `+ add` рядом с `tls-config`. В открывшемся окне укажите полные пути к загруженным файлам:
* Certificate: `/data/secure/client.crt`
* Private Key: `/data/secure/client.key`
* CA Certificate: `/data/secure/ca.crt`
* (Опционально) Server name (SNI): Укажите доменное имя брокера, если это требуется для правильной валидации сертификата.
Откройте настройки вашей ноды `mqtt-broker`.
* На вкладке Connection измените адрес сервера. Протокол должен быть `mqtts://`, а порт `8883` (или другой, если ваш брокер настроен нестандартно). Пример: `mqtts://broker.myhome.local:8883`.
* Перейдите на вкладку Security. В выпадающем списке `TLS` выберите только что созданную конфигурацию TLS.
* Нажмите `Update`, а затем `Deploy`.
Если все настроено правильно, нода `mqtt-in` / `mqtt-out` покажет статус `connected`.
Генерация самоподписанных сертификатов для тестирования
Для лабораторных работ не обязательно покупать сертификаты. Их можно сгенерировать самостоятельно с помощью утилиты `openssl` в терминале Linux.
# 1. Создаем приватный ключ и самоподписанный сертификат для нашего CA
openssl req -x509 -newkey rsa:2048 -keyout ca.key -out ca.crt -days 3650 -nodes -subj "/CN=My Home Automation CA"
# 2. Создаем приватный ключ и запрос на подпись (CSR) для MQTT-брокера
openssl req -newkey rsa:2048 -keyout server.key -out server.csr -nodes -subj "/CN=broker.myhome.local"
# 3. Подписываем запрос брокера нашим CA, получая сертификат сервера
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
# 4. Создаем приватный ключ и запрос на подпись (CSR) для нашего клиента (контроллера HI)
openssl req -newkey rsa:2048 -keyout client.key -out client.csr -nodes -subj "/CN=controller-livingroom"
# 5. Подписываем запрос клиента нашим CA, получая сертификат клиента
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
В результате вы получите все необходимые файлы. На MQTT-брокере (например, Mosquitto) нужно будет указать `ca.crt`, `server.crt` и `server.key`. А на контроллер HI, как описано выше, вы загружаете `ca.crt`, `client.crt` и `client.key`.
---
Аутентификация и авторизация в MQTT
Даже при использовании TLS, который шифрует трафик, брокер может быть настроен на прием анонимных соединений. Любой, у кого есть доступ к сети и CA-сертификат, сможет подключиться. Следующие уровни защиты — это аутентификация и авторизация.
Аутентификация по логину и паролю
Это самый простой и распространенный способ аутентификации. На стороне MQTT-брокера создается список пользователей и их паролей. При подключении клиент должен предоставить эти учетные данные.
В Node-RED это настраивается элементарно:
Это базовый уровень, который отсекает анонимных пользователей.
Авторизация с помощью списков контроля доступа (ACL)
После того как пользователь успешно прошел аутентификацию, вступает в силу механизм авторизации. Он определяет, что именно этот пользователь может делать. Наиболее гибкий инструмент для этого — Access Control Lists (ACL).
ACL — это набор правил, хранящихся на стороне MQTT-брокера, которые описывают права доступа для каждого пользователя к различным шаблонам топиков.
Рассмотрим пример конфигурации для популярного брокера Mosquitto.
Сначала в основном конфигурационном файле (`mosquitto.conf`) нужно включить требование аутентификации и указать путь к файлу с ACL:
# /etc/mosquitto/mosquitto.conf
# Разрешить анонимные подключения - нет
allow_anonymous false
# Указать путь к файлу с паролями
password_file /etc/mosquitto/passwd
# Указать путь к файлу с правилами ACL
acl_file /etc/mosquitto/acl.conf
Теперь самое интересное — содержимое файла `acl.conf`. Здесь мы определяем гранулярные права для разных ролей в нашей системе.
# /etc/mosquitto/acl.conf
# Пользователь "controller-sensors" имеет право только ПУБЛИКОВАТЬ (write)
# данные в топики, начинающиеся с "telemetry/".
# Он не сможет подписаться на какие-либо топики.
user controller-sensors
topic write telemetry/#
# Пользователь "controller-logic" имеет право ПОДПИСЫВАТЬСЯ (read)
# на все топики с телеметрией и ПУБЛИКОВАТЬ (write) команды в топики
# для исполнительных устройств.
user controller-logic
topic read telemetry/#
topic write commands/+/set
# Пользователь "dashboard-user" имеет право только ПОДПИСЫВАТЬСЯ (read)
# на все топики для отображения данных на дашборде.
# Он не сможет отправить ни одной команды.
user dashboard-user
topic read #
# Суперпользователь "admin" имеет полные права на чтение и запись (readwrite)
# во все топики.
user admin
topic readwrite #
Такой подход реализует принцип наименьших привилегий: каждый компонент системы имеет ровно столько прав, сколько ему необходимо для выполнения своих функций, и не более. Это значительно повышает общую безопасность и устойчивость системы.
---
Безопасность HTTP: HTTPS и методы аутентификации API
Принципы обеспечения безопасности для протокола HTTP очень схожи с MQTT.
> 🔗 Связанный материал: Подробная информация о базовой настройке ноды `HTTP Request` и ее параметрах рассмотрена в уроке COURSE-06-M08-L05 "Работа с API: нода HTTP Request".
HTTPS: HTTP over TLS
HTTPS (Hypertext Transfer Protocol Secure) — это тот же HTTP, но работающий поверх защищенного слоя TLS. Весь обмен данными между вашим контроллером (клиентом) и удаленным веб-сервером (API) шифруется.Для настройки работы с HTTPS-ресурсами в ноде `HTTP Request` необходимо:
Для большинства публичных API этого достаточно. Встроенная в контроллер операционная система уже содержит список доверенных глобальных CA, поэтому сертификат популярного веб-сервиса будет проверен автоматически.
Если же вы подключаетесь к внутреннему сервису с самоподписанным сертификатом или сервису, требующему клиентский сертификат (mTLS), вам потребуется создать ноду `tls-config` и выбрать ее в настройках ноды `HTTP Request`, точно так же, как мы делали для MQTT.
Методы аутентификации API
Шифрование — это только полдела. Большинство API требуют аутентификации, чтобы идентифицировать клиента и проверить его права на доступ к данным. В отличие от MQTT, где есть стандартизированные механизмы, в мире HTTP API царит разнообразие. Рассмотрим самые популярные.
1. API-ключ (API Key)
Это секретная строка, уникальная для вашего приложения, которую нужно передавать при каждом запросе.
Есть два распространенных способа передачи:
- В параметрах URL (менее безопасно): `https://api.weather.com/v1/forecast?q=Moscow&apikey=SECRET12345`
- В HTTP-заголовках (предпочтительный способ): Этот метод безопаснее, так как заголовки обычно не логируются в промежуточных серверах так же активно, как URL.
Чтобы добавить заголовок в ноде `HTTP Request`, в разделе "Headers" нужно добавить новое свойство. Имя заголовка обычно указывается в документации к API (например, `X-Api-Key` или `x-access-token`).
2. Токен носителя (Bearer Token)
Это современный стандарт, часто используемый в связке с протоколом OAuth2 или JWT (JSON Web Tokens). Сервер выдает клиенту временный токен, который клиент должен прикреплять к каждому последующему запросу.
Токен передается в стандартном заголовке `Authorization` со значением, которое начинается с префикса `Bearer `.
Пример: `Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWI...`Часто токен нужно получать динамически (например, раз в час). Это легко реализуется в Node-RED: один поток получает/обновляет токен и сохраняет его в переменную контекста, а другой поток перед отправкой HTTP-запроса считывает этот токен и добавляет его в заголовки.
Вот пример ноды `Function` перед нодой `HTTP Request` для динамической установки заголовка:
// Получаем токен, сохраненный ранее в контексте потока
const apiToken = flow.get("api_bearer_token");
// Если токена нет, останавливаемся
if (!apiToken) {
node.error("API Bearer Token is missing!");
return null;
}
// Формируем объект заголовков и добавляем его в сообщение
msg.headers = {
'Authorization': 'Bearer ' + apiToken,
'Content-Type': 'application/json'
};
return msg;
Этот код считывает токен, формирует правильный заголовок и передает его дальше ноде `HTTP Request`, которая автоматически использует его при отправке запроса.
Что дальше
В этом уроке мы рассмотрели фундаментальные аспекты безопасности протоколов MQTT и HTTP, научились настраивать шифрование с помощью TLS и применять различные методы аутентификации и авторизации. Теперь ваши потоки могут безопасно взаимодействовать как с локальными, так и с облачными сервисами. В следующих модулях мы перейдем к изучению более сложных сценариев автоматизации и интеграции с другим промышленным оборудованием.