1. Тема дня
Сегодня разбираем защищённую связь устройства с сервером:
TCP
→ TLS handshake
→ проверка сертификата сервера
→ optional client certificate
→ зашифрованный MQTT/HTTPSГлавная мысль: TLS защищает соединение только тогда, когда устройство проверяет не просто наличие шифрования, а подлинность сервера, hostname и срок действия сертификата.
2. Зачем это нужно в твоих проектах
Через LTE передаются phase events, fault snapshots, настройки, OTA manifest и команды управления. Без корректной проверки TLS устройство может подключиться к поддельному broker и принять вредную команду. Для OTA ошибка в CA/hostname может открыть путь к подмене образа или лишить весь парк возможности обновляться. Для STM32 с Ethernet/Wi-Fi/PPP архитектура аналогична:
LwIP / NetX Duo
→ Mbed TLS
→ CA store
→ optional mTLS
→ MQTT/HTTPS3. Теория
7.3.1 3.1. Что TLS защищает
Конфиденциальность:
посторонний не читает payload.
Целостность:
пакет нельзя незаметно изменить.
Аутентификация:
клиент проверяет, что сервер настоящий.При mTLS сервер дополнительно проверяет сертификат устройства.
7.3.2 3.2. Обычный TLS и mTLS
Обычный TLS:
ESP32 → ClientHello + SNI → Broker
ESP32 ← server certificate chain ← Broker
ESP32 проверяет CA, hostname, timemTLS:
устройство проверяет server certificate
сервер проверяет client certificate устройства7.3.3 3.3. Certificate chain
Root CA
└── Intermediate CA
└── mqtt.example.comУстройство обычно хранит Root CA или ограниченный набор CA, а не leaf-сертификат broker.
7.3.4 3.4. CA bundle или свой CA
CA bundle удобен для публичных endpoints, но доверяет большому набору CA и занимает Flash. Собственный CA сужает trust boundary, но требует защищённого CA private key, процедуры выпуска, ротации и отзыва.
7.3.5 3.5. Hostname verification и SNI
CA verification отвечает:
сертификат подписан доверенным CA?Hostname verification отвечает:
сертификат выпущен именно для mqtt.example.com?Отключать hostname verification в production нельзя.
7.3.6 3.6. TLS зависит от времени
X.509-сертификаты имеют Not Before и Not After. Поэтому устройство должно иметь достаточно правдоподобный UTC. Bootstrap strategy:
1. Загрузить last-known-good UTC из RTC/NVS.
2. Не уменьшать его ниже последнего подтверждённого значения.
3. Использовать время сети EC25 только как подсказку.
4. Проверить разумный год/диапазон.
5. Установить TLS.
6. Получить более надёжную синхронизацию.
7. Обновить last-known-good time.7.3.7 3.7. Где завершать TLS: ESP32 или EC25
TLS на ESP32 через PPPoS:
EC25 → PPP → lwIP → ESP-TLS/Mbed TLS → MQTT/HTTPSПлюсы: единый TLS-стек, лучшая диагностика, единый CA store, меньше зависимость от AT- прошивки. Минусы: расход RAM/CPU ESP32, нагрузка на UART PPP. TLS внутри EC25:
ESP32 → AT commands → EC25 TLS/MQTT stack → brokerПлюсы: TLS считает модем, меньше heap ESP32. Минусы: сложнее сертификаты, диагностика, ротация, зависимость от firmware модема.
7.3.8 3.8. Жизненный цикл сертификатов
typedef enum {
CERT_STATE_EMPTY = 0,
CERT_STATE_STAGED,
CERT_STATE_ACTIVE,
CERT_STATE_RENEWAL_REQUIRED,
CERT_STATE_REVOKED,
CERT_STATE_EXPIRED,
} certificate_state_t;
typedef struct {
uint32_t generation;
certificate_state_t state;
int64_t not_before_utc;
int64_t not_after_utc;
uint8_t fingerprint_sha256[32];
uint32_t connect_success_count;
uint32_t connect_fail_count;
} certificate_status_t;7.3.9 3.9. Ротация CA
Безопасно:
CA_OLD
→ firmware доверяет CA_OLD + CA_NEW
→ сервер переходит на CA_NEW
→ парк подтверждает подключение
→ удалить CA_OLD позжеОпасно:
сервер перешёл на CA_NEW
→ старые устройства знают только CA_OLD
→ парк offline7.3.10 3.10. Диагностика TLS
typedef enum {
TLS_STAGE_NONE = 0,
TLS_STAGE_DNS,
TLS_STAGE_TCP_CONNECT,
TLS_STAGE_CLIENT_HELLO,
TLS_STAGE_CERT_VERIFY,
TLS_STAGE_CLIENT_AUTH,
TLS_STAGE_ESTABLISHED,
} tls_stage_t;
typedef struct {
tls_stage_t last_stage;
int32_t last_tls_error;
int32_t last_verify_flags;
uint32_t handshake_ok;
uint32_t handshake_failed;
uint32_t hostname_failed;
uint32_t time_failed;
uint32_t client_auth_failed;
uint32_t max_handshake_ms;
uint32_t min_free_heap_during_handshake;
uint32_t certificate_generation;
} tls_diag_t;4. Типичные ошибки
1. Отключить server verification.
2. Проверять CA, но отключить hostname.
3. Один client certificate на весь парк.
4. Не иметь времени до TLS.
5. Шить leaf certificate сервера навсегда.
6. Переключить CA на сервере раньше OTA устройств.
7. Хранить private key в Git.
8. Печатать PEM/DER в debug log.
9. Не учитывать lifetime буферов сертификатов.
10. Перепутать TLS termination: ESP32 и EC25 одновременно.
11. Не измерять peak heap TLS handshake.5. Практическое задание на 30-60 минут
Создай TLS_PKI_POLICY.md:
# TLS / PKI policy
1. All external MQTT and OTA connections use TLS.
2. Server certificate and hostname are always verified.
3. Insecure verification is forbidden in production.
4. Each device has a unique identity.
5. Private keys are never stored in Git or logs.
6. UTC quality is checked before certificate validation.
7. CA rotation uses an old+new overlap window.
8. Client certificate rotation is transactional.
9. TLS errors are classified, not retried blindly.
10. Certificate expiry is monitored before deployment.Сделай inventory endpoints:
| Endpoint | Protocol | Authentication | Trust source |
|---|---|---|---|
| mqtt.example.com | MQTT/TLS | mTLS | private CA |
| ota.example.com | HTTPS | server TLS | CA bundle |
| api.example.com | HTTPS | token + TLS | CA bundle |Добавь CLI tls probe, который проверяет DNS/TCP/TLS/hostname/time/heap и не передаёт application secrets.
6. Что почитать дальше
- ESP-TLS, X.509 Certificate Bundle, ESP-MQTT TLS examples.
- Quectel EC25 SSL/MQTT/HTTP(S) application notes.
- STM32 Mbed TLS integration и STSAFE.
Короткий итог
external endpoint
→ DNS
→ TCP
→ TLS handshake
→ CA chain verification
→ hostname/SNI verification
→ optional client certificate
→ encrypted MQTT/HTTPS
→ monitored certificate lifecycleЗадание
Server certificate подписан trusted CA, но выдан другому hostname. Задайте connection decision и безопасные diagnostic information.
Критерии самопроверки: Сохранить hostname verification и отличать authentication failure от TCP или DNS failure.
Показать ответ автора
Отклонить connection: CA trust не подтверждает нужный hostname. Записать ограниченную verification category, endpoint identity, time quality и handshake status без private keys, PEM/DER material и application secrets.
Задание
Спланируйте переход CA_OLD к CA_NEW для устройств, которые могут быть offline при deployment. Задайте порядок сохранения authenticated update path.
Критерии самопроверки: Описать evidence каждого этапа и offline-device recovery path; не решать rotation отключением verification.
Показать ответ автора
Сначала развернуть firmware с доверием к CA_OLD и CA_NEW и проверить adoption устройств. Затем переключить server на CA_NEW и наблюдать connections; удалить CA_OLD позже по контролируемой policy с учётом устройств, пропустивших переход.