Segurança em MQTT: Autenticação e Criptografia no ESP32

A Internet das Coisas (IoT) está revolucionando a maneira como interagimos com o mundo ao nosso redor. Dispositivos como o ESP32 permitem que engenheiros, estudantes e entusiastas construam soluções conectadas de forma simples e eficiente. No entanto, conforme aumentamos a quantidade de dispositivos conectados, a segurança torna-se uma preocupação crucial. Hoje, vamos explorar como implementar autenticação e criptografia no MQTT utilizando o ESP32, garantindo que seus projetos sejam não apenas funcionais, mas também seguros.

Por que a Segurança é Importante no MQTT com ESP32🔗

O MQTT é um protocolo de comunicação leve amplamente usado em aplicações IoT devido à sua simplicidade e eficiência. No entanto, por padrão, ele não possui mecanismos robustos de segurança. Sem implementar medidas adequadas, seus dados podem ser interceptados ou adulterados por terceiros mal-intencionados.

Imagine um cenário onde você está monitorando a temperatura de uma estufa agrícola usando o ESP32 e enviando os dados para um servidor central. Se alguém interceptar essa comunicação, pode obter informações sensíveis ou até mesmo enviar comandos falsos, prejudicando toda a operação. Portanto, implementar autenticação e criptografia é essencial para proteger suas informações e garantir a integridade do sistema.

Entendendo a Autenticação no MQTT🔗

A autenticação é o processo de verificar a identidade de um usuário ou dispositivo antes de permitir o acesso a recursos ou dados. No contexto do MQTT, isso significa garantir que apenas dispositivos autorizados possam se conectar ao broker (servidor) e publicar ou subscrever mensagens.

Implementando Autenticação Simples

A maneira mais básica de implementar autenticação no MQTT é através de um nome de usuário e senha. Muitos brokers MQTT suportam esse método, permitindo que você defina credenciais que os clientes devem fornecer ao se conectar.

Passo a Passo:

1. Configurar o Broker MQTT com Autenticação

Se você estiver usando um broker como o Mosquitto, pode habilitar a autenticação editando o arquivo de configuração:
allow_anonymous false
password_file /etc/mosquitto/passwd
Em seguida, crie um arquivo de senha:
mosquitto_passwd -c /etc/mosquitto/passwd seu_usuario

2. Atualizar o Código do ESP32 para Fornecer Credenciais

No código do seu ESP32, você precisará fornecer o nome de usuário e a senha ao estabelecer a conexão.
#include <WiFi.h>
#include <PubSubClient.h>
const char* ssid = "SuaRedeWiFi";
const char* password = "SenhaRedeWiFi";
const char* mqttServer = "EnderecoDoBroker";
const int mqttPort = 1883;
const char* mqttUser = "seu_usuario";
const char* mqttPassword = "sua_senha";
WiFiClient espClient;
PubSubClient client(espClient);
void setup()
{
    Serial.begin(115200);
    setup_wifi();
    client.setServer(mqttServer, mqttPort);
}
void setup_wifi()
{
    delay(10);
    Serial.println();
    Serial.print("Conectando a ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi conectado");
    Serial.print("Endereço IP: ");
    Serial.println(WiFi.localIP());
}
void reconnect()
{
    while (!client.connected())
    {
        Serial.print("Tentando se conectar ao MQTT...");
        if (client.connect("ESP32Client", mqttUser, mqttPassword))
        {
            Serial.println("conectado");
        }
        else
        {
            Serial.print("falhou, rc=");
            Serial.print(client.state());
            Serial.println(" tentando novamente em 5 segundos");
            delay(5000);
        }
    }
}
void loop()
{
    if (!client.connected())
    {
        reconnect();
    }
    client.loop();
    // Seu código adicional aqui
}

Limitando Acesso a Tópicos

Além da autenticação básica, alguns brokers permitem controlar quais usuários podem acessar determinados tópicos. Isso adiciona uma camada extra de segurança, garantindo que um dispositivo só possa interagir com os tópicos para os quais tem permissão.

Introdução à Criptografia no MQTT🔗

A criptografia é o processo de codificar informações de tal forma que apenas as partes autorizadas possam acessá-las. No MQTT, a criptografia é geralmente implementada usando TLS/SSL, que protege os dados em trânsito entre o cliente e o broker.

Por que Usar Criptografia

Sem criptografia, os dados enviados entre o ESP32 e o broker são transmitidos em texto claro. Isso significa que qualquer pessoa com acesso à rede pode interceptar e ler as informações. A criptografia impede essa interceptação, garantindo a confidencialidade dos dados.

Implementando TLS/SSL no ESP32

Para usar TLS/SSL com MQTT no ESP32, é necessário usar uma porta segura (geralmente 8883) e fornecer certificados adequados.

Passo a Passo:

1. Configurar o Broker MQTT com TLS/SSL

No Mosquitto, você pode habilitar TLS/SSL adicionando as seguintes linhas ao arquivo de configuração:
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
Certifique-se de que os certificados estão corretamente gerados e armazenados nas pastas especificadas.

2. Gerar Certificados

Você pode gerar certificados autofirmados para testes usando o OpenSSL:
# Gerar chave privada da CA
openssl genrsa -des3 -out ca.key 2048
# Gerar certificado da CA
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
# Gerar chave privada do servidor
openssl genrsa -out server.key 2048
# Gerar CSR (Certificate Signing Request) para o servidor
openssl req -new -key server.key -out server.csr
# Assinar o certificado do servidor com a CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650

3. Atualizar o Código do ESP32 para Utilizar TLS/SSL

No ESP32, você precisa utilizar a classe WiFiClientSecure em vez de WiFiClient.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* ssid = "SuaRedeWiFi";
const char* password = "SenhaRedeWiFi";
const char* mqttServer = "EnderecoDoBroker";
const int mqttPort = 8883;
const char* mqttUser = "seu_usuario";
const char* mqttPassword = "sua_senha";
const char* ca_cert = \
    "-----BEGIN CERTIFICATE-----\n" \
    "SEU_CERTIFICADO_CA_AQUI\n" \
    "-----END CERTIFICATE-----\n";
WiFiClientSecure espClient;
PubSubClient client(espClient);
void setup()
{
    Serial.begin(115200);
    setup_wifi();
    espClient.setCACert(ca_cert);
    client.setServer(mqttServer, mqttPort);
}
// O restante do código permanece similar
Importante: Substitua "SEU_CERTIFICADO_CA_AQUI" pelo conteúdo real do seu certificado CA.

Exemplo Prático: Autenticação e Criptografia Combinados🔗

Vamos juntar tudo e criar um exemplo onde o ESP32 se conecta a um broker MQTT utilizando autenticação por nome de usuário e senha, além de criptografia TLS/SSL.

Código Completo:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* ssid = "SuaRedeWiFi";
const char* password = "SenhaRedeWiFi";
const char* mqttServer = "EnderecoDoBroker";
const int mqttPort = 8883;
const char* mqttUser = "seu_usuario";
const char* mqttPassword = "sua_senha";
const char* ca_cert = \
    "-----BEGIN CERTIFICATE-----\n" \
    "SEU_CERTIFICADO_CA_AQUI\n" \
    "-----END CERTIFICATE-----\n";
WiFiClientSecure espClient;
PubSubClient client(espClient);
void setup()
{
    Serial.begin(115200);
    setup_wifi();
    espClient.setCACert(ca_cert);
    client.setServer(mqttServer, mqttPort);
}
void setup_wifi()
{
    delay(10);
    Serial.println();
    Serial.print("Conectando a ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi conectado");
    Serial.print("Endereço IP: ");
    Serial.println(WiFi.localIP());
}
void reconnect()
{
    while (!client.connected())
    {
        Serial.print("Tentando se conectar ao MQTT...");
        if (client.connect("ESP32Client", mqttUser, mqttPassword))
        {
            Serial.println("conectado");
            // Inscreva-se em tópicos aqui, se necessário
        }
        else
        {
            Serial.print("falhou, rc=");
            Serial.print(client.state());
            Serial.println(" tentando novamente em 5 segundos");
            delay(5000);
        }
    }
}
void loop()
{
    if (!client.connected())
    {
        reconnect();
    }
    client.loop();
    // Exemplo de publicação
    client.publish("topico/teste", "Mensagem segura via MQTT!");
    delay(10000); // Aguarda 10 segundos antes de enviar outra mensagem
}

Neste exemplo, o ESP32:

  • Conecta-se à rede Wi-Fi.
  • Estabelece uma conexão segura com o broker MQTT usando TLS/SSL.
  • Autentica com nome de usuário e senha.
  • Publica uma mensagem criptografada a cada 10 segundos.

Considerações sobre Certificados e Autoridades Certificadoras🔗

Ao usar certificados autofirmados, é importante notar que eles são adequados apenas para testes e desenvolvimento. Em ambientes de produção, é recomendável obter certificados de uma Autoridade Certificadora (CA) confiável. Isso garante que os dispositivos possam verificar a autenticidade do broker e evitar ataques man-in-the-middle.

Como Carregar Certificados no ESP32

O ESP32 possui um espaço limitado de memória, portanto, o gerenciamento de certificados deve ser feito com cuidado. Você pode armazenar o certificado CA diretamente no código, como mostrado anteriormente, ou utilizar o sistema de arquivos SPIFFS para armazenar certificados maiores.

Boas Práticas de Segurança com MQTT e ESP32🔗

1. Mantenha o Firmware Atualizado

Mantenha sempre o firmware do ESP32 atualizado para aproveitar as últimas correções de segurança.

2. Use Credenciais Fortes

Utilize senhas complexas e altere-as regularmente. Evite usar credenciais padrão ou fáceis de adivinhar.

3. Implemente Controle de Acesso

Restrinja o acesso a tópicos sensíveis e atribua permissões específicas para cada dispositivo ou usuário.

4. Monitore Atividades Suspeitas

Configure logs e alertas no broker MQTT para detectar atividades incomuns que possam indicar uma tentativa de ataque.

5. Desative Protocolos e Portas Não Utilizados

Se você não precisa de conexões não seguras (por exemplo, na porta 1883), desative-as para reduzir a superfície de ataque.

6. Eduque os Usuários

Se o dispositivo for utilizado por outros, certifique-se de que eles estejam cientes das práticas de segurança e da importância de manter as informações confidenciais.

Conclusão🔗

A segurança é um componente essencial em qualquer aplicação IoT. Ao implementar autenticação e criptografia no MQTT com o ESP32, você protege seus dados contra acessos não autorizados e garante a integridade e confiabilidade do seu sistema. Embora possa parecer desafiador no início, seguir as práticas recomendadas e entender os conceitos fundamentais permite que você construa soluções robustas e seguras.

Lembre-se de que a segurança não é um estado final, mas um processo contínuo de avaliação e aprimoramento. Mantenha-se informado sobre novas ameaças e atualizações no protocolo MQTT e no ESP32 para garantir que seus projetos permaneçam protegidos no futuro.

Este artigo faz parte do grupo Monitoramento Remoto com ESP32 e MQTT
Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Artigos Relacionados