Segurança MQTT

Como Fazer a Rotação de Credenciais MQTT sem Tempo de Inatividade

Uma estratégia passo a passo de credenciais duplas para rotacionar usuários e senhas MQTT em uma frota: prepare a nova credencial, faça a troca com fallback, verifique e só então revogue a antiga.

Linha do tempo ilustrando a rotação de credenciais MQTT com as credenciais antiga e nova se sobrepondo antes da revogação
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

Para fazer a rotação de credenciais MQTT sem tempo de inatividade, você precisa de dois conjuntos de credenciais válidos ao mesmo tempo, de dispositivos capazes de voltar da credencial nova para a antiga e de uma etapa de verificação antes de revogar qualquer coisa. Este guia apresenta essa estratégia de credenciais duplas passo a passo, incluindo código do lado do dispositivo e a ordem das operações para emitir e revogar credenciais em um broker MQTT gerenciado.

Por que rotacionar credenciais MQTT?

Credenciais estáticas têm vida longa nos dispositivos. Ao longo dos anos elas passam por pipelines de build, notebooks de suporte, hardware devolvido e trocas de terceirizados. A rotação limita por quanto tempo qualquer cópia vazada continua útil. Você também precisa de um processo de rotação testado para eventos não planejados:

  • Um dispositivo é roubado, devolvido ou descomissionado.
  • Uma imagem de firmware com segredos embutidos foi publicada por engano.
  • Um funcionário ou integrador com acesso às credenciais sai da empresa.
  • Uma revisão de segurança ou um contrato com cliente exige rotação periódica.

O pior momento para desenhar um processo de rotação é durante um incidente. Executá-lo periodicamente mantém o processo funcionando.

Por que a rotação ingênua causa interrupções

A abordagem tentadora é: trocar a senha no broker e depois enviar a nova para os dispositivos. Todo dispositivo que ainda não recebeu a atualização fica bloqueado, e um dispositivo bloqueado no MQTT muitas vezes também não consegue receber a atualização, porque o canal de atualização é o próprio MQTT. Você acaba com uma visita de campo para cada dispositivo offline.

A ordem inversa também falha: se os dispositivos trocam primeiro e o broker ainda não conhece a nova credencial, eles não conseguem se conectar. A única abordagem segura é uma janela de sobreposição em que as duas credenciais funcionam.

A estratégia de rotação com credenciais duplas

Fase Estado do broker Estado do dispositivo Condição de saída
1. Emitir Antiga e nova válidas Só a antiga Nova credencial criada e registrada
2. Preparar Antiga e nova válidas Antiga ativa, nova armazenada Dispositivo confirma que armazenou a nova credencial
3. Trocar Antiga e nova válidas Nova ativa, antiga como fallback Dispositivo conectado com a nova credencial
4. Verificar Antiga e nova válidas Nova ativa Nenhuma conexão com a credencial antiga por um período definido
5. Revogar Só a nova Só a nova, antiga apagada Credencial antiga removida de todos os lugares

As fases valem para qualquer broker. O que muda é como as credenciais são emitidas e revogadas.

Fase 1: emitir a nova credencial

Em um broker Mosquitto auto-hospedado, isso significa adicionar um segundo usuário ao arquivo de senhas. No ConnectMQ, emita um novo conjunto de credenciais para o dispositivo no portal. Cada conjunto vem com usuário, senha e client ID próprios, porque os client IDs são vinculados às credenciais emitidas. Registre no seu inventário o mapeamento entre o dispositivo físico e os client IDs antigo e novo antes de seguir em frente.

Esse vínculo tem uma consequência prática: durante a rotação, o dispositivo não troca só a senha, ele troca todo o trio de identidade. Garanta que qualquer consumidor que use o client ID como chave, como o monitoramento de presença em $SYS/broker/connection/{clientId}/state ou o seu próprio inventário, conheça os dois IDs durante a sobreposição.

Fase 2: preparar no dispositivo

Entregue a nova credencial pela conexão existente, autenticada e protegida por TLS. Um padrão típico é um topic de comandos que só aquele dispositivo escuta:

devices/<deviceId>/cmd/credentials    # backend -> dispositivo, QoS 1, não retido
devices/<deviceId>/evt/credentials    # dispositivo -> backend, confirmação

Nunca publique credenciais como retained messages, nem em um topic compartilhado ou legível por curingas. Se o seu broker não aplica permissões por topic, mantenha clientes não confiáveis totalmente fora dele ou entregue as credenciais por um canal separado, como o seu serviço de atualização OTA. O dispositivo grava a nova credencial em armazenamento protegido, em um slot separado do atual, e confirma com um hash, não com a própria senha.

Fase 3: trocar com fallback

O dispositivo se reconecta com a nova credencial. Se o broker a rejeitar, o dispositivo volta para a antiga e informa a falha. É essa etapa que torna a rotação segura.

import json
import os
import ssl
import time
import paho.mqtt.client as mqtt

HOST = "YOUR_BROKER_HOST"
STORE = "/var/lib/mydevice/credentials.json"   # proteja com permissões 0600

def load():
    with open(STORE) as f:
        return json.load(f)   # {"active": {...}, "pending": {...} or null}

def save(data):
    tmp = STORE + ".tmp"
    with open(tmp, "w") as f:
        json.dump(data, f)
    os.replace(tmp, STORE)    # troca atômica, sobrevive a queda de energia durante a gravação

def try_connect(cred, timeout=15):
    result = {}
    def on_connect(client, userdata, flags, reason_code, properties):
        result["rc"] = reason_code
    c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                    client_id=cred["client_id"], protocol=mqtt.MQTTv5)
    c.username_pw_set(cred["username"], cred["password"])
    c.tls_set(cert_reqs=ssl.CERT_REQUIRED)
    c.on_connect = on_connect
    c.connect(HOST, 8883, keepalive=60)
    c.loop_start()
    deadline = time.time() + timeout
    while "rc" not in result and time.time() < deadline:
        time.sleep(0.2)
    if result.get("rc") is not None and not result["rc"].is_failure:
        return c
    c.loop_stop()
    c.disconnect()
    return None

def connect_with_rotation():
    data = load()
    if data.get("pending"):
        client = try_connect(data["pending"])
        if client:
            data["previous"] = data["active"]   # mantém como fallback até a revogação
            data["active"], data["pending"] = data["pending"], None
            save(data)
            return client
        print("New credential rejected, falling back")
    client = try_connect(data["active"])
    if client is None and data.get("previous"):
        client = try_connect(data["previous"])
    return client

Mantenha a credencial antiga como previous até que o backend informe ao dispositivo que ela foi revogada. Depois, apague-a do armazenamento.

Fase 4: verificar

Antes de revogar qualquer coisa, confirme que a frota migrou. Sinais úteis:

  1. A confirmação de cada dispositivo no seu topic evt/credentials.
  2. A presença do novo client ID em $SYS/broker/connection/{clientId}/state e a ausência do antigo.
  3. O relatório do inventário: dispositivos que ainda usam a credencial antiga depois da janela.

Investigue os retardatários individualmente. Dispositivos offline são comuns; eles vão trocar na próxima vez que ficarem online, desde que você não revogue cedo demais.

Fase 5: revogar

Remova o conjunto de credenciais antigo no portal (ou apague o usuário e recarregue o Mosquitto). Depois, diga aos dispositivos para apagarem o slot previous. A partir daí, uma cópia vazada da credencial antiga não serve para nada.

Checklist de rotação

  1. O inventário mapeia cada dispositivo ao seu client ID atual.
  2. A nova credencial é emitida e registrada antes de qualquer dispositivo mudar.
  3. As credenciais são entregues apenas via TLS, em um topic ou canal específico do dispositivo, nunca retidas.
  4. O dispositivo guarda a nova credencial em um slot separado, com gravação atômica.
  5. O dispositivo volta para a credencial antiga em caso de rejeição e informa o ocorrido.
  6. A janela de sobreposição é longa o suficiente para dispositivos que ficam offline por dias.
  7. A revogação acontece só depois da verificação, e a exclusão no dispositivo, depois da revogação.
  8. O processo é executado periodicamente, não só durante incidentes.

Armadilhas a observar

  • Loops de tentativa apertados com senha errada. O ConnectMQ bloqueia endereços IP após repetidas falhas de login. Uma planta inteira, por exemplo em Manaus, atrás de um único endereço NAT pode ser bloqueada por alguns dispositivos mal-comportados. Use backoff exponencial e faça o fallback rapidamente.
  • Dois dispositivos com uma credencial. Como o client ID é vinculado à credencial, dois dispositivos que compartilham um conjunto tomam a sessão um do outro e se desconectam em loop. Cada dispositivo precisa do seu próprio conjunto.
  • Cota de conexões durante a sobreposição. Se os dispositivos mantêm as duas conexões por um instante, ou se você testa credenciais novas a partir de um notebook, conte isso no limite de conexões do seu plano.
  • Esquecer os clientes que não são dispositivos. Fluxos do Node-RED, agentes Telegraf e serviços de backend também têm credenciais. Rotacione-as no mesmo cronograma.

O armazenamento no dispositivo importa tanto quanto o processo de rotação. Veja proteger credenciais MQTT em dispositivos para opções em ESP32 e Linux, e provisionamento seguro de dispositivos IoT para colocar a primeira credencial no dispositivo com segurança.

Comece a usar o ConnectMQ

Um broker MQTT gerenciado tira das suas mãos os arquivos de senhas e as renovações de certificado, para que você possa se concentrar no lado do dispositivo da rotação. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e teste o fluxo completo de credenciais duplas com alguns dispositivos antes de implantá-lo; o servidor MQTT público é anônimo e serve apenas para testes e protótipos, não para validar credenciais. Para entender como as credenciais trafegam no CONNECT, leia autenticação MQTT com usuário e senha e, para ver como isso se encaixa em um ambiente de produção, leia sobre como operar um broker MQTT na nuvem.

Perguntas frequentes

Com que frequência devo rotacionar credenciais MQTT?

Não existe um intervalo universal. Escolha um que o seu processo consiga sustentar, normalmente anual ou a cada grande versão de firmware, e sempre faça a rotação imediatamente após suspeita de vazamento ou quando um dispositivo sair do seu controle.

Posso rotacionar credenciais em dispositivos que estão offline?

Sim, desde que a credencial antiga continue válida até que eles voltem. O dispositivo faz a troca na próxima conexão, e você só revoga depois disso.

Por que o client ID muda durante a rotação no ConnectMQ?

O ConnectMQ vincula os client IDs às credenciais emitidas, então um novo conjunto de credenciais vem com seu próprio client ID. Atualize qualquer monitoramento de presença ou inventário que use o client ID como chave.

E se a nova credencial for rejeitada?

O dispositivo deve voltar para a credencial antiga, reconectar e informar a falha, para que você corrija a credencial emitida antes de tentar de novo.

Artigos relacionados

Listas de Controle de Acesso (ACLs) no MQTT: Conceitos e Design

O que são as listas de controle de acesso MQTT, como brokers como o Mosquitto expressam regras de leitura e escrita por topic, como se comportam as operações negadas e como projetar namespaces de topics para manter a autorização simples.

8 min de leitura

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.