Instalaci Mosquitto jsem provedl skrz Docker. Tady je docker-compose.yml:
version: '3.6' networks: default: driver: bridge ipam: driver: default nextcloud: driver: bridge internal: true ipam: driver: default services: mosquitto: container_name: mosquitto build: context: ./.templates/mosquitto/. args: - MOSQUITTO_BASE=eclipse-mosquitto:latest restart: unless-stopped environment: - TZ=${TZ:-Etc/UTC} ports: - "8883:8883" volumes: - ./volumes/mosquitto/config:/mosquitto/config - ./volumes/mosquitto/data:/mosquitto/data - ./volumes/mosquitto/log:/mosquitto/log - ./volumes/mosquitto/pwfile:/mosquitto/pwfile
Warning
V rámci instalace řeším rovnou SSL certifikáty a tomu odpovídá i porty v docker-compose.yml. Pokud bych chtěl nainstalovat verzi bez SSL, tak volím porty 1883:1883.
Protože budu Mosquitto provozovat pouze v domácí síti, budu potřebovat self signed certifikát. Podrobnosti jsem rozepsal zde, nicméně omezím se nyní na postup pouze pro náš účel.
K vytvoření nezbytných certifikátů pomůže tento skript, ve kterém je potřeba změnit IP adresu na IP adresu zařízení, na kterém MQTT server Mosquitto poběží.
#!/bin/bash IP="192.168.1.22" COUNTRY="CZ" STATE="Brno" LOCALITY="Brno" ORG="majordomus" SUBJECT_BASE="/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG" SUBJECT_CA="$SUBJECT_BASE/OU=CA/CN=$IP" SUBJECT_SERVER="$SUBJECT_BASE/OU=Server/CN=$IP" SUBJECT_CLIENT="$SUBJECT_BASE/OU=Client/CN=$IP" # Vytvořte konfigurační soubor san.cnf pro zahrnutí SAN cat > san.cnf <<EOF [ req ] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = $COUNTRY stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = $STATE localityName = Locality Name (eg, city) localityName_default = $LOCALITY organizationName = Organization Name (eg, company) organizationName_default = $ORG commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = $IP [ req_ext ] subjectAltName = @alt_names [ alt_names ] IP.1 = $IP EOF function generate_CA () { echo "$SUBJECT_CA" openssl req -x509 -nodes -sha256 -newkey rsa:2048 -subj "$SUBJECT_CA" -days 3650 -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 -config san.cnf openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -extensions req_ext -extfile san.cnf } 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 } generate_CA generate_server
Platnost certifikátu jsem raději nastavil na 10 let. Po spuštění kódu budu mít ve více souborů. Nicméně pro MQTT server Mosquitto budu potřebovat:
Pro klienta (aby se připojil k MQTT serveru) mi bude stačit soubor:
Podle docker file je konfigurační soubor umístěn v cestě ./volumes/mosquitto/config
Do této složky nahrajeme tedy vygenerované certifikáty:
Dbejme zejména práva k těmto souborům. Nastavit stejně, jako má soubor mosquitto.conf. Mosquitto v Dockeru musí mít možnost certifikáty číst.
Ve složce je také umístěný konfigurační soubor mosquitto.conf. Ten upravíme, aby povolil SSL a bude vypadat takto:
listener 8883 # persistence enabled for remembering retain flag across restarts # persistence true persistence_location /mosquitto/data # logging options: # enable one of the following (stdout = less wear on SD cards but # logs do not persist across restarts) #log_dest file /mosquitto/log/mosquitto.log log_dest stdout log_timestamp_format %Y-%m-%dT%H:%M:%S #log_type all # password handling: # password_file commented-out allow_anonymous true = # open access # password_file commented-out allow_anonymous false = # no access # password_file activated allow_anonymous true = # passwords omitted is permitted but # passwords provided must match pwfile # password_file activated allow_anonymous false = # no access without passwords # passwords provided must match pwfile # password_file /mosquitto/pwfile/pwfile allow_anonymous false # certificates cafile /mosquitto/config/ca.crt certfile /mosquitto/config/server.crt keyfile /mosquitto/config/server.key #require_certificate true # Uncomment to enable filters #acl_file /mosquitto/config/filter.acl
Změna portu, na kterém Mosquitto běží:
listener 8883
Zapnutí souboru, ve kterém budou přihlašovací jména a hesla (vygenerujeme později) a zakázání anonymního připojení.
password_file /mosquitto/pwfile/pwfile allow_anonymous false
Nastavení cest k certifikátům (cesta reflektuje, že Mosquitto poběží v Dockeru):
cafile /mosquitto/config/ca.crt certfile /mosquitto/config/server.crt keyfile /mosquitto/config/server.key
Nebudeme vyžadovat, aby se klient přihlašoval svým certifikátem - museli bychom totiž vygenerovat ještě certifikáty pro klienty a zároveň bychom mohli vypnout přihlašování jménem a heslem. Takže tuto položku mějme zakomentovanou nebo nastavenou na false.
#require_certificate true
Připojíme do kontejneru s Mosquitto a vytvořím uživatele s heslem:
docker exec -it mosquitto sh mosquitto_passwd -c /mosquitto/pwfile/pwfile majordomus
Pokud vše proběhlo správně, tak takto se připojíme na nějaký topic:
mosquitto_sub -u majordomus --pw 'passw0rd' -h 192.168.1.22 -p 8883 -v -t majordomus/detskypokojRS/ --cafile ca.crt
pro zapisování:
mosquitto_pub -u majordomus --pw 'passw0rd' -h 192.168.1.22 -p 8883 -v -t majordomus/detskypokojRS/ --cafile ca.crt