urMQTT: olyan MQTT brókert építünk, amely egyben operációs rendszer is
Fejlesztési jegyzetek az urMQTT-ről, egy Rustban írt unikernelről, amely önmagában MQTT bróker: egyetlen ELF saját TCP/IP-vel, TLS 1.3-mal, brókerrel és SQLite-tal, egyetlen ISO-ról indítva.
A járművekben, a parkolókban és az elektronikai szekrényekben működő eszközökben van egy közös vonás: kis üzeneteket küldenek, ritkán, de sok van belőlük, és folyamatosan csatlakoznak. Évek óta MQTT brókerekhez kapcsoljuk őket, és évek óta ugyanaz a kérdés foglalkoztat bennünket. Miért kell egy ilyen egyszerű dologhoz egy egész Linux, OpenSSL, valamilyen nyelvi futtatókörnyezet, SSH, csomagkezelő, és csak azután maga a bróker? Ezen rétegek mindegyike hozza a maga sebezhetőségeit, fogyasztja a maga memóriáját, és még egy olyan dologgal bővíti a rendszert, ami elromolhat, miközben egy eszközflotta a szervertől mindössze hármat vár el: tartson fenn sok, szinte tétlen kapcsolatot, minden eszközt megbízhatóan hitelesítsen, és az üzeneteket veszteség nélkül továbbítsa.
Így született meg az urMQTT: egy unikernel, amely maga az MQTT bróker. A mag, a TCP/IP, a TLS 1.3, az MQTT és egy beágyazott adatbázis egyetlen Rust binárisban, amelyet egyetlen ISO-ról lehet elindítani. Nincsenek folyamatok, nincsenek rendszerhívások, nincs shell. Az első platform, amelyen épül és tesztelődik, az aarch64, ugyanez a kód pedig x86_64 felé is halad, UEFI-n és klasszikus BIOS-on keresztül, valamint valódi hardver felé: a cél egyetlen ISO, amely mindezeken elindul. A projekt nyílt forráskódú, MIT vagy Apache 2.0 licenc alatt, és ebben az írásban szeretnénk rögzíteni, hol tartunk, hogyan épül fel belülről, és mit tanultunk útközben.
Mit jelent pontosan az „unikernel"
Egy hagyományos bróker olyan program, amely egy operációs rendszeren fut. Az urMQTT alatt nincs operációs rendszer: maga indítja el magát az UEFI firmware-en és a Limine bootloaderen keresztül, beállítja a saját laptábláit, programozza a megszakításvezérlőt és az időzítőt, PCIe-n megkeresi a virtio eszközöket, DHCP-vel címet kap, és egyetlen porton hallgatózik. Mindaz, amit egyébként a kernel, az eszközmeghajtók, a hálózati verem és az alkalmazás végezne, itt egyetlen ELF, amely EL1 szinten fut.
Egy tipikus telepítéssel való összehasonlítás önmagáért beszél:
| Tipikus bróker Linuxon | urMQTT | |
|---|---|---|
| Kitett szolgáltatások | SSH, bróker, gyakran metrika- vagy adminisztrációs port is | csak a TCP 8883 (MQTT TLS 1.3-on, mTLS-sel) |
| Kód a képfájlban | kernel, userland, libc, OpenSSL, futtatókörnyezet | egyetlen Rust ELF (plusz a vendorolt SQLite) |
| Távoli felügyelet | shell, konfigurációs fájlok, csomagfrissítések | semmi. Az új verzió egy új ISO |
| Memória tétlen kapcsolatonként | kilobájtok (socketpufferek, TLS-objektumok, heap) | cél: ≤ 512 B |
| Többmagos modell | szálak és zárak, vagy egyetlen eseményciklus | szál magonként, megosztott állapot nélkül, végigvitt feldolgozás |
| Kódintegritás | lehetségesek egyszerre írható és végrehajtható leképezések | W^X, lezárt laptáblák, PAC/BTI |
A prioritásaink ebben a sorrendben: biztonság, skálázhatóság, többmagos teljesítmény, kis lábnyom és megváltoztathatatlan telepítés. Ha két cél ütközik, az nyer, amelyik ezen a listán feljebb áll.
Hol tartunk most
A projekt pre-alfa fázisban van, de tizenhét fejlesztési mérföldkő lezárult, M0-tól M17-ig. Az urMQTT ma MQTT 3.1.1-et szolgál ki TLS 1.3-on, kötelező klienstanúsítványokkal, az állapotát pedig SQLite-ban őrzi, nyers lemezen. Röviden, ez az, amit már tud:
- Mag: saját kivételvektorok dekódolt jelentésekkel, saját laptáblák érvényesített W^X-szel, őrlapok, PAC és BTI, ahol a processzor támogatja, GICv3 és GICv2, általános időzítő, SMP legfeljebb 64 maggal.
- Hardverfelismerés DTB-ből vagy ACPI-ból egyetlen platformleírásba, mindkét forrásból azonos eredménnyel.
- Eszközmeghajtók: PCIe ECAM, MSI-X, virtio-net, virtio-blk, virtio-scsi és virtio-rng, valamint hardveres entrópiával kezdeti értékkel ellátott CSPRNG.
- Hálózat: saját DHCPv4, ARP, ICMP és szigorú IPv4, majd saját, csak szerveroldali TCP: SYN-sütik, hierarchikus időzítőkerék, NewReno, ACK-ok összevonása, TIME_WAIT állapotok nélkül.
- TLS: csak TLS 1.3, kötelező mTLS, az eszközazonosító a CN-ből vagy a SAN URI-ból származik; a kézfogást a rustls végzi, utána saját rekordréteg következik AES-128-GCM-mel és ChaCha20-Poly1305-tel. Munkamenet-folytatás PSK-jegyekkel, visszavonási lista, már a kézfogásnál működő befogadás-vezérlés.
- MQTT: másolásmentes kodek, fuzzolva és valódi mosquitto kliensekkel tesztelve; QoS 0 és 1, helyettesítő karakterek, megőrzött üzenetek, végrendelet (LWT), tartós munkamenetek, a
devices/{id}/#mintára szűkített ACL, eszközönkénti sebességkorlátok. - Tárolás: SQLite a magon belül, nyers lemez feletti VFS-en keresztül, WAL módban, indításkor integritásellenőrzéssel; eszközregiszter, visszavonások, megőrzött üzenetek, tartós munkamenetek üzenetsorokkal az offline eszközök számára; magonként külön telemetriai napló rekordonkénti CRC-vel és összeomlás utáni helyreállítással.
- Üzemeltetés és felügyelet: watchdog időzítő a kezelőkhöz, állapotellenőrzés, korlátozott naplózás, syslog és statsd UDP-n, az újracsatlakozási viharokat átvészelő befogadás.
- Szállítás: CI-ben ellenőrzött, bitre azonos újraépítések, ISO és nyers GPT lemezkép, minisign aláírások, útmutatók KVM-hez, Proxmoxhoz és Hetznerhez.
Minden lépést az azt elhozó mérföldkő jelöl, a repóban lévő docs/PROGRESS.md fájl pedig az egyetlen igazságforrás arról, hogy mi működik valójában.
Az architektúra három képben
A teljes tervet a docs/ARCHITECTURE.md írja le, minden fontosabb döntés indoklása pedig ADR-ként található a docs/DECISIONS.md fájlban. Íme az áttekintés.
A rétegek
Fentről lefelé: a bróker (munkamenetek, témafa, QoS, megőrzött üzenetek, végrendeletek, ACL, korlátok), az MQTT kodek, a TLS, a TCP, a hálózati réteg, majd a meghajtók. E fő útvonal mellett áll a tárolás (SQLite és a telemetriai napló), mindez alatt pedig a memóriakezelés, a platformfelismerés és a build időben konstansokká fordított konfiguráció, a beágyazott CA-tanúsítvánnyal, a szervertanúsítvánnyal és a kulccsal együtt. Egyedül a virtio eszközökkel rendelkező hipervizor van a képen kívül.
Szál magonként, megosztott állapot nélkül
Minden adatmag saját ciklust forgat, saját TCP-veremmel, TLS-állapotokkal, a bróker egy szeletével (munkamenetek és témafa), heap-gyorsítótárral és telemetriai partícióval. A magok semmilyen módosítható állapotot nem osztanak meg, csak korlátos, zármentes gyűrűket, minden rendezett magpárhoz egyet. A legfelső mag az SQLite-ot futtatja, és semmi mást.
A hálózati kártyának ma egyetlen sorpárja van, amelyet a 0. mag tart kézben. Ez minden MQTT-folyamot a négyes Toeplitz-hash-e alapján az egyik munkamagra irányít, és elküldi mindazt, amit a munkamagok visszaadnak. A munkamenet a saját otthoni magján él, amelyet a kliensazonosító hash-e határoz meg, így az átvétel, a végrendeletek és a tartósság sosem lépi át a magok határát. Az a kapcsolat, amely egy másik magra érkezik, ott tartja a TCP- és TLS-állapotát, az egyszerű MQTT-t pedig kredit alapú forgalomszabályozással továbbítja az otthoni magnak. Minden irányított üzenet a bróker többi szeletére is szétterjed, amelyek mindegyike a megőrzött üzenetek egy replikáját tartja.
Három szabály tartja egyben ezt a modellt. Végigvitt feldolgozás: a beérkezett csomagot egyetlen mag teljes egészében feldolgozza, a TCP-től a helyben történő TLS-visszafejtésen, az MQTT-elemzésen és az útválasztáson át a titkosított válaszig, feladatsorok nélkül és az alkalmazási pufferekbe való másolás nélkül. Adaptív lekérdezés: terhelés alatt a vételi sorokat aktívan lekérdezzük, tétlenség esetén a mag visszatér a megszakításokhoz és a WFI-hez; a megszakításkezelők csak nyugtázzák a megszakítást és megjelölik a munkát. Watchdog időzítő: magonkénti 10 ms-os ütem elkapja azokat a kezelőket, amelyek túllépik a költségvetésüket.
Egy PUBLISH élete
Az eszköz elküld egy TLS-rekordot. A hálózati kártya leíróval, másolás nélkül átadja a mag ciklusának. A ciklus ellenőrzi a TCP-t, helyben visszafejti a TLS-t, és egy kölcsönzött pufferből elemzi az MQTT-t, majd a memóriában ellenőrzi az ACL-t, a sebességkorlátot és az útvonalat a témafán át. Ha egy másik magot érdekel az adott téma, útválasztási üzenetet kap a tartalomra mutató hivatkozással és a témaazonosítóval; az adatbázis telemetriai rekordot vagy megőrzött üzenet frissítést kap, kötegelve. A PUBACK válasz közvetlenül a kimenő pufferbe titkosítódik, és egyesül a TCP ACK-kal, így az eszköz felé egyetlen szegmens indul. A másik magnak az üzenet előfizetőnként egy titkosításba kerül a küldés pillanatában.
Mennyibe kerül egy kapcsolat
A cél legfeljebb 512 bájt tétlen TLS-kapcsolatonként, 256 felé törekedve. Amíg a kapcsolat nyugszik, semmit nem tartunk pufferben érte: a beérkezett adatokat közvetlenül a hálózati keretből dolgozzuk fel, a küldési, a rekord- és az MQTT-pufferek pedig csak addig léteznek, amíg valami befejezetlen vagy nyugtázatlan. A mag ezt maga is méri: pontos heapszámlálók kért bájtokban és a ténylegesen lefoglalt blokkokban, tíz másodpercenként rögzítve, nyitott kapcsolatonkénti, alapszint feletti heapként.
| Rész | Méret | Hogyan |
|---|---|---|
| TCP vezérlőblokk | 96 B | tömörített jelzőbitek, 16 bites RTT/RTO, rés az időzítőkerékben, tétlenségkor puffer nélkül |
| Rés a TCP-táblában | 4–8 B | csak a kapcsolatindex, a tábla legfeljebb félig tele |
| Kapcsolat és TLS 1.3 rekordállapot | 152 B | irányonkénti titok és sorszám (40 B); a kulcs és az IV rekordonként származtatódik |
| MQTT-kapcsolat | 48 B | az azonosító és a végrendelet csak addig van a heapen, amíg létezik |
| MQTT-munkamenet, forró alak | 64 B | egyetlen előfizetés sorban, internált csomópontazonosítók |
Előfizetés a devices/<id>/cmd/# témára |
0 facsomópont | a munkamenet-azonosítóhoz viszonyítva tárolva, minden eszközre közös |
Mérve HVF alatt, négy virtuális maggal, ebből három munkamag, ahol minden eszköz egy mTLS-kapcsolatot és egy QoS 1-es előfizetést tart, a foglaló kerekítésével együtt:
| Kapcsolatok | Bájt kapcsolatonként |
|---|---|
| 960 | 531 B |
| 9 922 | 494 B |
| 10 197 | 474 B |
A hálózati keretek készlete fixen körülbelül 2 MiB, ami tízezer kapcsolatnál nagyjából 200 B kapcsolatonként, egymillió kapcsolatnál nagyjából 2 B. Ennél többet nem tudtunk mérni: a QEMU felhasználói módú hálózata macOS-en 10 197 kapcsolatnál nem fogadott el több kapcsolatot, nagyjából a QEMU-folyamat 10 240 leírós határánál. A szám csökken, ahogy a fix részek több kapcsolatra oszlanak szét, így nem nő a kapcsolatok számával.
Biztonsági modell
A biztonság az első prioritás, és minden ütközést megnyer a többi céllal szemben. A modell több rétegből áll:
- Egyetlen port. TCP 8883, csak TLS 1.3, kötelező klienstanúsítványok, amelyeket a képfájlba ágyazott CA ír alá. Az MQTT-kliensazonosítónak meg kell egyeznie a tanúsítványban szereplő eszközazonosítóval.
- Nincs bejárat. Nincs shell, konzolbemenet, SSH, adminisztrációs API, dinamikus kód, hálózaton elérhető SQL, sem fájlrendszer.
- Memóriabiztonság. Rust, a protokollcsomagokban
forbid(unsafe_code)-dal; mindenunsafeblokkhoz// SAFETY:megjegyzés tartozik, amelyet egy lint ellenőriz, külső bemenetre pedig nincs pánik: a clippy az adatúton lévő csomagokban tiltja azunwrap,expect, indexelés éspanic!használatát. - Kihasználás elleni védelem. A W^X a leíró kódolásával és a
SCTLR_EL1.WXNbittel érvényesül, és minden indításkor felülvizsgálatra kerül. A laptáblák indítás után csak olvashatók, írható alias nélkül. A címtér alsó fele ki van zárva. Minden veremnek van őrlapja, a kivételek külön veremen futnak. A PAC és a BTI akkor kapcsol be, ha a processzor támogatja, és ezt füsttesztek ellenőrzik. - Visszaélésekkel szembeni ellenállás. SYN-sütik; a befogadás elutasítja az új kapcsolatokat, bármiféle kriptográfia előtt, ha kevés a heap, ha az adatbázis lemaradásban van, ha túl sok a folyamatban lévő kézfogás magonként vagy forráscímenként, vagy ha túl magas a kézfogások üteme. Eszközönkénti sebességkorlátok, korlátos sorok, a bróker ellennyomásához kötött TCP-ablak, korlátozott naplózás, watchdog időzítő és állapotellenőrzés.
- Megváltoztathatatlanság. A konfiguráció, a CA és a szerverkulcs a képfájlba van ágyazva. Bármi megváltoztatása új képfájlt jelent.
A fenyegetésmodell a docs/SECURITY.md fájlban található.
Tárolás fájlrendszer nélkül
Az adatok egy különálló lemezen élnek, virtio-blk vagy virtio-scsi eszközön, amelyen nincs fájlrendszer. Az elrendezés minimális és saját:
LBA 0 [ szuperblokk: varázsérték · elrendezés-verzió · uuid · régiótábla · CRC-32C ]
LBA 8, 16 [ fájlméret-tábla, A/B rések (a legújabb érvényes nyer) ]
LBA 64 [ SQLite főadatbázis ½ ][ SQLite WAL ⅛ ][ napló 1 MiB ][ telemetriai napló: 8 partíció … ]
utolsó 4 KiB [ terület a blokkeszköz indításkori önellenőrzéséhez ]
Az SQLite-ot (vendorolt 3.54.1, build közbeni ellenőrzőösszeg-vizsgálattal) clanggal fordítottuk a magba, szabványos könyvtár nélkül, és fix memsys5 heapet használ. A VFS-e három fix fájlt képez le lemezrégiókra. WAL módban fut locking_mode=EXCLUSIVE beállítással, így nincs szüksége megosztott memóriás indexre, valamint synchronous=FULL mellett; ha a quick_check indításkor hibát talál, a rendszer biztonságosan leáll. Az adatbázisban találhatók az eszközregiszter, a visszavonások, a megőrzött üzenetek és a tartós munkamenetek a nem csatlakozó eszközök QoS 1-es üzenetsoraival.
Az adatbázis magja, a legmagasabb sorszámú, az SQLite-ot futtatja és semmi mást. Az adatsík zármentes SPSC gyűrűn keresztül küldi neki az állapotváltozásokat; ő ezeket 5 ms-onként vagy 512 műveletenként egyetlen tranzakcióba gyűjti, a nyugtákat pedig egy másik gyűrűn adja vissza. Az üres lemezt az első indításkor formázza; minden mást soha nem formáz felül.
A telemetria más úton halad. Minden elfogadott PUBLISH a storage.telemetry_topics alatt felsorolt témákon a saját magja telemetriai naplójának partíciójába kerül: szegmensek gyűrűjébe, rekordonkénti CRC-vel, a szegmens sorszámával sózva, így a gyűrű régi köreinek tartalma soha nem bukkan fel újra. A magok a rekordokat saját gyűrűjükön, másolás nélkül adják át az adatbázis magjának, amely 5 ms-onként vagy 256 KiB-onként írja ki őket. Indításkor a helyreállítás minden kiírt rekordot megtart, levágja a befejezetlen farkat, és új szegmensben folytatja. A megőrzés méret szerint történik, a gyűrűn keresztül, és kor szerint, a retention_days beállításon keresztül. Ezt egymillió rekorddal és írás közben kiadott kill -9-cel ellenőriztük.
A számok
A tools/loadgen terhelésgenerátor három dolgot végez: mTLS-es és CONNECT-es TLS 1.3 kézfogási vihart, hosszú életű, PINGREQ-et küldő kapcsolatokat, amelyek másodpercenként telemetriát publikálnak, valamint újracsatlakozási viharokat. A make bench Apple M4 Pro gépen, HVF alatt a következőt adja:
| Munkamagok | kézfogás/s a vendégen belül | skálázás | QEMU felhasználói hálózaton át (kapcsolat/s) |
|---|---|---|---|
| 1 | 862 | 1,00× | 789 |
| 2 | 1 724 | 2,00× | 636 |
| 4 | 3 438 | 3,99× | 536 |
A vendégen belüli szám, ahol a kliens és a szerver ugyanabban a virtuális gépben van, és minden munkamag önállóan dolgozik, azt mutatja, hogy az adatsík lineárisan skálázódik. A hálózati számot a QEMU egyszálú felhasználói hálózata korlátozza, nem a vendég; ezt is rögzítettük, ADR-032 néven.
Az újracsatlakozási viharokat úgy teszteljük, hogy az összes eszköz egyszerre csatlakozik, az elutasított próbálkozásokat késleltetéssel megismétli, majd mind leáll DISCONNECT nélkül. A fejlesztői módban a heap_limit_mb= paraméter arra készteti a befogadást, hogy a heapet a valóságosnál kisebbnek tekintse, így a heapnél nagyobb vihar is kipróbálható kevés sockettel. Egy ilyen, 3 000 eszközös körben 1 368 csatlakozott 36 másodperc alatt, 5 619 próbálkozást pedig rendben elutasítottunk, 8 MiB-os korlát mellett; a memória a vihar után visszaállt.
Hogyan dolgozunk
A projektet egy írott specifikáció, a PROMPT.md vezeti a mérföldkőtervvel, és minden mérföldkő ugyanazzal a rituáléval zárul: zöld make check és make smoke, egyetlen commit M<n> jelöléssel, bejegyzés a docs/PROGRESS.md fájlba és ADR minden olyan döntéshez, amely nem magától értetődő. A szabályok rövidek, és nem alkudozunk rajtuk: nincs pánik külső bemenetre, unsafe csak a hardveres és FFI-csomagokban és mindig megjegyzéssel, nincs allokáció a forró úton, megjegyzés minden atomi műveleti sorrendhez, minden korlát a konfigurációból származik, a szándékos ideiglenes részek pedig hangosan buknak el.
A CI többet végez, mint amennyit kézzel el tudnánk érni: fmt, clippy a hostra és az aarch64-unknown-none célra, typos, actionlint és shellcheck; teszteket Linuxon és macOS-en arm64-en; a mag építését fejlesztői és éles konfigurációval, az ELF méretével az összefoglalóban; indítást QEMU alatt a füsttesztek összes forgatókönyvével és a soros naplók elmentésével; cargo-deny a figyelmeztetésekre, licencekre és forrásokra; percenként fuzzolást a tizenegy cél mindegyikén, éjszaka pedig célonként tíz percet gyorsítótárazott korpusszal. Ehhez jön a CodeQL, az OpenSSF Scorecard, a Dependabot és a SLSA-eredetű kiadás. Minden idegen action a teljes commit SHA-hoz van rögzítve.
A reprodukálhatóságot szó szerint vesszük: a make repro kétszer építi meg a HEAD-et friss munkafákban, és bájtról bájtra összehasonlítja az ELF-et, az ISO-t és a nyers lemezképet. A kiadásokat minisignnel írjuk alá, az artefaktumok pedig ellenőrizhetők a gh attestation verify paranccsal. Az éles képfájl tartalmazza a szerver privát kulcsát, ezért maga az ISO titok; a GitHubon a kiadások mellett lévő képfájlok fejlesztői képek, ideiglenes kulcsokkal, és csak kipróbálásra valók.
Mit tanultunk
Néhány lecke, amely megváltoztatta a tervet:
- A saját TCP végül mégis megérte. A prototípus smoltcp-n futott, és az M13-ig jól szolgált minket. De egy szerver, amely százezres nagyságrendű kapcsolatot tart, nem kliens-TCP-t igényel, hanem SYN-sütiket, időzítőkereket és 96 bájtos állapotot. Az M14-ben a smoltcp-t saját, csak szerveroldali veremre cseréltük, szimulált veszteséges tesztekkel és szegmens-fuzzinggal.
- A memóriát belülről kell mérni. A kapcsolatonkénti becslések használhatatlanok voltak, amíg a mag maga nem kezdte számolni a heapet az allokátor blokkjaiban, nem pedig a kért bájtokban. Csak ekkor láttuk, hová megy valójában az 512 bájt, és ekkor jutottunk le 494-re.
- A tesztelőeszköz a termék része. A legnagyobb korlát nem a mag volt, hanem a QEMU felhasználói hálózata és az efemer portok száma a fejlesztői gépen. Százezer és több kapcsolathoz macOS-en
vmnet-shared, vagy Linux KVM-mel, tap interfésszel és több klienscímmel van szükség. - Az SQLite operációs rendszer nélkül is lehetséges, de csak szigorú feltételekkel: fix heap, kizárólagos zárolás megosztott memória nélkül, fájlokat nem ismerő VFS, és olyan befogadás, amely nem engedi lemaradni az adatbázist.
- Az újracsatlakozási viharok a normális állapot, nem a kivétel. Amikor a mobilhálózat leesik, majd visszatér, eszközök ezrei kopogtatnak egyszerre. Ezért a befogadás bármiféle kriptográfia előtt elutasítja a kapcsolatot, és minden elutasított kapcsolat szinte semmibe sem kerül.
Mi következik
Az M17 utáni munkát három irányban terveztük meg, a közöttük lévő sorrend pedig a docs/PLAN.md fájlban van rögzítve. Ezek közül egyik sincs még megépítve.
- Egyetlen ISO több platformra. Ugyanaz az
urmqtt-<env>-<verzió>.isofájl és egyetlen nyers GPT lemezkép, amely aarch64 UEFI-n, x86_64 UEFI-n és x86_64 BIOS-on is elindul, virtuális gépekben és valódi hardveren, egyetlen Intel PC-vel kezdve. Továbbra is mindent magában foglaló eszköz, reprodukálható és aláírt. - Nyers lemez, fájlrendszer nélkül. Bájtszintű formátumspecifikáció, a magéval közös elemzőket használó
urmqtt-diskhost eszköz, 1 MiB-os régiózarás, a lemez növekedése az adatokkal, discard a vékonyan kiosztott lemezekhez, az adatbázis A/B pillanatképei, bitellenőrzés és választhatóan AES-256-XTS titkosítás hardveres AES-szel. - Bizonyíthatóan biztonságos. Eszközök futásidejű visszavonása és engedélyezési listája aláírt vezérlőcsatornán, új képfájl nélkül; a saját TLS és TCP differenciális és konformanciatesztelése; KASLR, veremvédelem, kCFI, MTE és megerősített allokátor; EL0 szinten izolált SQLite; Secure Boot; SBOM és cargo-vet; végül külső auditra szánt csomag.
Azok a platformok, amelyek csak nem virtio eszközöket kínálnak, mint az AWS ENA vagy az Azure MANA, egyelőre nem támogatottak. A Raspberry Pi 4 és 5 KVM-hostként, a Hetzner CAX és az Oracle Ampere A1 dokumentált és kóddal támogatott, de valódi szolgáltatáson még nem próbáltuk ki őket.
Próbálja ki
A repó a github.com/zeljan-alduk/urMQTT címen érhető el. A rögzített nightly eszközlánccal rendelkező Rusttal és a QEMU-val a make certs, a make run és egyetlen mosquitto kliens elegendő az első PUBLISH-hoz mTLS-en keresztül a saját gépén. Az elején szereplő figyelmeztetés a végén is érvényes: ez pre-alfa, és mindent, ami működik, a docs/PROGRESS.md ír le. A hibajelentéseket, a tervezéssel kapcsolatos kérdéseket és a biztonsági bejelentéseket a SECURITY.md útmutatása szerint szívesen fogadjuk. Minden következő mérföldkőről itt fogunk beszámolni.
Hozzászólások
Hozzászólási szabályok