====== 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)]]