Conectar ao broker MQTT com Python paho e TLS • Do bit Ao Byte
Djames Suhanko 20 de agosto de 2020 4 min read
Mostrei aqui como configurar certificado no broker Mosquitto e mostrei como conectar ao broker utilizando TLS com mosquitto-clients. Também escrevi um artigo disponibilizando um script para coleta. E como montar um belo dashboard com Grafana e MQTT. Também como configurar HTTPS no Grafana; nada mal, hum? Mas ainda faltam alguns artigos para não ter desculpas para não usar MQTT. Antes de irmos para C++ e Qt, vamos ver como conectar ao broker MQTT com Python paho e TLS.
O processo de configuração de um broker MQTT é simples, como já demonstrado. Se ainda não viu nada sobre MQTT, talvez esteja um bocado atrasado; se bem que na verdade estamos todos. O MQTT (Message Queue Telemetry Transport) é um protocolo de telemetria criado pela IBM em 1999. Atualmente é um protocolo de grande importância, sendo provavelmente o mais leve depois da comunicação socket sem protocolos adicionais ao TCP/IP. Já escrevi "montanhas" de artigos sobre sua utilização, mas resolvi dedicar alguns artigos agora a compartilhar informações relacionadas à segurança – ainda mais que estou iniciando a implementação de LoRaWAN, de modo que isso não deve passar despercebido. Inicialmente não tinha mesmo a questão de um canal criptografado, mas agora como a temos, eis que para linguagem interpretada temos o Python paho e TLS.
Python paho e TLS: Python 2.7 ou Python 3?
Meu caro, esqueça o Python 2. Tem distribuição Linux que nem vem mais instalado, não vale o esforço de manter código nesse padrão. Algumas coisas mudaram o comportamento, como o range, print e outros. Até a forma de tratar hexadecimal mudou, como já mostrei em algum artigo tratando dados binários. Então, a recomendação é: use Python 3.
Claro que o importante é exemplificar, certo? Então permita-me contar brevemente a razão desse código que disponho logo após.
Pode ser que você se depare com o mesmo problema, mas tomara que não, senão valerá a máxima de que "os fins justificam os meios".
Em alguns clientes que rodam um sistema no Raspberry, os reports do MQTT pararam de acontecer repentinamente. Após analisar um bocado, vi que a razão era bloqueio pelo próprio fornecedor do link, que bloqueou o serviço na porta (inicialmente) 1883, logo no início da implementação. A porta 8883 ainda não estava sequer habilitada, mas tomaria o mesmo caminho, a partir do momento em que fosse filtrado o tráfego. Como resolver isso? Bem, considerando que o servidor que recebia os dados MQTT era o mesmo que servia o Grafana, não daria pra fazer aplicar a solução sem outro servidor.
Após contratar um segundo servidor, a solução: encaminhar os dados do MQTT para a porta 443, já com TLS. Agora está resolvido o problema, mas teve custo. Se for contratar link e tiver a opção de escolher, tire a Copel da lista. Agora, ao código.
client.subscribe("/TOPICO_RAIZ_A_SER_LIDO/#")
#print("Received a message on topic: " + msg.topic)
#print("Could not convert " + message + " to a float value")
#print(str(receiveTime) + ": " + msg.topic + " " + str(val))
#print("Finished writing to InfluxDB")
dbclient = InfluxDBClient('127.0.0.1', 8086, 'USER', 'SENHA', 'BANCO')
client = mqtt.Client("Colector")
client.username_pw_set('USERNAME_MQTT','SENHA_MQTT')
client.tls_set('/CAMINHO_ABSOLUTO_DO_CA_CRT')
client.connect("IP_OU_URL_DO_BROKER", 443, 60)
Esse é o programa da bridge, que discorri a respeito no artigo sobre a implementação do Grafana, citado no primeiro parágrafo. Adicionalmente temos duas linhas relacionadas ao TLS. Em uma delas, definimos o caminho absoluto do arquivo .crt (descrito na implementação de TLS no MQTT, também citado no primeiro parágrafo). Na outra linha, definimos o parâmetro "insecure", porque o nome do certificado não casa com o nome do broker, mas independente disso, sim, está com TLS e é uma conexão segura a partir de então.