====== Mosquitto ======
===== Jak funguje MQTT =====
V [[https://randomnerdtutorials.com/what-is-mqtt-and-how-it-works/|tutoriálu]] je srozumitelně popsané, jak MQTT funguje.
===== Podrobnější logování v Mosquitto =====
Do konfiguračního souboru lze [[https://iot.stackexchange.com/questions/956/how-to-enable-detailed-logging-of-mosquitto-broker-on-windows-7|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
===== Zabezpečení Mosquitto v Dockeru =====
==== Zapnutí autentizace ====
Vycházím z návodu [[https://www.homeautomationguy.io/docker-tips/configuring-the-mosquitto-mqtt-docker-container-for-use-with-home-assistant/|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: [[https://techsparx.com/software-development/mqtt/mosquitto-docker.html|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!'
==== Zapnutí komunikace přes SSL ====
Nejprve jsem postupoval podle návodu [[https://medium.com/himinds/mqtt-broker-with-secure-tls-and-docker-compose-708a6f483c92
|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 [[https://serverfault.com/questions/1006639/create-der-certificatekey-from-pem|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 [[https://medium.com/himinds/mqtt-broker-with-secure-tls-communication-on-ubuntu-18-04-lts-and-an-esp32-mqtt-client-5c25fd7afe67|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:
* https://github.com/peterhinch/micropython-mqtt/issues/10
* https://dev.to/bassparanoya/esp32-micropython-mqtt-tls-28fd
* https://forum.micropython.org/viewtopic.php?f=18&t=11906#p65746
* [[https://forum.pycom.io/topic/4775/solved-mqtt-and-tls|Solved mqtt and tls - ESP32]]
* [[https://microcontrollerslab.com/esp32-esp8266-micropython-mqtt-publish-subscribe-ds18b20-readings/|ESP32 ESP8266 MicroPython MQTT Publish Subscribe DS18B20 Readings]]
* [[https://randomnerdtutorials.com/micropython-mqtt-publish-ds18b10-esp32-esp8266/|MicroPython: MQTT – Publish DS18B20 Temperature Readings (ESP32/ESP8266)]]