ГлавнаяАкадемияNode-RED: установка, flows, msg/JSON, отладка → Безопасность MQTT и HTTP: TLS, аутентификация

Безопасность MQTT и HTTP: TLS, аутентификация

Урок 6 · Node-RED: установка, flows, msg/JSON, отладка · 30 мин · theory

Введение в безопасность MQTT и HTTP

В современной системе автоматизации, подключенной к сети, вопросы безопасности выходят на первый план. Развертывание контроллеров и IoT-устройств без обеспечения базовых мер защиты — это прямой путь к созданию уязвимостей, которые могут привести к серьезным последствиям: от нарушения работы систем жизнеобеспечения объекта до компрометации всей локальной сети.

> ⚠️ Внимание: Развертывание IoT-устройств без базовых мер безопасности создает серьезные риски не только для объекта, но и для всей сетевой инфраструктуры. Незащищенный контроллер может стать точкой входа для атак на другие устройства в вашей сети.

Для инженера автоматизации важно понимать основные векторы атак, чтобы грамотно им противодействовать:

Для противодействия этим угрозам применяются два фундаментальных механизма, которые важно различать:

> 📋 Ключевые понятия:

> * Шифрование (Конфиденциальность): Процесс преобразования данных в нечитаемый формат (шифротекст) с помощью ключа. Только тот, у кого есть правильный ключ, может расшифровать данные и прочитать их. Это защищает от атак типа 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 являются цифровые сертификаты. Это электронные документы, которые удостоверяют личность участника сети. В нашей экосистеме мы имеем дело с тремя основными типами:

  • Центр Сертификации (Certificate Authority, CA): Это корень доверия. CA — это организация (или в нашем случае, сгенерированный нами главный сертификат), которая подписывает сертификаты серверов и клиентов, тем самым ручаясь за их подлинность. Клиент должен доверять CA, чтобы принять сертификат, подписанный этим CA.
  • Сертификат Сервера: Этот сертификат используется MQTT-брокером, чтобы доказать клиенту свою подлинность. Он говорит: "Я действительно сервер `broker.myhome.local`, и вот моя подпись от доверенного CA". Это основная защита от MITM-атак.
  • Сертификат Клиента (опционально): Этот сертификат используется клиентом (нашим контроллером), чтобы доказать брокеру свою подлинность. Это называется взаимной аутентификацией (mutual TLS, mTLS). Брокер может быть настроен так, чтобы принимать соединения только от клиентов с доверенными сертификатами.
  • Процесс установления безопасного соединения, известный как TLS Handshake (рукопожатие), выглядит следующим образом (упрощенно):

  • Client Hello: Клиент (контроллер) отправляет брокеру сообщение: "Привет, я хочу установить защищенное соединение по TLS. Вот список шифров, которые я поддерживаю".
  • Server Hello & Certificate: Брокер отвечает: "Привет, я тоже. Давай использовать вот этот шифр". Затем он отправляет свой публичный сертификат сервера, подписанный CA.
  • Проверка Клиентом: Клиент получает сертификат сервера и проверяет его подпись с помощью имеющегося у него сертификата CA. Если подпись верна, клиент доверяет серверу.
  • (Опционально) Client Certificate: Если брокер требует аутентификацию клиента, клиент отправляет свой сертификат.
  • (Опционально) Проверка Сервером: Брокер проверяет сертификат клиента по своему списку доверенных CA.
  • Key Exchange: После успешной проверки подлинности обе стороны генерируют сессионный ключ шифрования, который будет использоваться для кодирования всех дальнейших сообщений.
  • Защищенный канал установлен: Весь последующий MQTT-трафик (команды, телеметрия) шифруется этим сессионным ключом.
  • ---

    Практика: Настройка 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

  • Создание `tls-config` ноды:
  • В интерфейсе 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-брокеру:
  • Откройте настройки вашей ноды `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 это настраивается элементарно:

  • Откройте конфигурацию ноды `mqtt-broker`.
  • Перейдите на вкладку Security.
  • Заполните поля Username и Password.
  • Это базовый уровень, который отсекает анонимных пользователей.

    Авторизация с помощью списков контроля доступа (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` необходимо:

  • Указать URL, начинающийся с `https://`.
  • Убедиться, что установлена галочка "Enable secure (SSL/TLS) connection".
  • Для большинства публичных API этого достаточно. Встроенная в контроллер операционная система уже содержит список доверенных глобальных CA, поэтому сертификат популярного веб-сервиса будет проверен автоматически.

    Если же вы подключаетесь к внутреннему сервису с самоподписанным сертификатом или сервису, требующему клиентский сертификат (mTLS), вам потребуется создать ноду `tls-config` и выбрать ее в настройках ноды `HTTP Request`, точно так же, как мы делали для MQTT.

    Методы аутентификации API

    Шифрование — это только полдела. Большинство API требуют аутентификации, чтобы идентифицировать клиента и проверить его права на доступ к данным. В отличие от MQTT, где есть стандартизированные механизмы, в мире HTTP API царит разнообразие. Рассмотрим самые популярные.

    1. API-ключ (API Key)

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

    Есть два распространенных способа передачи:

    Чтобы добавить заголовок в ноде `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 и применять различные методы аутентификации и авторизации. Теперь ваши потоки могут безопасно взаимодействовать как с локальными, так и с облачными сервисами. В следующих модулях мы перейдем к изучению более сложных сценариев автоматизации и интеграции с другим промышленным оборудованием.