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_pubemosquitto_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.
É legal capturar tráfego MQTT?
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.



