Управление ESP8266 без проброса портов: исходящий путь через MQTT
Брокер, доступный из интернета, позволяет управлять домашним устройством через соединение, которое оно само открыло. Что это меняет для памяти TLS, тем и повторной доставки.
Устройство стоит за домашним роутером без проброса портов и без публичного адреса, и всё же должно получать конфигурацию за секунды. Трюк не в дыре в межсетевом экране. Это соединение, которое устройство открывает наружу к брокеру, до которого может дотянуться, а тот затем возвращает сообщения по тому же установленному пути. Каждое свойство, которое нравится людям в этом дизайне, и каждая ловушка в нём происходят из этого переворота.
Что на самом деле проходит через NAT
Когда устройство открывает TCP-соединение к брокеру, домашний роутер создаёт отображение и держит его живым всё время существования потока. Ответы в этом потоке возвращаются к устройству, потому что отображение уже существует. Брокер никогда не инициирует ничего в сторону дома, поэтому нет нежелательного входящего пакета, который роутер должен был бы отклонить. В этом вся сетевая аргументация, и поэтому подход работает в сетях, которые вы не контролируете.
Устройство должно поддерживать соединение живым или восстанавливать его, и это становится вопросом надёжности, как только архитектура определена.
Брокер маршрутизирует темы, а не проксирует HTTP
MQTT определяет обмены публикации и подписки: устройство подписывается на фильтр тем, который ему разрешено читать, а уполномоченный контроллер публикует в подходящую тему. Брокер сопоставляет публикации с подписками и доставляет копии. Он не знает, что такое запрос браузера, и не будет пересылать HTTP GET на веб-сервер устройства. Если существующая прошивка говорит только на HTTP, дизайну с брокером нужно изменение приложения или намеренный компонент перевода.
Имена тем тоже не авторизация. Большинство брокеров поддерживают списки контроля доступа для каждого клиента, и устройства следует ограничивать их собственными деревьями публикации и подписки, а не делить одно глобальное пространство имён.
Ресурсы устройства определяют форму TLS
У ESP8266 ограниченная RAM, и рукопожатие TLS — самое дорогое, что он делает. Ядро Arduino поставляет BearSSL именно из-за этого ограничения, и выбор между проверкой CA и закреплением отпечатка меняет и объём памяти, и то, что может сделать злоумышленник с действительным сертификатом на другое имя. Проверка CA брокера — более сильный вариант, когда куча позволяет. Размер полезной нагрузки тоже важен: клиент MQTT держит буфер, и сообщения больше него молча обрезаются, если буфер не увеличен намеренно.
Keepalive и тайм-ауты сокета — часть того же бюджета, потому что клиент, который никогда не замечает мёртвое соединение, перестаёт получать команды, не сообщая об ошибке.
Семантика сообщений, которая кусается
Сохранённое сообщение хранится брокером и доставляется более поздним подходящим подписчикам, что отлично для текущего состояния и опасно для одноразовых команд: устройство, подключившееся заново, может получить вчерашнюю команду как новую. QoS 1 гарантирует доставку хотя бы один раз, поэтому дубликаты нормальны, и приложение должно быть устойчиво к повторению, в идеале с идентификатором или меткой времени, которую оно может отклонить. Последняя воля даёт сигнал состояния, когда устройство падает, но только если соединение действительно отказывает, а не зависает.
Поведение чистой сессии решает, сохраняет ли брокер ваши подписки, пока вас нет, и ошибка здесь — причина, по которой некоторые устройства теряют первое сообщение после каждого переподключения.
TLS защищает участок до брокера. Это не сквозное шифрование полезной нагрузки от оператора брокера, который может читать всё, что вы публикуете через него.
Ограничьте жизненный цикл и проверьте его безвредными данными
Планируйте переподключение с отступлением, а не плотным циклом повторов, подписывайтесь заново явно, если сессия не постоянная, и записывайте результат соединения, чтобы молчаливое офлайн-устройство оставляло следы. Проверьте путь переподключения на образцах полезной нагрузки, которые ничего не делают, потому что первый производственный тест канала команд не должен быть настоящей командой. Затем подтвердите, что делает устаревшее сохранённое сообщение при переподключении, и решите, приемлемо ли такое поведение для каждой темы.
Сделанный так, дизайн убирает одно входящее сетевое требование и оставляет программное обеспечение устройства, политику брокера и семантику сообщений видимой работой, а не скрытыми допущениями.