Guias

Proteja o Mosquitto: senhas, ACLs e TLS

Proteja um broker Mosquitto passo a passo: crie um arquivo de senhas com mosquitto_passwd, restrinja tópicos com ACL usando %u e %c e ative TLS na porta 8883.

Atualizado · 8 min de leitura

Uma instalação nova do Mosquitto 2.x recusa clientes remotos anônimos, o que é um bom começo — mas, para usá-lo de verdade, você precisa de três camadas: autenticação (quem é você?), autorização (em quais tópicos você pode mexer?) e criptografia (alguém na rede consegue ler isto?). No Mosquitto, elas correspondem ao arquivo de senhas, ao arquivo de ACL e a um listener TLS. Este guia configura as três.

Se o broker ainda não está instalado, comece por como instalar o Mosquitto ou como rodá-lo no Docker. Os caminhos abaixo pressupõem uma instalação por pacote no Linux; no Docker, use /mosquitto/config/ em vez de /etc/mosquitto/.

1. Crie um arquivo de senhas com o mosquitto_passwd

O mosquitto_passwd guarda os nomes de usuário com hashes de senha com salt (nunca em texto puro). Crie o arquivo com o primeiro usuário e depois adicione os outros:

Criar usuários
# -c creates a NEW file and overwrites any existing one — first user only
sudo mosquitto_passwd -c /etc/mosquitto/passwd alice

# add or update users (prompts for the password)
sudo mosquitto_passwd /etc/mosquitto/passwd sensor-01

# non-interactive, e.g. in provisioning scripts
sudo mosquitto_passwd -b /etc/mosquitto/passwd bob 'S3cure-pass'

# delete a user
sudo mosquitto_passwd -D /etc/mosquitto/passwd bob

Evite o -b em máquinas compartilhadas: a senha acaba no histórico do shell e na lista de processos. Restrinja o arquivo para que só o broker possa lê-lo:

bash
sudo chown mosquitto:mosquitto /etc/mosquitto/passwd
sudo chmod 0700 /etc/mosquitto/passwd

Agora diga ao broker para usá-lo:

/etc/mosquitto/conf.d/secure.conf
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
Teste
sudo systemctl restart mosquitto

# should fail with "not authorised"
mosquitto_pub -h localhost -t test -m hi

# should succeed
mosquitto_pub -h localhost -u alice -P 'your-password' -t test -m hi

2. Restrinja tópicos com um arquivo de ACL

Só o arquivo de senhas permite que todo usuário autenticado leia e escreva em todos os tópicos. Um arquivo de ACL limita isso. Depois que acl_file é definido, tudo o que não for explicitamente permitido é negado.

/etc/mosquitto/acl
# --- pattern rules apply to every authenticated client ---
# each device may read and write only below its own username
pattern readwrite devices/%u/#
# each client may read its own command topic, keyed by client ID
pattern read commands/%c

# --- user-specific rules ---
user alice
topic readwrite #

user dashboard
topic read devices/#
topic write commands/+

user sensor-01
topic write telemetry/sensor-01/#
DiretivaSignificado
user <name>As linhas topic seguintes valem para esse nome de usuário
topic [read|write|readwrite|deny] <filter>Concede (ou, com deny, bloqueia) acesso; curingas + e # são permitidos. Omitir o tipo de acesso equivale a readwrite
pattern [access] <filter>Vale para todos os clientes; %u é substituído pelo nome de usuário e %c pelo client ID

Ative-o ao lado do arquivo de senhas:

/etc/mosquitto/conf.d/secure.conf
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl

Dois comportamentos pegam muita gente de surpresa. Primeiro, uma publicação em um tópico proibido é descartada silenciosamente no MQTT 3.1.1 — o cliente não vê erro nenhum (clientes MQTT 5 recebem um reason code no PUBACK de QoS 1/2). Segundo, uma assinatura proibida é recusada no SUBACK, o que muitas bibliotecas cliente não deixam transparecer. Quando "as mensagens simplesmente não chegam", verifique a ACL primeiro e rode o broker com log_type all durante a depuração. Use o testador de tópicos para conferir quais tópicos um filtro como devices/+/# realmente cobre.

3. Criptografe o tráfego com TLS

Sem TLS, nomes de usuário, senhas e payloads atravessam a rede em texto puro. A convenção é MQTT sobre TLS na porta 8883 (veja portas MQTT). Você precisa de um certificado, da chave privada dele e — em configurações autoassinadas — do certificado da CA.

/etc/mosquitto/conf.d/tls.conf
# MQTT over TLS
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile  /etc/mosquitto/certs/server.key
# cafile is only needed for self-signed / private CA chains or client certificates
# cafile /etc/mosquitto/certs/ca.crt

# Secure WebSockets for browser clients
listener 8884
protocol websockets
certfile /etc/mosquitto/certs/server.crt
keyfile  /etc/mosquitto/certs/server.key

Quando o TLS estiver funcionando, remova ou bloqueie no firewall o listener 1883 simples (ou prenda-o ao localhost com listener 1883 127.0.0.1) para que as credenciais não vazem por ele. Para exigir certificados de cliente (mutual TLS), adicione cafile e require_certificate true ao listener; adicionar use_identity_as_username true faz do CN do certificado o nome de usuário para fins de ACL.

Teste a partir de um cliente:

bash
# public CA (e.g. Let's Encrypt): use the system trust store
mosquitto_sub -h mqtt.example.com -p 8883 --capath /etc/ssl/certs \
  -u alice -P 'your-password' -t 'devices/#' -v

# self-signed / private CA
mosquitto_sub -h mqtt.example.com -p 8883 --cafile ca.crt \
  -u alice -P 'your-password' -t 'devices/#' -v

O hostname em -h precisa corresponder ao CN/SAN do certificado; caso contrário, a verificação falha. Mais opções de CLI estão na colinha de mosquitto_pub/sub.

Usando um certificado da Let's Encrypt

Um certificado publicamente confiável significa que os clientes não precisam de um arquivo de CA personalizado. Obtenha um com o certbot para o hostname do seu broker (a porta 80 precisa estar acessível para o desafio HTTP) e aponte o Mosquitto para os arquivos em live:

ini
listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/fullchain.pem
keyfile  /etc/letsencrypt/live/mqtt.example.com/privkey.pem
  • Use fullchain.pem, não cert.pem — os clientes precisam do certificado intermediário.
  • O usuário mosquitto precisa conseguir ler a chave; por padrão, /etc/letsencrypt só é acessível pelo root. Muitas configurações copiam os arquivos para /etc/mosquitto/certs/ com um deploy hook do certbot e ajustam o dono lá.
  • Os certificados são renovados a cada poucos meses. Adicione systemctl reload mosquitto ao deploy hook para que o broker carregue o novo certificado.

Juntando tudo

/etc/mosquitto/conf.d/secure.conf
listener 1883 127.0.0.1

listener 8883
certfile /etc/mosquitto/certs/fullchain.pem
keyfile  /etc/mosquitto/certs/privkey.pem

listener 8884
protocol websockets
certfile /etc/mosquitto/certs/fullchain.pem
keyfile  /etc/mosquitto/certs/privkey.pem

allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl

Em vez de editar à mão, você pode gerar isto com o gerador de mosquitto.conf. Para o panorama geral — políticas de client ID, limites de taxa, monitoramento —, leia as boas práticas de segurança MQTT e, se os clientes começarem a falhar com "not authorised", o guia de erros de conexão explica cada código.

Perguntas frequentes

Como recarrego o arquivo de senhas do Mosquitto sem reiniciar?

Envie um SIGHUP ao broker, por exemplo com sudo systemctl reload mosquitto ou kill -HUP com o PID do broker. O Mosquitto relê o arquivo de senhas e o de ACL ao receber SIGHUP, então os clientes existentes continuam conectados.

O que significa %u em um arquivo de ACL do Mosquitto?

Em uma linha pattern, %u é substituído pelo nome de usuário do cliente que se conecta e %c pelo client ID dele. pattern readwrite devices/%u/# permite que cada usuário acesse apenas os tópicos sob o próprio nome.

O Mosquitto pode usar um certificado da Let’s Encrypt?

Sim. Aponte certfile para fullchain.pem e keyfile para privkey.pem, garanta que o usuário mosquitto consiga lê-los e recarregue o broker após cada renovação. Os clientes então verificam o servidor com o repositório de CAs do sistema.