it:iot:mosquitto

Mosquitto

V tutoriálu je srozumitelně popsané, jak MQTT funguje.

Do konfiguračního souboru lze dle zdroje přidat tyto řádky:

# Types of messages to log. Use multiple log_type lines for logging
# multiple types of messages.
# Possible types are: debug, error, warning, notice, information, 
# none, subscribe, unsubscribe, websockets, all.
# Note that debug type messages are for decoding the incoming/outgoing
# network packets. They are not logged in "topics".
log_type error
log_type warning
log_type notice
log_type information

Vycházím z návodu Configuring the Mosquitto MQTT Docker container for use with Home Assistant, který popisuje zapnutí autentizace pro Mosquitto. Další informace jsem pak čerpal z tohoto článku: Deploying Mosquitto MQTT broker on Linux using Docker

V konfiguračním souboru mosquitto.conf nastavím/změním toto:

password_file /mosquitto/pwfile/pwfile
allow_anonymous false

Pak se připojím do kontejneru s mosquitto a vytvořím uživatele s heslem:

docker exec -it mosquitto sh
mosquitto_passwd -c /mosquitto/pwfile/pwfile majordomus

Nakonec retartovat kontejner s Mosquitto.

Příkaz pro čtení s autentizací:

$ mosquitto_sub -u henry --pw 'passw0rd' -h localhost -p 1883 -v -t test/message

Příkaz pro publikaci s autentizací:

$ mosquitto_pub -u henry -P 'passw0rd' -h localhost -p 1883 -t test/message -m 'Hello World!'

Nejprve jsem postupoval podle návodu Secure MQTT broker (TLS) and Docker Compose.

Jako první jsem použil tento skript pro vygenerování certifikátů:

#!/bin/bash
 
IP="192.168.1.22"
SUBJECT_CA="/C=CZ/ST=Brno/L=Brno/O=majordomus/OU=CA/CN=$IP"
SUBJECT_SERVER="/C=CZ/ST=Brno/L=Brno/O=majordomus/OU=Server/CN=$IP"
SUBJECT_CLIENT="/C=CZ/ST=Brno/L=Brno/O=majordomus/OU=Client/CN=$IP"
 
function generate_CA () {
   echo "$SUBJECT_CA"
   openssl req -x509 -nodes -sha256 -newkey rsa:2048 -subj "$SUBJECT_CA"  -days 365 -keyout ca.key -out ca.crt
}
 
function generate_server () {
   echo "$SUBJECT_SERVER"
   openssl req -nodes -sha256 -new -subj "$SUBJECT_SERVER" -keyout server.key -out server.csr
   openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
}
 
function generate_client () {
   echo "$SUBJECT_CLIENT"
   openssl req -new -nodes -sha256 -subj "$SUBJECT_CLIENT" -out client.csr -keyout client.key 
   openssl x509 -req -sha256 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
}
 
 
function generate_der () {
   echo "generate DER certificates for ESP8266"
   openssl x509 -in client.crt -out cert.der -outform DER
   openssl rsa -in client.key -out key.der -outform DER
}
 
function generate_server_pem () {
   echo "generate PEM certificates for Node RED"
   openssl x509 -in server.crt -out server-cert.pem
   openssl rsa -in server.key -out server-key.pem
}
 
 
generate_CA
generate_server
generate_client
generate_der
generate_server_pem

Kód jsem si trochu upravil. Určitě je potřeba tam dát IP adresu zařízení serveru a dále jsem změnil to, že certifikáty se vygenerují s platností na delší dobu než 365 dní.

Dále jsem přidal kód pro vygenerování DER certifikátů serveru kvůli ESP8266. V diskusi jsem se dočetl, že DER je binární formát a ten právě potřebuje ESP8266.

V dalším kroku jsem nahrál soubory ca.crt, server.crt a server.key do konfigurační složky mosquitto a nastavil konfigurační soubor:

cafile /mosquitto/config/ca.crt
certfile /mosquitto/config/server.crt
keyfile /mosquitto/config/server.key

require_certificate true
#use_identity_as_username true

Parametr use_identity_as_username jsem zakomentoval. Pokud by byl aktivní, tak by nebylo potřeba používat přihlašovací jméno a heslo. Stačil by pouze klientský certifikát. Ale takové použití mi nevyhovuje a nevím, jestli by to nedělalo s ESP8266 problém, když klientský certifikát nevyužívá.

Jako poslední jsem upravil port, na kterém mosquitto běží, protože zabezpečené připojení se očekává na portu 8883.

listener 8883

V dalším kroku jsem ještě editoval docker-compose.yml a změnil port pro mosquitto také:

   ports:
   - "8883:8883"
docker-compose up -d

Pro otestování zabezpečeného připojení mi pomohl tento návod.

mosquitto_sub -h 192.168.1.22 -u 'majordomus' --pw 'supertajneheslo' -t 'dum/pracovna/vlhkost' -p 8883 -d --cafile ca.crt --cert client.crt --key client.key
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: dum/pracovna/vlhkost, QoS: 0, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 0

ESP8266, microPython a Mosquito přes SSL

Po dlouhém bádání jsem se dopracoval k tomu, že je potřeba certifikát v binárním formátu DER. Nainstaloval jsem si mpfshell a nahrál do ESP8266 vygenerované certifikáty cert.der a key.der. Ještě je dobré si uvědomit, že by nemělo být připojeno nic jiného k portu s ESP8266, jinak to nebude fungovat.

sudo pip3 install mpfshell
mpfshell -c "open ttyUSB0"
ls
put cert.der
put key.der
ls

Pak jsem musel upravid kód v microPythonu, aby načetl certifikáty a použil je při autentizaci.

with open("key.der", 'rb') as f:
            key = f.read()
 
with open("cert.der", 'rb') as f:
            cert = f.read()
 
 
ssl_params = dict()
ssl_params["cert"] = cert
ssl_params["key"] = key
 
 
mqttc = MQTTClient(CLIENT_NAME, BROKER_ADDR, 8883, USER, PASSWORD, ssl=True, ssl_params=ssl_params, keepalive=60)
 

zdroje, ze kterých jsem čerpal:

  • it/iot/mosquitto.txt
  • Poslední úprava: 2023/02/12 09:49
  • autor: Petr Nosek