Upravljanje ESP8266 bez preusmjeravanja porta: izlazna MQTT staza
Broker dostupan s interneta omogućava da se kućni uređaj kontroliše preko veze koju je sam otvorio. Šta to mijenja za TLS memoriju, teme i ponavljanje.
Uređaj stoji iza kućnog rutera bez preusmjeravanja porta i bez javne adrese, a ipak mora primiti konfiguraciju u roku od nekoliko sekundi. Trik nije rupa u firewallu. To je veza koju uređaj otvara prema van ka brokeru do kojeg može doći, a koji zatim vraća poruke natrag istim uspostavljenim putem. Svako svojstvo koje ljudi vole u ovom dizajnu, i svaka zamka u njemu, dolazi iz tog preokreta.
Šta zapravo prolazi kroz NAT
Kada uređaj otvori TCP vezu ka brokeru, kućni ruter stvara mapiranje i održava ga živim dok tok postoji. Odgovori na tom toku vraćaju se uređaju jer mapiranje već postoji. Broker nikada ne inicira ništa prema kući, pa nema neželjenog dolaznog paketa koji bi ruter odbio. To je cijeli mrežni argument i zato ovaj pristup radi na mrežama koje ne kontrolišete.
Uređaj mora održavati vezu živom ili je ponovo uspostavljati, što postaje pitanje pouzdanosti kada se arhitektura ustali.
Broker usmjerava teme, ne proxy-uje HTTP
MQTT definiše razmjene objavljivanja i pretplate: uređaj se pretplaćuje na filter tema koji smije čitati, a ovlašteni kontroler objavljuje na odgovarajuću temu. Broker uparuje objave sa pretplatama i dostavlja kopije. On ne zna šta je zahtjev preglednika i neće proslijediti HTTP GET web serveru uređaja. Ako postojeći firmware govori samo HTTP, dizajn s brokerom zahtijeva promjenu aplikacije ili namjernu komponentu za prevođenje.
Imena tema također nisu autorizacija. Većina brokera podržava liste kontrole pristupa po klijentu, a uređaje treba ograničiti na njihova vlastita stabla objavljivanja i pretplate umjesto da dijele jedan globalni prostor imena.
Resursi uređaja određuju oblik TLS-a
ESP8266 ima ograničen RAM, a TLS rukovanje je najskuplja stvar koju radi. Arduino jezgro isporučuje BearSSL upravo zbog tog ograničenja, a izbor između provjere CA i prikivanja otiska mijenja i memorijski otisak i ono što napadač s važećim certifikatom za drugo ime može učiniti. Provjera brokerovog CA jača je opcija kada heap to dopušta. Veličina korisnog tereta je također važna: MQTT klijent drži bafer, a poruke veće od njega se tiho odsijecaju osim ako se bafer namjerno poveća.
Keepalive i socket timeouti dio su istog budžeta, jer klijent koji nikada ne primijeti mrtvu vezu prestaje primati komande bez prijave greške.
Semantika poruka koja grize
Zadržanu poruku broker pohranjuje i dostavlja kasnijim odgovarajućim pretplatnicima, što je odlično za trenutno stanje i opasno za jednokratne komande: uređaj koji se ponovo poveže može primiti jučerašnju komandu kao da je nova. QoS 1 garantuje dostavu najmanje jednom, pa su duplikati normalni i aplikacija mora biti sigurna za ponavljanje, idealno s identifikatorom ili vremenskom oznakom koju može odbiti. Posljednja volja daje vam statusni signal kada uređaj padne, ali samo ako veza zaista padne, a ne visi.
Ponašanje čiste sesije odlučuje da li broker zadržava vaše pretplate dok vas nema, a greška u tome je razlog zašto neki uređaji propuštaju prvu poruku nakon svakog ponovnog povezivanja.
TLS štiti dio puta do brokera. To nije end-to-end enkripcija korisnog tereta protiv operatera brokera, koji može čitati sve što objavite kroz njega.
Ograničite životni ciklus i testirajte ga bezopasnim podacima
Planirajte ponovno povezivanje s odustajanjem umjesto tijesne petlje ponovnih pokušaja, pretplatite se izričito ako sesija nije trajna i bilježite rezultat povezivanja da bi tihi offline uređaj ostavio dokaz. Testirajte put ponovnog povezivanja primjerima korisnog tereta koji ništa ne rade, jer prvi proizvodni test kanala komandi ne smije biti stvarna komanda. Zatim potvrdite šta zastarjela zadržana poruka radi pri ponovnom povezivanju i odlučite je li takvo ponašanje prihvatljivo za svaku temu.
Ovako napravljen, dizajn uklanja jedan dolazni mrežni zahtjev i ostavlja softver uređaja, politiku brokera i semantiku poruka kao vidljiv posao umjesto skrivenih pretpostavki.