Segurança MQTT

Certificado Autoassinado no MQTT: Quando e Como Usar

Um tutorial prático para criar uma autoridade certificadora privada com OpenSSL, proteger um broker Mosquitto de laboratório na porta 8883 e conectar clientes, além dos custos operacionais que tornam os certificados públicos mais fáceis em produção.

Ilustração de certificado autoassinado no MQTT com uma autoridade certificadora privada assinando o certificado de um broker em uma rede de laboratório
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

Um certificado autoassinado para MQTT permite criptografar um broker de laboratório ou offline, como o de uma planta isolada da internet em Manaus, sem uma autoridade certificadora pública. Feito de forma ingênua, ele falha na verificação em todos os clientes ou tenta as pessoas a desativar a verificação de vez. Este tutorial mostra o padrão correto, uma pequena CA privada criada com OpenSSL, depois configura o Mosquitto na porta 8883, conecta clientes Python e de linha de comando e explica quando um certificado publicamente confiável poupa todo esse trabalho.

Certificado autoassinado vs CA privada

A expressão "certificado autoassinado" é usada para duas configurações diferentes:

  • Um único certificado de servidor autoassinado: o certificado do broker assina a si mesmo. Os clientes precisam confiar exatamente nesse certificado. Quando ele expira ou muda, todos os clientes precisam ser atualizados.
  • Uma CA privada: você cria seu próprio certificado de CA raiz (autoassinado) e o usa para assinar o certificado do broker. Os clientes confiam na CA, então você pode reemitir o certificado do broker à vontade, desde que a CA continue a mesma.

A abordagem com CA privada é o que você quer quase sempre. Ela custa dois comandos OpenSSL a mais e evita redistribuir a confiança toda vez que o certificado do servidor muda.

Quando um certificado autoassinado faz sentido no MQTT

Cenário Autoassinado / CA privada Certificado publicamente confiável
Testes no notebook ou laboratório Boa escolha Possível, mas desnecessário
Rede de fábrica isolada (air-gapped), sem DNS público Muitas vezes a única opção Impossível sem DNS público
Broker interno acessado por IP ou nome .local Viável CAs públicas não emitem para esses nomes
Broker exposto à internet para dispositivos e apps Evite Fortemente preferível
Dashboards no navegador via WSS Trabalhoso (alertas do navegador) Funciona de imediato
Clientes de terceiros que você não controla Trabalhoso (precisam instalar sua CA) Funciona de imediato

Passo 1: crie a CA privada

Crie um diretório de trabalho e uma chave e um certificado de CA. Proteja o ca.key: quem tiver esse arquivo pode se passar pelo seu broker.

mkdir -p ~/mqtt-ca && cd ~/mqtt-ca

openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
  -subj "/O=Example Lab/CN=Example Lab MQTT CA" -out ca.crt

Passo 2: crie o certificado do broker com SAN

Clientes TLS modernos ignoram o common name do certificado na checagem de hostname e olham apenas o Subject Alternative Name (SAN). Omitir o SAN é o motivo mais comum de uma configuração MQTT autoassinada falhar na verificação. Inclua todos os nomes e endereços IP que os clientes vão usar.

openssl genrsa -out broker.key 2048
openssl req -new -key broker.key \
  -subj "/O=Example Lab/CN=mqtt.lab.local" -out broker.csr

cat > broker.ext <<'EOF'
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:mqtt.lab.local, DNS:localhost, IP:192.168.1.50
EOF

openssl x509 -req -in broker.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 397 -sha256 -extfile broker.ext -out broker.crt

Confira o resultado antes de usá-lo:

openssl x509 -in broker.crt -noout -subject -issuer -dates -ext subjectAltName
openssl verify -CAfile ca.crt broker.crt

O segundo comando deve exibir broker.crt: OK. Substitua os nomes e o endereço IP pelos seus.

Passo 3: configure o Mosquitto para TLS

Copie os arquivos para o broker e crie a configuração do listener:

sudo mkdir -p /etc/mosquitto/certs
sudo cp ca.crt broker.crt broker.key /etc/mosquitto/certs/
sudo chown mosquitto: /etc/mosquitto/certs/broker.key
sudo chmod 600 /etc/mosquitto/certs/broker.key
# /etc/mosquitto/conf.d/tls.conf
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/broker.crt
keyfile /etc/mosquitto/certs/broker.key

# Exige também credenciais MQTT
allow_anonymous false
password_file /etc/mosquitto/passwd

Crie um usuário com sudo mosquitto_passwd -c /etc/mosquitto/passwd labuser, reinicie com sudo systemctl restart mosquitto e verifique o journalctl -u mosquitto em busca de erros, como arquivos de chave ilegíveis.

Passo 4: conecte os clientes

Todo cliente precisa do ca.crt, nunca da chave da CA. Com as ferramentas do mosquitto:

mosquitto_sub -h mqtt.lab.local -p 8883 --cafile ca.crt \
  -u labuser -P 'your-password' -i lab-sub-1 -t "lab/#" -v

mosquitto_pub -h mqtt.lab.local -p 8883 --cafile ca.crt \
  -u labuser -P 'your-password' -i lab-pub-1 -t "lab/test" -m "hello private CA"

Em Python, com o paho-mqtt 2.x:

import paho.mqtt.client as mqtt

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="lab-python-1")
client.tls_set(ca_certs="ca.crt")          # confia apenas na CA privada
client.username_pw_set("labuser", "your-password")
client.connect("mqtt.lab.local", 8883)
client.loop_start()
client.publish("lab/test", "verified against private CA", qos=1).wait_for_publish()
client.loop_stop()
client.disconnect()

No Node.js, passe ca: fs.readFileSync("ca.crt") nas opções do MQTT.js. Em um ESP32, incorpore o conteúdo do ca.crt e chame setCACert(). Repare que a verificação continua totalmente ativada em todos os exemplos: o cliente simplesmente confia na sua CA em vez de uma pública. Se encontrar erros de verificação, nosso guia sobre SSL CERTIFICATE_VERIFY_FAILED no MQTT lista as causas habituais.

Confiando na CA privada em todo o sistema

Passar --cafile para cada ferramenta fica cansativo nas máquinas do laboratório. Em uma estação Linux, você pode adicionar a CA ao repositório do sistema operacional para que as ferramentas que o utilizam, como mosquitto_sub --capath /etc/ssl/certs, o curl e a maioria dos runtimes de linguagens, confiem automaticamente no broker do laboratório:

# Debian / Ubuntu / Raspberry Pi OS
sudo cp ca.crt /usr/local/share/ca-certificates/example-lab-mqtt-ca.crt
sudo update-ca-certificates

No Windows, importe o ca.crt no repositório "Autoridades de Certificação Raiz Confiáveis" com certutil -addstore -f Root ca.crt em um prompt elevado; no macOS, adicione-o ao keychain do Sistema e marque-o como confiável. Faça isso de forma consciente. Tudo o que for assinado pela CA do laboratório passa a ser confiável para aquela máquina para qualquer finalidade, não só MQTT, então proteja a chave da CA à altura e remova a CA das máquinas que saírem do laboratório. Observe que clientes Python baseados em certifi e o Node.js ignoram o repositório do sistema operacional, a menos que configurados de outra forma, então continuam precisando do arquivo da CA.

Armadilhas a evitar

  1. SAN ausente: a verificação de hostname falha mesmo com a cadeia válida.
  2. Distribuir o arquivo errado: os clientes precisam do ca.crt, não do broker.crt, e nunca do ca.key.
  3. Desativar a verificação: --insecure, tls_insecure_set(True) ou rejectUnauthorized: false tornam o certificado inútil.
  4. Esquecer a expiração: coloque a data de expiração do certificado do broker na agenda e automatize a renovação, se puder. Um certificado expirado derruba todos os clientes de uma vez.
  5. Validade longa demais no certificado do servidor: certificados de longa duração são práticos, mas aumentam o impacto de uma chave vazada. Mantenha a CA de longa duração e o certificado do broker mais curto.
  6. Chave da CA no broker: guarde a chave da CA offline. O broker só precisa da própria chave e do próprio certificado.
  7. Problemas de relógio: dispositivos sem hora precisa rejeitam certificados válidos.

A mesma CA privada também pode assinar certificados de cliente se você quiser TLS mútuo; veja MQTT mTLS com certificados de cliente X.509.

Renovando o certificado do broker

Como a CA privada continua a mesma, a renovação só afeta o broker. Gere uma nova chave (ou reutilize a antiga, se a sua política permitir), crie um novo CSR, assine-o com a mesma CA e o mesmo arquivo broker.ext e substitua os arquivos no broker:

openssl genrsa -out broker-new.key 2048
openssl req -new -key broker-new.key -subj "/O=Example Lab/CN=mqtt.lab.local" -out broker-new.csr
openssl x509 -req -in broker-new.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 397 -sha256 -extfile broker.ext -out broker-new.crt

sudo cp broker-new.crt /etc/mosquitto/certs/broker.crt
sudo cp broker-new.key /etc/mosquitto/certs/broker.key
sudo systemctl restart mosquitto

Os clientes não mudam, porque confiam no ca.crt, não no certificado do broker. Essa é a recompensa do padrão de CA privada em comparação com um certificado autoassinado isolado, em que todos os clientes precisariam do novo arquivo. Vale a pena adicionar um cron job simples que avise um mês antes da expiração:

openssl x509 -checkend 2592000 -noout -in /etc/mosquitto/certs/broker.crt \
  || echo "MQTT broker certificate expires within 30 days"

O custo operacional que ninguém menciona

Uma CA privada é fácil no primeiro dia. O custo aparece depois: distribuir o ca.crt para cada novo cliente, explicar os alertas do navegador quando alguém abre um dashboard via WSS, renovar o certificado do broker antes que expire, substituir a própria CA depois de uma década ou de um comprometimento da chave, e documentar tudo isso para o próximo engenheiro. Em um sistema exposto à internet, esse esforço não traz nada que um certificado publicamente confiável já não ofereça.

Esse é o principal motivo para usar um broker MQTT gerenciado em produção. O ConnectMQ apresenta um certificado Let's Encrypt em que sistemas operacionais, navegadores, Python e Node.js já confiam, e o renova automaticamente. Os clientes se conectam na porta 8883 ou via WebSocket seguro na 8084 sem nenhum arquivo de CA para distribuir, além de incorporar uma raiz pública padrão nos microcontroladores. Você pode confirmar isso em segundos no servidor MQTT público (gratuito), que serve para testes e protótipos, não para dados de produção:

mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -i pubca-test-3e8b -t "connectmq/demo/3e8b/#" -v

Para comparar modelos de hospedagem, leia nosso guia de broker MQTT na nuvem e, para a lista completa de medidas de hardening, veja configuração de TLS no MQTT.

Comece a usar o ConnectMQ

Dispense a CA privada no seu broker de produção. Cadastre-se no ConnectMQ em app.connectmq.com, escolha o plano Serverless gratuito, sem cartão de crédito, crie um broker e conecte-se na porta 8883 com o username, a senha e o client ID gerados. O ConnectMQ cuida dos certificados e das renovações; deixe sua configuração autoassinada no laboratório, que é o lugar dela.

Perguntas frequentes

Posso usar um certificado autoassinado em MQTT de produção?

Pode, em redes fechadas onde você controla todos os clientes, desde que mantenha uma CA privada adequada e gerencie as renovações. Para brokers expostos à internet, um certificado publicamente confiável é mais simples e evita distribuir a confiança para cada cliente.

Por que meu cliente rejeita o certificado mesmo com o arquivo da CA?

O motivo mais comum é um Subject Alternative Name ausente ou errado. Verifique com openssl x509 -noout -ext subjectAltName -in broker.crt e garanta que ele lista o hostname que os clientes usam.

Consigo um certificado Let's Encrypt para um broker interno?

Somente para um nome de domínio público que você controla, usando validação por DNS. CAs públicas não emitem certificados para endereços IP privados ou nomes .local.

Preciso reiniciar o Mosquitto depois de renovar o certificado?

O Mosquitto carrega os certificados na inicialização, então planeje um restart ou reload após a renovação e teste com openssl s_client em seguida.

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.