Segurança MQTT

Tutorial MQTT com Wireshark: Capture e Analise o Tráfego MQTT

Capture seu próprio tráfego MQTT com o Wireshark, leia cada campo dos pacotes na porta 1883 e veja exatamente o que o TLS na porta 8883 protege, usando o servidor MQTT público (gratuito) broker.connectmq.com.

Captura MQTT no Wireshark mostrando pacotes CONNECT e PUBLISH decodificados ao lado de registros TLS criptografados na porta 8883
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

Uma captura MQTT no Wireshark mostra exatamente o que seu cliente envia ao broker, campo por campo. Neste tutorial você vai capturar seu próprio tráfego para o servidor MQTT público (gratuito) broker.connectmq.com na porta 1883, decodificar pacotes CONNECT, SUBSCRIBE e PUBLISH e depois repetir o teste na porta TLS 8883 para ver o que a criptografia esconde. É a maneira mais rápida de depurar problemas de conexão e de comprovar por si mesmo por que o tráfego de produção precisa usar TLS.

Capture tráfego apenas em redes e dispositivos que sejam seus ou que você tenha autorização para monitorar.

O que você precisa

  • Wireshark 3.x ou 4.x do site oficial, com permissão de captura na sua máquina.
  • Os clientes de linha de comando do Mosquitto (mosquitto_pub e mosquitto_sub).
  • Opcionalmente, Python 3 com paho-mqtt 2.x para a etapa de descriptografia TLS.
  • Um prefixo de topic único, por exemplo connectmq/demo/ws-4821/.

O servidor MQTT público está aberto a todos e serve apenas para testes e protótipos, então publique apenas dados de teste. O artigo sobre o servidor MQTT público (gratuito) lista seus limites.

Passo 1: inicie uma captura com filtro de porta

Abra o Wireshark, escolha a interface de rede que você usa para acessar a internet e digite um filtro de captura para gravar apenas o tráfego MQTT:

tcp port 1883 or tcp port 8883

Inicie a captura. O Wireshark reconhece MQTT na porta 1883 automaticamente e aplica seu dissector MQTT.

Passo 2: gere tráfego MQTT sem criptografia

Em um terminal, faça a assinatura:

mosquitto_sub -h broker.connectmq.com -p 1883 -i ws-sub-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/#' -v

Em um segundo terminal, publique uma mensagem retida e uma normal:

mosquitto_pub -h broker.connectmq.com -p 1883 -i ws-pub-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/temp' -m '{"celsius":21.7}' -q 1

mosquitto_pub -h broker.connectmq.com -p 1883 -i ws-pub-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/status' -m 'online' -r

Encerre o assinante com Ctrl+C e pare a captura.

Passo 3: aplique filtros de exibição MQTT

Digite um filtro de exibição na barra do topo. Estes são os mais úteis:

Filtro de exibição Mostra
mqtt Todos os pacotes MQTT decodificados
mqtt.msgtype == 1 CONNECT
mqtt.msgtype == 2 CONNACK
mqtt.msgtype == 3 PUBLISH
mqtt.msgtype == 8 SUBSCRIBE
mqtt.msgtype == 12 or mqtt.msgtype == 13 PINGREQ e PINGRESP
mqtt.msgtype == 14 DISCONNECT
mqtt.topic contains "ws-4821" Pacotes do seu prefixo de topic
mqtt.clientid == "ws-pub-4821" CONNECT de um cliente específico
tls Tráfego criptografado, normalmente na 8883

Os nomes dos campos podem variar um pouco entre versões do Wireshark. Se um filtro for rejeitado, expanda um pacote, clique com o botão direito em um campo e escolha "Apply as Filter" para obter o nome exato.

Passo 4: leia os pacotes decodificados

CONNECT

Selecione um pacote CONNECT e expanda "MQ Telemetry Transport Protocol". Você verá:

  • Nome e versão do protocolo (MQTT, versão 5, ou 4 para 3.1.1).
  • Connect flags: clean start, will flag, flags de usuário e senha.
  • Keep alive em segundos.
  • Propriedades (MQTT 5), como o session expiry interval.
  • Client ID, aqui ws-pub-4821.

Se um cliente enviasse usuário e senha pela porta 1883, ambos apareceriam aqui em texto puro. Essa única observação é o argumento mais forte a favor do TLS de que você vai precisar.

CONNACK

O CONNACK mostra o reason code (0x00 significa sucesso) e, no MQTT 5, propriedades do servidor como tamanho máximo de pacote, receive maximum, se retained messages e assinaturas com curinga estão disponíveis e o QoS máximo. Lê-las é uma forma rápida de entender os limites de um broker.

SUBSCRIBE e SUBACK

O pacote SUBSCRIBE lista os filtros de topic com suas opções. O SUBACK retorna um reason code por filtro. Um código de 0x80 ou maior significa que a assinatura foi recusada, algo fácil de passar despercebido nos logs da aplicação, mas óbvio no Wireshark.

PUBLISH

Cada PUBLISH mostra o topic, o QoS, a flag de retain, o identificador do pacote para QoS 1 e 2, as propriedades e o payload bruto. Sua mensagem {"celsius":21.7} pode ser lida no painel de bytes do pacote. O publish com QoS 1 é seguido por um PUBACK do broker com o mesmo identificador de pacote. Veja níveis de QoS do MQTT explicados para entender o que significa cada troca.

Passo 5: repita o teste via TLS na porta 8883

Inicie uma nova captura com o mesmo filtro e repita a publicação, desta vez usando TLS:

mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -i ws-pub-tls-4821 -V mqttv5 \
  -t 'connectmq/demo/ws-4821/temp' -m '{"celsius":22.1}' -q 1

No Windows ou no macOS, aponte --cafile para um pacote de CAs em vez de --capath. A ConnectMQ usa um certificado Let's Encrypt, no qual os pacotes de CAs padrão confiam.

Aplique o filtro de exibição tls. Agora você vê:

  • Um handshake TLS: ClientHello, ServerHello e, dependendo da versão, mensagens de certificado.
  • O Server Name Indication (broker.connectmq.com) no ClientHello, que não é criptografado.
  • Registros "Application Data" sem topic, client ID ou payload visíveis.

Um observador na rede ainda consegue ver que você conversou com o broker, quando e aproximadamente quantos dados enviou. Ele não consegue ver credenciais, topics nem o conteúdo das mensagens. Essa é a proteção que o TLS oferece, e o guia de configuração de TLS no MQTT explica como configurá-lo em cada cliente.

Passo 6: descriptografe seu próprio tráfego TLS para depuração

Às vezes é preciso inspecionar o tráfego TLS do seu próprio cliente durante o desenvolvimento. O Wireshark consegue descriptografar TLS se o cliente gravar suas chaves de sessão em um arquivo de key log. O módulo ssl do Python oferece suporte a isso:

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

ctx = ssl.create_default_context()
ctx.keylog_filename = "tls-keys.log"  # apenas em desenvolvimento, nunca em produção

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="ws-py-tls-4821",
                     protocol=mqtt.MQTTv5)
client.tls_set_context(ctx)

def on_connect(c, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    c.publish("connectmq/demo/ws-4821/debug", "decrypt me", qos=1)

client.on_connect = on_connect
client.connect("broker.connectmq.com", 8883, keepalive=30)
client.loop_start()
time.sleep(3)
client.loop_stop()
client.disconnect()

No Wireshark, vá em Edit > Preferences > Protocols > TLS e defina "(Pre)-Master-Secret log filename" com o arquivo tls-keys.log. Como o Wireshark não sabe que a porta 8883 transporta MQTT, clique com o botão direito em um pacote TLS, escolha "Decode As..." e defina a porta 8883 como MQTT. Os pacotes descriptografados agora mostram os mesmos campos que você viu na 1883.

Apague o arquivo de key log depois. Qualquer pessoa que o tenha consegue descriptografar aquela captura.

Solução de problemas com o Wireshark

Sintoma na captura Causa provável
SYN enviado, sem SYN-ACK Firewall bloqueando a porta ou hostname errado
TCP conecta, o cliente envia CONNECT, o broker fecha imediatamente Violação de protocolo, client ID vazio ou credenciais inválidas
CONNACK com reason 0x86 ou 0x87 Usuário/senha incorretos ou não autorizado
CONNACK com 0x85 Client identifier inválido
Alerta TLS "unknown CA" ou "bad certificate" O cliente não confia na cadeia de certificados
PINGREQ sem PINGRESP, seguido de reset A rede derruba conexões ociosas; reduza o keep alive
DISCONNECT com 0x97 Cota excedida no broker
Muitos pacotes CONNECT com segundos de intervalo Loop de reconexão, muitas vezes por um client ID duplicado

O caso do client ID duplicado é especialmente comum: dois dispositivos com o mesmo ID se revezam derrubando um ao outro, e o Wireshark mostra o padrão na hora.

Levando para produção

O servidor MQTT público serve para testes. Para dados reais, como a telemetria de uma usina ou de uma linha de manufatura, crie um broker privado, use o usuário, a senha e o client ID gerados e conecte-se apenas via TLS na 8883 ou via WebSockets seguros na 8084. Na ConnectMQ, os brokers privados também incluem isolamento de tenants, cotas, proteção contra inundação e bloqueio de IP após logins com falha repetidos. O Wireshark continua útil nesse cenário: capturar do seu lado, por exemplo no gateway de uma planta em Campinas, confirma que nada sai do seu dispositivo sem criptografia. Para entender o que mais pode dar errado em brokers desprotegidos, leia sobre brokers MQTT expostos.

Comece a usar a ConnectMQ

Experimente agora mesmo as capturas acima com o broker.connectmq.com e depois crie um broker privado no plano Serverless (Free) em app.connectmq.com, sem cartão de crédito. Seu código de cliente só precisa de um hostname, credenciais e da porta 8883 para passar do teste para um broker MQTT gerenciado. Para dicas gerais de fortalecimento, veja as melhores práticas de segurança MQTT.

Perguntas frequentes

Por que o Wireshark não mostra MQTT na porta 8883?

O tráfego na 8883 é criptografado com TLS, então o Wireshark só vê registros TLS. Você pode descriptografar suas próprias sessões com um arquivo de key log e depois usar "Decode As" para aplicar o dissector MQTT.

Qual é o filtro do Wireshark para MQTT?

Use o filtro de exibição mqtt para todos os pacotes decodificados, ou mqtt.msgtype == 3 apenas para pacotes PUBLISH. Um filtro de captura tcp port 1883 limita a gravação ao MQTT sem criptografia.

O Wireshark consegue ver MQTT sobre WebSockets?

Sim. Em uma porta WebSocket sem criptografia, o Wireshark decodifica os frames WebSocket e pode aplicar o dissector MQTT ao payload deles. WebSockets seguros na 8084 são criptografados, assim como a porta 8883.

Capturar tráfego nos seus próprios dispositivos e redes para depuração é uma prática normal. Capturar o tráfego de outras pessoas sem autorização não é, então limite as capturas a sistemas que sejam seus ou que você tenha permissão para monitorar.

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.