Segurança MQTT

Provisionamento Seguro de Dispositivos IoT para Frotas MQTT

Como colocar uma identidade MQTT única e protegida em cada dispositivo: provisionamento na fábrica, fluxos com claim certificate e bootstrap, credenciais por dispositivo e os passos para conectar dispositivos provisionados a um broker MQTT gerenciado.

Diagrama de fluxo do provisionamento seguro de dispositivos IoT, da linha de produção ao serviço de bootstrap e ao broker MQTT
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

O provisionamento seguro de dispositivos IoT é o processo de dar a cada dispositivo uma identidade única e as credenciais necessárias para chegar ao seu broker MQTT, sem que esses segredos vazem pelo caminho. Este guia compara os principais modelos de provisionamento, percorre um fluxo de bootstrap prático e mostra como dispositivos provisionados se conectam a um broker ConnectMQ com credenciais por dispositivo.

O que o provisionamento precisa garantir

Seja qual for o modelo escolhido, um bom processo de provisionamento entrega cinco propriedades:

  1. Unicidade. Cada dispositivo recebe a própria credencial. Dois dispositivos nunca compartilham um segredo.
  2. Confidencialidade. O segredo nunca fica visível em texto claro para pessoas ou sistemas que não precisam dele, incluindo logs e artefatos de build.
  3. Rastreabilidade. Você consegue associar cada credencial a um número de série, um lote e um cliente.
  4. Revogabilidade. Você consegue desativar um dispositivo sem mexer nos outros.
  5. Recuperabilidade. Você consegue reprovisionar um dispositivo após um reparo ou um reset de fábrica.

Uma senha compartilhada compilada no firmware falha em pelo menos três desses pontos. É o motivo mais comum para uma única unidade comprometida virar um incidente em toda a frota.

Comparação dos modelos de provisionamento

Modelo Como a credencial chega ao dispositivo Indicado para Principal risco
Injeção na fábrica A estação de gravação escreve uma credencial única durante a fabricação Linhas de produção controladas Segredos nos sistemas da fábrica
Claim certificate ou segredo de bootstrap O dispositivo sai com uma identidade de bootstrap compartilhada ou por lote e a troca por uma credencial única no primeiro boot Frotas grandes, fabricação terceirizada Abuso do segredo de bootstrap se não for limitado
Onboarding assistido pelo usuário Um app no celular ou uma página web local entrega as credenciais durante a configuração Produtos de consumo Phishing, canal local inseguro
Digitação manual O instalador digita as credenciais em uma página de configuração Pilotos pequenos Erro humano, reutilização de credenciais

Provisionamento na fábrica

Durante a fabricação, uma estação de gravação gera ou obtém uma credencial única e a grava no armazenamento protegido do dispositivo, normalmente junto com o número de série. Em microcontroladores, isso costuma ser uma partição NVS criptografada ou um secure element; em dispositivos Linux, um arquivo criptografado ou um armazenamento protegido por TPM. A estação registra o mapeamento no seu sistema de inventário, nunca o segredo em texto claro.

Pontos fortes: os dispositivos saem da fábrica prontos para se conectar. Pontos fracos: a rede da fábrica passa a lidar com segredos, então precisa de controle de acesso e trilha de auditoria próprios, e você precisa confiar no fabricante.

Claim certificates e fluxos de bootstrap

Um claim certificate é uma identidade limitada compartilhada por um lote de dispositivos. Sua única permissão é chamar um serviço de provisionamento e solicitar uma identidade única de longo prazo. Várias plataformas IoT implementam esse padrão, e você pode construir a mesma ideia com qualquer broker:

  1. O dispositivo inicia com um segredo de bootstrap ou claim certificate e o seu número de série de hardware.
  2. Ele chama o seu serviço de provisionamento via HTTPS, provando que possui o segredo de bootstrap.
  3. O serviço verifica o número de série contra a allowlist de fabricação e confirma que ele ainda não foi reivindicado.
  4. O serviço retorna uma credencial MQTT única para aquele dispositivo e marca o número de série como reivindicado.
  5. O dispositivo guarda a credencial em armazenamento protegido e descarta o segredo de bootstrap, ou o mantém apenas para reprovisionamento.

Como a identidade de claim não pode publicar nem se inscrever em nada, uma cópia vazada permite ao atacante, no máximo, reivindicar números de série ainda não reivindicados, e a allowlist com reivindicação única limita até isso.

Onboarding assistido pelo usuário

Dispositivos de consumo costumam ser provisionados pelo dono por meio de um app que se conecta ao dispositivo via BLE ou por um ponto de acesso Wi-Fi temporário. Criptografe esse canal local, exija prova de presença física, como apertar um botão, e faça o app buscar a credencial do dispositivo no seu backend em vez de embutir qualquer coisa no app.

Um fluxo de bootstrap prático para um broker MQTT

Se o seu broker emite as credenciais, como normalmente faz um broker MQTT gerenciado, o seu serviço de provisionamento vira o custodiante que distribui credenciais um dispositivo por vez. Com o ConnectMQ, você emite as credenciais no portal; cada conjunto inclui usuário, senha e um client ID vinculado a essas credenciais. Um design simples e robusto:

  • Emita os conjuntos de credenciais no portal antes de um lote de produção.
  • Carregue-os no armazenamento criptografado do seu serviço de provisionamento, um por número de série esperado.
  • Deixe os dispositivos reivindicá-los usando o fluxo de bootstrap acima.

Um endpoint de provisionamento mínimo, escrito em Python com Flask para ilustração:

# pip install flask
import hmac
import hashlib
import json
from flask import Flask, request, jsonify, abort

app = Flask(__name__)
BOOTSTRAP_KEY = b"load-from-a-secret-manager-not-source"

# serial -> {"claimed": bool, "cred": {...}}  (use um banco de dados real em produção)
INVENTORY = json.load(open("batch-2026-10.json"))

def valid_proof(serial: str, nonce: str, proof: str) -> bool:
    expected = hmac.new(BOOTSTRAP_KEY, f"{serial}:{nonce}".encode(),
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, proof)

@app.post("/provision")
def provision():
    body = request.get_json(force=True)
    serial, nonce, proof = body.get("serial"), body.get("nonce"), body.get("proof")
    if not (serial and nonce and proof) or not valid_proof(serial, nonce, proof):
        abort(401)
    entry = INVENTORY.get(serial)
    if entry is None or entry["claimed"]:
        abort(403)
    entry["claimed"] = True        # em produção, persista isto antes de responder
    return jsonify(entry["cred"])  # {"username": ..., "password": ..., "client_id": ...}

if __name__ == "__main__":
    # Sirva atrás de HTTPS (proxy reverso com certificado válido)
    app.run(host="127.0.0.1", port=8080)

Em produção, armazene os nonces para impedir replay, limite a taxa de requisições do endpoint, persista o flag de reivindicação de forma atômica e gere alertas para reivindicações repetidas do mesmo número de série.

Conectando um dispositivo provisionado

Depois que o dispositivo tem a sua credencial, a conexão é uma autenticação MQTT com usuário e senha comum sobre TLS. Um exemplo para ESP32 com PubSubClient que lê a credencial da NVS:

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Preferences.h>

extern const char ROOT_CA[];   // PEM da ISRG Root X1, compilado no firmware

WiFiClientSecure net;
PubSubClient mqtt(net);
Preferences prefs;
String user, pass, clientId;

void setup() {
  Serial.begin(115200);
  prefs.begin("mqtt", true);                 // namespace somente leitura
  user = prefs.getString("user", "");
  pass = prefs.getString("pass", "");
  clientId = prefs.getString("cid", "");
  prefs.end();
  if (user.isEmpty()) { Serial.println("Not provisioned"); return; }

  WiFi.begin("YOUR_SSID", "YOUR_WIFI_PASSWORD");
  while (WiFi.status() != WL_CONNECTED) delay(500);

  net.setCACert(ROOT_CA);
  mqtt.setServer("YOUR_BROKER_HOST", 8883);
}

void loop() {
  if (user.isEmpty()) { delay(1000); return; }   // aguarda o provisionamento
  if (!mqtt.connected()) {
    if (mqtt.connect(clientId.c_str(), user.c_str(), pass.c_str())) {
      mqtt.publish(("devices/" + clientId + "/status").c_str(), "online", true);
    } else {
      Serial.printf("MQTT connect failed, state=%d\n", mqtt.state());
      delay(10000);                          // espera antes de tentar, não martele o broker
    }
  }
  mqtt.loop();
}

Ative a criptografia de flash e a criptografia da NVS para que a credencial armazenada não possa ser lida de um chip de flash copiado. Os detalhes estão em proteger credenciais MQTT em dispositivos.

Reprovisionamento, reparos e descomissionamento

O provisionamento não é um evento único. Dispositivos voltam para reparo, recebem reset de fábrica dos clientes, mudam de dono e chegam ao fim da vida útil. Planeje cada um desses caminhos antes de o primeiro lote ser enviado:

  • Reset de fábrica. Decida se um reset apaga a credencial MQTT. Se apagar, o dispositivo precisa de um caminho de volta ao fluxo de bootstrap, o que significa que o seu serviço de provisionamento deve permitir uma nova reivindicação controlada, por exemplo depois que um chamado de suporte marcar o número de série como redefinível.
  • Reparos e troca de placas. Quando a placa principal é substituída, a credencial antiga vai embora com a placa antiga. Revogue-a, emita um novo conjunto e atualize o inventário para que o número de série aponte para o novo client ID.
  • Mudança de dono. Para dispositivos vendidos ou transferidos entre clientes, emita credenciais novas em um broker do novo dono, em vez de transferir as antigas.
  • Descomissionamento. Revogue a credencial no portal no dia em que o dispositivo sair de serviço e registre a data. Credenciais abandonadas que ainda funcionam são uma fonte comum de conexões inesperadas meses depois.

Cada um desses caminhos reutiliza os mesmos blocos do provisionamento inicial e da rotação de credenciais: emitir, entregar, verificar, revogar.

Checklist de provisionamento

  1. Credencial única por dispositivo, nunca uma senha para a frota inteira.
  2. Segredos gerados ou emitidos de forma centralizada, não inventados por engenheiros de firmware.
  3. Identidade de bootstrap limitada ao provisionamento, com reivindicação única e allowlist.
  4. Credenciais guardadas em armazenamento criptografado ou em um secure element.
  5. TLS com verificação de certificado em toda conexão, inclusive na chamada de provisionamento.
  6. Inventário que associa o número de série ao client ID, sem segredos em texto claro.
  7. Um caminho testado de reprovisionamento e de rotação de credenciais.
  8. Backoff em falhas de autenticação; o ConnectMQ bloqueia IPs após repetidas falhas de login.

Planejando capacidade e ambientes

O provisionamento interage com os limites do plano. O plano Serverless (Free) permite até 25 conexões, o que serve para um piloto; o Serverless (Paid) vai até 1.000 conexões, e os planos Dedicated ou BYOC atendem frotas maiores ou reguladas. Mantenha brokers separados para desenvolvimento, homologação e produção, para que dispositivos de teste nunca tenham credenciais de produção, e use o servidor MQTT público apenas para experimentos sem dados sensíveis.

Comece a usar o ConnectMQ

Provisione seus primeiros dispositivos em um broker MQTT na nuvem com TLS, isolamento de tenants e client IDs vinculados às credenciais emitidas. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito.

Perguntas frequentes

O que é provisionamento seguro de dispositivos IoT?

É o processo de dar a cada dispositivo uma identidade e credenciais únicas, entregá-las sem exposição e registrá-las para que possam ser rastreadas e revogadas depois.

O que é um claim certificate?

Um claim certificate é uma identidade limitada, muitas vezes compartilhada por lote, cuja única permissão é solicitar uma credencial única de dispositivo a um serviço de provisionamento no primeiro boot.

Devo embutir credenciais MQTT nas imagens de firmware?

Não. Uma imagem de firmware é copiada muitas vezes e costuma ser fácil de extrair. Em vez disso, grave credenciais únicas no armazenamento protegido de cada dispositivo.

O ConnectMQ oferece um serviço de provisionamento de dispositivos?

Não. Você emite as credenciais no portal do ConnectMQ e as entrega com o seu próprio processo de fábrica ou de bootstrap, como mostrado acima.

Artigos relacionados

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.