V prvním a druhém dílu seriálu o MQTT jsem používal veřejný MQTT broker. To se hodí pro demo, ale produkční systém na tom stavět nechcete. Pokud pro svůj MQTT server nechcete používat hostované řešení, můžete si rozjet vlastní server. Asi nejpoužívanějším softwarem pro tento účel je Mosquitto. Je to open source multiplatformní projekt, který funguje na Windows, Linuxu i Mac OS. Ukážu vám, jak Mosquitto nainstalovat na Linux, nastavit na něm TLS zabezpečení a WebSockets rozhraní.

Následující postup funguje na aktuálním Ubuntu a Raspberry Pi OS. Měl by přiměřeně fungovat i na ostatních distribucích.

Instalace

1.

Ve většině distribucí Linuxu je Mosquitto součástí standardních repozitářů. Mělo by tedy stačit nainstalovat balíčky mosquitto a mosquitto-clients:

sudo apt-get install mosquitto mosquitto-clients -y

Pokud výše uvedený příkaz skončí chybou, postupujte podle návodu pro vaši distribuci na webu mosquitto.org.

2.

Mosquitto nyní běží s výchozími nastaveními. Máte k dispozici utility mosquitto_pub a mosquitto_sub, které slouží jako publisher a subscriber.

Následujícím příkazem spusťte subcriber tak, že bude naslouchat na topicu test:

mosquitto_sub -h localhost -t test &
3.

Znak & na konci příkazu znamená, že proces má běžet na pozadí a tedy nemá blokovat interaktivní konzoli. Příkaz vypsal něco jako:

[1] 12345

To druhé číslo (zde 12345) je PID, číselný identifikátor procesu. Poznamenejte si ho, budete ho později potřebovat k jeho ukončení.

Seznam svých běžících procesů si můžete vypsat pomocí příkazu ps. Měli byste vidět něco jako:

PID   TTY          TIME CMD
12100 pts/0    00:00:00 bash
12345 pts/0    00:00:00 mosquitto_sub
12347 pts/0    00:00:00 ps
4.

Následujícím příkazem pošlete pomocí publishera zprávu Hello, world! do topicu test:

mosquitto_pub -h localhost -t test -m "Hello, world!"
5.

Zpráva bude vypsána na konzoli. Vypsal ji tam proces mosquitto_sub.

6.

Pomocí kill můžete ukončit subscribera běžícího na pozadí. Použijte k tomu PID zjištěné v kroku 3.

kill 12345
7.

Pomocí ps si můžete ověřit, že proces subscribera neběží.

Nastavení firewallu

MQTT obvykle využívá následující porty:

8.

V tomto návodu budeme pracovat s porty 1883 (MQTT), 8883 (šifrované MQTTS), 8884 (MQTT over WebSockets). Zpřístupněte tyto porty na firewallu. Pomocí UFW tak můžete učinit následujícími příkazy:

sudo ufw allow 1883/tcp
sudo ufw allow 8883/tcp
sudo ufw allow 8884/tcp
sudo ufw reload

Nastavení TLS

Název serveru v příkladu je mqtt.ztech.cz. Upravte postup podle vašeho názvu serveru.

9.

Abyste mohli používat Mosquitto s TLS (ať už přímo nebo přes WebSockets), musíte mít certifikát vydané důvěryhodnou certifikační autoritou.

Pokud takový certifikát máte, musíte ho zpřístupnit Mosquittu, například tak, že vytvoříte následující soubory:

  • /etc/mosquitto/certs/cert.pem - vlastní certifikát,
  • /etc/mosquitto/certs/privkey.pem - privátní klíč k certifikátu,
  • /etc/mosquitto/certs/chain.pem - certifikát CA a mezilehlých autorit.

Následující postup předpokládá, že máte certifikáty získané od Let's Encrypt CA pomocí utility Certbot. Pokud máte certifikáty získané jinak, např. od vlastní CA, nakopírujte je na výše uvedené cesty a pokračujte krokem 16.

Zpřístupnění certifikátů získaných od Let's Encrypt

Pokud nemáte validní certifikát, můžete ho zdarma získat od Let's Encrypt certifikační autority. Pokud na stejném serveru běží web server a má veřejnou adresu, je to triviální. Pokud ne, můžete použít například postup popsaný v článku Získání certifikátů od Let’s Encrypt pomocí dns-01 challenge s Cloudflare.

Certbot certifikáty ve výchozím nastavení umístí do adresáře /etc/letsencrypt/live/ a nastaví práva tak, že k privátnímu klíči má přístup jenom root. Nicméně můžeme nastavit deploy hook, který vždy po získání nových certifikátů tyto nakopíruje do /etc/mosquitto/certs a dá práva uživateli mosquitto.

10.

Vytvořte soubor /usr/local/sbin/copy-to-mosquitto.sh, který bude obsahovat příkazy pro zkopírování souborů a nastavení práv:

sudo nano /usr/local/sbin/copy-to-mosquitto.sh
11.

Zadejte do souboru následující příkazy (místo mqtt.ztech.cz zadejte název vašeho certifikátu):

cp /etc/letsencrypt/live/mqtt.ztech.cz/cert.pem /etc/mosquitto/certs/
cp /etc/letsencrypt/live/mqtt.ztech.cz/privkey.pem /etc/mosquitto/certs/
cp /etc/letsencrypt/live/mqtt.ztech.cz/chain.pem /etc/mosquitto/certs/
chown mosquitto:mosquitto /etc/mosquitto/certs/*.pem
12.

Stiskem Ctrl+S uložte soubor a Ctrl+X ukončete editor.

13.

Následujícím příkazem nastavte soubor jako spustitelný:

sudo chmod +x /usr/local/sbin/copy-to-mosquitto.sh
14.

Následujícím příkazem (místo mqtt.ztech.cz zadejte název vašeho certifikátu) nastavíte, že se má po vydání nového certifikátu shora uvedený soubor spustit (a zároveň ho spustíte ihned):

sudo certbot reconfigure --cert-name mqtt.ztech.cz \
                         --deploy-hook "/usr/local/sbin/copy-to-mosquitto.sh" \
                         --run-deploy-hooks
15.

Následujícím příkazem si zkontrolujte, že vše v pořádku proběhlo:

sudo ls -la /etc/mosquitto/certs/

Měli byste vidět něco jako:

drwxr-xr-x 2 root      root      4096 Jun 28 21:41 .
drwxr-xr-x 5 root      root      4096 Jun 28 18:22 ..
-rw-r-xr-- 1 mosquitto mosquitto 1302 Jun 28 21:41 cert.pem
-rw-r-xr-- 1 mosquitto mosquitto 1566 Jun 28 21:41 chain.pem
-rw-r-x--- 1 mosquitto mosquitto  241 Jun 28 21:41 privkey.pem
-rw-r--r-- 1 root      root       130 Sep 30  2023 README

Konfigurace Mosquitta

16.

Následujícím příkazem vytvořte konfigurační soubor Mosquitta:

sudo nano /etc/mosquitto/conf.d/default.conf

Soubor se může jmenovat jakkoliv, ale musí být umístěn v adresáři /etc/mosquitto/conf.d/ a mít příponu .conf.

17.

Zadejte do něj následující obsah (upravte cestu k certifikátům a privátnímu klíči dle potřeby). Za textem v posledním řádku (keyfile...) stiskněte Enter - musí tam být zalomení řádku. Pokud tomu tak není, bude ho Mosquitto ignorovat.

allow_anonymous true

# Non-secure listener
listener 1883

# TLS-enabled listener
listener 8883
certfile /etc/mosquitto/certs/cert.pem
cafile /etc/mosquitto/certs/chain.pem
keyfile /etc/mosquitto/certs/privkey.pem

Volba allow_anonymous true říká, že se na náš server může připojit kdokoliv a může cokoliv kamkoliv publikovat a číst. To obecně není dobrý nápad. Nastavení práv probereme v dalším pokračování tohoto seriálu.

18.

Stiskem Ctrl+S uložte soubor a Ctrl+X ukončete editor.

19.

Následujícím příkazem Mosquitto restartujete

sudo systemctl restart mosquitto
20.

Že vše funguje si můžete ověřit podobně jako v kroku 2. Místo mqtt.ztech.cz zadejte název vašeho serveru.

Příkaz pro spuštění subscribera na pozadí je:

mosquitto_sub -h mqtt.ztech.cz -p 8883 --capath /etc/ssl/certs \
              -t test &

Příkaz pro zaslání zprávy do topicu test je:

mosquitto_pub -h mqtt.ztech.cz -p 8883 --capath /etc/ssl/certs \
              -t test -m "Hello, world!"

Nastavení MQTT over WebSockets

Pokud chcete využívat MQTT přímo z prohlížeče, musí být MQTT server dostupný pomocí HTTPS a WebSockets.

21.

Následujícím příkazem otevřete k editaci konfigurační soubor Mosquitta:

sudo nano /etc/mosquitto/conf.d/default.conf
22.

Přidejte do něj následující konfiguraci (a nezapomeňte na prázdný řádek na konci souboru):

allow_anonymous true

# Non-secure listener
listener 1883

# TLS-enabled listener
listener 8883
certfile /etc/mosquitto/certs/cert.pem
cafile /etc/mosquitto/certs/chain.pem
keyfile /etc/mosquitto/certs/privkey.pem

# WebSockets+TLS listener
listener 8884
protocol websockets
certfile /etc/mosquitto/certs/cert.pem
cafile /etc/mosquitto/certs/chain.pem
keyfile /etc/mosquitto/certs/privkey.pem

23.

Stiskem Ctrl+S uložte soubor a Ctrl+X ukončete editor.

24.

Následujícím příkazem Mosquitto restartujte, aby se projevila změna konfigurace:

sudo systemctl restart mosquitto
25.

Že vše funguje přes WebSockets si můžete ověřit např. z webového klienta od HiveMQ.