MQ Telemetry Transport (MQTT) je jednoduchý centralizovaný protokol sloužící zpravidla pro použití s nejrůznějšími senzory. Lze jej však využít i pro přenos mnoha jiných, zejména telemetrických dat. Protokol byl vyvíjen společností IBM v devadesátých letech minulého století. Od té doby se využívá pro sběr a distribuci dat v malých i velkých infrastrukturách. Základem je systém typu zveřejnit/odebírat (publish/subscribe). Zařízení s funkcí zveřejnit odesílají zprávy zprostředkovateli (broker), který na základě přihlášených odběrů provede třídění a přeposlání správným uživatelům. Předávání je pouze jednosměrné (potvrzované), lze však využít QoS. Tento protokol byl vyvíjen pro použití v ekosystému M2M, nicméně dnes je stejně vhodné jej použít i pro IoT a WoT. Od počátku byl protokol koncipován pro sítě TCP/IP. V současnosti, díky rozvoji nových technologií, je možné nalézt např. implementaci MQTT-SN (MQTT for Sensor Networks), kterou je možné využít i v jiných typech sítí a přenosových soustavách. Důležitým předpokladem je přenos dat v blocích, nelze tedy použít datový proud (streamování). Touto novou technologií může být ZigBee, ale i běžné SMS, atp.
Témata (topics)
Zprávy jsou zveřejňovány pod tématy (topic), které mají hierarchickou strukturu, a můžeme si je nezávisle definovat. Jednotlivé úrovně hierarchie jsou oddělovány znakem „/“. Příkladem může být téma obsahující informaci o venkovní teplotě:
senzory/venku/jih/teplota 24,3 °C
Při identifikaci tématu je možné použít zástupných znaků „+“ nebo „#“. Znak „+“ slouží jako zástupný pro celou jednu úroveň, např. senzory/+/+/teplota slouží pro odebírání dat ze všech teplotních senzorů. Znak „#“ lze využít jako zástupný znak pro všechny následující úrovně, tedy senzory/venku/# zaregistruje k odebírání všech dat z venkovních senzorů. Nelze jej však, na rozdíl od znaku „+“, umístit uprostřed téma.
Název tématu si můžeme volitelně volit, měli bychom ale používat znakovou sadu ASCII. Předejdeme tím mnoha potížím. Jediné téma, které je rezervované systémem je $SYS
. To obsahuje informace o běhu brokera.
Pří odesílání zpráv se kromě tématu uplatňuje jaké atribut QoS. MQTT má vlastní systém řízení kvality služby. Ten je založen na definování úrovní úspěšného doručení zprávy od klienta k brokerovi a dále od brokera k příjemci. Pokud má hodnotu 0, není úspěšné doručení požadováno, případně může být doručeno duplicitně. V případě hodnot 1 (vždy doručeno s možnou duplicitou) a 2 (vždy doručeno bez duplicit) je úspěšné doručení požadováno a v případě problémů může zpráva zůstat na brokeru.
Infrastruktura
Základem pro použití protokolu MQTT je kromě senzorů/jiných zdrojů dat a „spotřebitele“ také zařízení/aplikace, která se stará o řízení distribuce těchto dat. Jedná se o zprostředkovatele – broker. Broker je softwarová aplikace, která řídí autentizaci a autorizaci klientů, obsahuje kryptografické funkce pro zajištění ochrany obsahu před neoprávněným odposlechem a manipulací, a jak bylo uvedeno, distribuuje data na základě přihlášení k odběru jednotlivých témat. Kromě těchto základních funkcí umožňuje komunikaci s dalšími brokery, díky čemuž můžeme vytvářet složitější infrastrukturu.
Pokud se podíváme na klienty, kteří mohou spolupracovat s brokerem, existuje mnoho MQTT knihoven pro různé programovací jazyky. Mezi ty základní patří C, Perl, Python, Ruby, Java, Go, JavaScript, .NET, atd. Pro MQTT je zásadě důležitý pouze TCP/IP stack. Pro zařízení bez TCP/IP můžeme použít implementaci MQTT-SN, která ale na straně brokera vyžaduje modul MQTT-SN Gateway, který zprostředkovává komunikaci mezi oběma rozhraními.
Přihlášení klienta – autentizace a autorizace
Důležitým aspektem při příjmu, zpracování a odesílání dat je bezpečnost. Samozřejmě protokol MQTT umožňuje práci bez ověřování klientů a šifrování dat, ale pokud chceme zabezpečit jejich obsah, máme na výběr řadu možností.
Každá komunikace mezi klientem a brokerem začíná přihlášením klienta (CONNECT
). V přihlašovací sekvenci nás zajímá zejména identifikace klienta (ClientID
), uživatelské jméno (Username
– volitelné), heslo (Password
– volitelné). MQTT podporuje, díky podpoře SSL/TLS, také přihlášení pomocí klientského SSL certifikátu. Je důležité si uvědomit, že protokol MQTT je čistě textový, a proto bez použití SSL/TLS bude komunikace nešifrovaná (nebezpečí se týká hlavně přenášeného hesla). Jistou možností je využití vlastních klíčů (pre shared key – PSK), které slouží pro zašifrování komunikace jednotlivých klientů na základě jejich identit.
Pokud nám to dovolí možnosti našeho klienta, nastavíme ClientID na jednoduchý řetězec co nejlépe jej identifikující. V opačném případě (např. různé Arduino senzory) využíváme při programování firmware např. řetězec skládající se z části sériového čísla a našeho vlastního textového identifikátoru. ClientID se hodí např. právě pro PSK.
Na rozdíl od ClientID, jméno uživatele slouží pro nastavení přístupových oprávnění (access control list – ACL) k jednotlivým tématům. V příslušné konfiguraci brokera můžeme nalézt také volby pro řízení zpráv od/pro anonymní uživatele (v případě, že jsme při přihlašování nepoužili atribut Username).
Mezi další atributy využitelnými při přihlašování jsou:
Clean Session
– určuje, zda má být navázané spojení mezi klientem a brokerem trvalé. V případě nastavení na false
, budou všechny zprávy s QoS 1 a 2, které nebyly úspěšně doručeny od brokera klientovi, uloženy a po dalším navázání spojení předány. Pokud je nastaveno na true
, broker žádné zprávy pro klienta neukládá.
Last Will
– jedná se o trojici volitelných atributů Last Will Topic
, Last Will QoS
a Last Will Message
, které definují téma, zprávu a související QoS (1 nebo 2) pro případ, že dojde k neočekávanému odpojení klienta. To může být z důsledku poruchy sítě, problémy na brokeru nebo při vypršení doby nastavené atributem Keep Alive
. Pokud se taková situace stane, na brokeru se objeví definovaná zpráva. Tato vlastnost se často využívá pro zobrazení stavu klienta. Při přihlášení se použije např. téma zarizeni/venku/cidlo_teploty/stav
a zpráva offline
. Ihned se pošle nová zpráva online
s QoS 0. Pokud je klient násilně odpojen, zobrazí se automaticky zpráva offline
. V případě úspěšného odpojení pomocí paketu DISCONNECT
je díky nastavení QoS aktuální zprávy online
na 0 toto téma z brokera odstraněno. Jak bylo uvedeno, Last Will
se použije pouze v případě násilného odpojení. Pokud ale chceme zanechat stav i po úspěšném odpojení, před jeho provedením nastavíme zprávu např. na Disconnected
s QoS 1 nebo 2.
Keep Alive
– definuje časový interval, kdy si klient a broker vymění informaci o svém stavu pomocí paketů PINGREQ
a PINGRESP
.
Zveřejňování zpráv – publish
Pokud je klient úspěšně připojen k brokeru, může začít odesílat zprávy. Každá zpráva musí obsahovat název tématu, definici QoS (0 – 2), vlastní obsah zprávy a příznak uchování Retain Flag
. Ten se používá v případě, že chceme na brokeru ponechat poslední zprávu pro nově připojené klienty. Zprávy jsou dle objednaných témat odesílány až po jejich opětovném příjmu brokerem. V tomto případě nový klient dostane právě tu aktuálně poslední.
MQTT je protokolem textovým. Zveřejňovat lze ale i např. obrázky a jiná binární data. Jen musí být převedeny/zakódovány do textového formátu (např. pomocí Base64). Maximální velikost zprávy je 268 435 455 bytů (~ 256 MB).
Odebírání zpráv – subscribe
Každý odběr tématu musí být na brokeru správně zaregistrován. Při registraci je možné využít obou, již popsaných, zástupných znaků. V případě, že chceme u některých témat nastavit vlastní QoS, můžeme tak učinit. Broker následně bere v úvahu nastavení vyšší priority.
Po úspěšné registraci jednoho nebo více téma je, na základě nastavení QoS a případném nalezení v paměti brokera, přes funkci zveřejnění (subscribe) zaslán obsah klientovi.
Podobným způsobem, jakým probíhá objednávání, funguje i odhlašování témat.
Broker na IoT bráně
Pokud chceme používat protokol MQTT na IoT bráně (např. Rasberry Pi) máme na výběr různé implementace. Já si vybral open source projekt Mosquitto. Ten zahrnuje vlastní broker a klienty pro zveřejňování i odběr témat. S Mosquitto lze provozovat MQTT prakticky bez konfigurace, pouze s výchozím nastavením. Pokud ale chceme sofistikovanější funkce, kterými jsou přihlašování pomocí certifikátů nebo řízení přístupu k tématům, je nastavení příslušných voleb jednoduchou záležitostí.
Chceme-li využít MQTT brokera např. s programovacím jazykem Python, nabízí se klientská knihovna Eclipse Paho MQTT.
Pravděpodobně budeme chtít vytvořit nějakou jednoduchou internetovou stránku, která bude zobrazovat aktuální stav veškerých dostupných senzorů. K tomu zde máme technologii Websockets.
Příklad použití MQTT
Pokud opominu přenos telemetrie ze senzorů, lze MQTT použít pro jakýkoliv přenos informací. Příkladem může být monitorování běhu nějakého procesu. V mém případě výpis seznamu adresářů a souborů na souborovém systému.
Na počítači spustím program mosquitto_sub
, kde definuji server s brokerem a téma, které mne zajímá („#“; mohu i konkrétně „devices/ntb/ls“):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
[user@pc-2 ~]$ mosquitto_sub -h mqtt-broker.my-own-domain.net -t "#" /: celkem 76 lrwxrwxrwx 1 root root 7 5. říj 21.06 bin -> usr/bin drwxr-xr-x 4 root root 16384 10. říj 20.04 boot drwxr-xr-x 16 root root 3580 5. říj 11.46 dev drwxr-xr-x 72 root root 4096 11. říj 18.25 etc drwxr-xr-x 6 hts video 4096 19. bře 2015 home lrwxrwxrwx 1 root root 7 5. říj 21.06 lib -> usr/lib drwx------ 2 root root 16384 14. lis 2013 lost+found drwxr-xr-x 2 root root 4096 4. čen 2013 mnt drwxr-xr-x 2 root root 4096 1. čec 14.44 net drwxr-xr-x 5 root root 4096 21. úno 2015 opt dr-xr-xr-x 155 root root 0 1. led 1970 proc drwxr-x--- 12 root root 4096 11. říj 18.24 root drwxr-xr-x 21 root root 920 11. říj 22.53 run lrwxrwxrwx 1 root root 7 5. říj 21.06 sbin -> usr/bin drwxr-xr-x 3 root root 4096 7. bře 2015 srv dr-xr-xr-x 11 root root 0 10. říj 19.10 sys drwxrwxrwt 14 root root 4096 12. říj 03.45 tmp drwxr-xr-x 7 root root 4096 9. říj 21.22 usr drwxr-xr-x 14 root root 4096 9. říj 21.22 var /boot: celkem 30450 -rwxr-xr-x 1 root root 9846 10. říj 16.36 bcm2708-rpi-b.dtb -rwxr-xr-x 1 root root 10125 10. říj 16.36 bcm2708-rpi-b-plus.dtb -rwxr-xr-x 1 root root 9850 10. říj 16.36 bcm2708-rpi-cm.dtb -rwxr-xr-x 1 root root 17900 10. říj 16.07 bootcode.bin -rwxr-xr-x 1 root root 294 7. říj 12.19 cmdline.txt -rwxr-xr-x 1 root root 6819 23. srp 12.48 config.txt -rwxr-xr-x 1 root root 4449 22. dub 05.55 config.txt.pacnew -rwxr-xr-x 1 root root 2441 10. říj 16.07 fixup_cd.dat … |
Nyní na notebooku spustím mosquitto_sub
:
1 |
[user@ntb-1 /]$ ls -lR / | mosquitto_pub -h mqtt-broker.my-own-domain.net -t devices/ntb/ls -l |
Na prvním počítači mohu vidět „přesměrovaný“ výstup. Samozřejmě mohu použít např. SSH, netcat, ale zde opticky vidíme i rychlost přenosu jednotlivých zpráv. Co řádek (parametr -l
), to nová zpráva pro definované téma.
Lze použít při kompilaci, komprimaci souborů, monitoringu pomocí příkazu ping, atp. Jen bych tím asi nezálohoval.
Stav brokera (téma $SYS/#
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
[mqtt@linux ~]# mosquitto_sub -t "\$SYS/#" -v $SYS/broker/version mosquitto version 1.4.3 $SYS/broker/timestamp 2015-10-10 21:06:50+0200 $SYS/broker/uptime 77 seconds $SYS/broker/clients/total 0 $SYS/broker/clients/inactive 0 $SYS/broker/clients/disconnected 0 $SYS/broker/clients/active 0 $SYS/broker/clients/connected 0 $SYS/broker/clients/expired 0 $SYS/broker/messages/stored 47 $SYS/broker/messages/received 23413 $SYS/broker/messages/sent 5814 $SYS/broker/subscriptions/count 0 $SYS/broker/retained messages/count 47 $SYS/broker/heap/current 8784 $SYS/broker/heap/maximum 11736 $SYS/broker/publish/messages/dropped 0 $SYS/broker/publish/messages/received 23403 $SYS/broker/publish/messages/sent 5804 $SYS/broker/publish/bytes/received 1552108 $SYS/broker/publish/bytes/sent 389385 $SYS/broker/bytes/received 2021675 $SYS/broker/bytes/sent 507787 $SYS/broker/load/messages/received/1min 12490.86 $SYS/broker/load/messages/received/5min 4088.72 $SYS/broker/load/messages/received/15min 1491.05 $SYS/broker/load/messages/sent/1min 4066.80 $SYS/broker/load/messages/sent/5min 1081.31 $SYS/broker/load/messages/sent/15min 378.30 $SYS/broker/load/publish/sent/1min 4061.53 $SYS/broker/load/publish/sent/5min 1079.56 $SYS/broker/load/publish/sent/15min 377.66 $SYS/broker/load/publish/received/1min 12485.59 $SYS/broker/load/publish/received/5min 4086.98 $SYS/broker/load/publish/received/15min 1490.41 $SYS/broker/load/bytes/received/1min 1079426.35 $SYS/broker/load/bytes/received/5min 353130.20 $SYS/broker/load/bytes/received/15min 128759.36 $SYS/broker/load/bytes/sent/1min 355297.36 $SYS/broker/load/bytes/sent/5min 94461.90 $SYS/broker/load/bytes/sent/15min 33043.07 $SYS/broker/load/sockets/1min 3.14 $SYS/broker/load/sockets/5min 1.04 $SYS/broker/load/sockets/15min 0.39 $SYS/broker/load/connections/1min 3.14 $SYS/broker/load/connections/5min 1.04 $SYS/broker/load/connections/15min 0.39 … |
Doplnění
MQTT lze využít pouze pro jednosměrný přenos zpráv. Pokud hledáme protokol využitelný pro konfiguraci zařízení, který bude paměťově nenáročný, nabízí se CoAP (Constrained Application Protocol) skupiny IETF. Ten je podobný HTTP, ale pro činnost nepoužívá TCP, ale UDP. Proto jej nelze provozovat společně s SSL/TLS ale s DTLS (Datagram Transport Layer Security).
Související
Nastavení Mosquitto MQTT brokera s reverzním proxy serverem NGINX
Pingback: Návrh a stavba HTPC | brichacek.net
Pingback: Nastavení Mosquitto MQTT brokera s reverzním proxy serverem NGINX | brichacek.net
MQTT samozrejme lze pouzit obousmerne – staci 2 aplikace a 1 MQTT broker – konkretnim prikladem muze byt napr. implementace zigbee2mqtt.io, ktery obsahuje 3 komponenty – back-end(+konvertory) a front-end (WebUI) – back-end a front-end spolu nekomunikuji naprimo, ale prostrednictivm MQTT zprav zasilanych skrze MQTT brokera (v obvyklych nasazenich v teto pozici Mosquitto).