← Blog

· 15 min čítania #rust#mqtt#iot#unikernel#open source

urMQTT: budujeme MQTT broker, ktorý je zároveň operačným systémom

Vývojárske poznámky o urMQTT, unikernel napísanom v Ruste, ktorý je sám osebe MQTT broker: jeden ELF s vlastným TCP/IP, TLS 1.3, brokerom a SQLite, spustený z jedného ISO.

Zariadenia vo vozidlách, na parkoviskách a v skriniach s elektronikou majú jednu spoločnú vlastnosť: posielajú malé správy, zriedka, ale je ich veľa a sú neustále pripojené. Roky ich pripájame na MQTT brokery a roky nás trápi tá istá otázka. Prečo na niečo také jednoduché potrebujeme celý Linux, OpenSSL, runtime nejakého jazyka, SSH, správcu balíkov a až potom broker? Každá z týchto vrstiev prináša vlastné zraniteľnosti, spotrebúva vlastnú pamäť a pridáva ďalšiu vec, ktorá sa môže pokaziť, a flotila zariadení od servera potrebuje len tri veci: aby držal veľa takmer nečinných spojení, aby spoľahlivo overil totožnosť každého zariadenia a aby preniesol správy bez straty.

Tak vznikol urMQTT: unikernel, ktorý je MQTT broker. Jadro, TCP/IP, TLS 1.3, MQTT a vstavaná databáza v jedinom binárnom programe v Ruste, ktorý sa spúšťa z jedného ISO. Žiadne procesy, žiadne systémové volania, žiadny shell. Prvou platformou, na ktorej sa buduje a testuje, je aarch64, a ten istý kód smeruje na x86_64, cez UEFI aj klasický BIOS, a na skutočný hardvér: cieľom je jeden ISO, ktorý sa zavedie na všetkých z nich. Projekt je open source pod licenciou MIT alebo Apache 2.0 a v tomto texte chceme zapísať, kam sme sa dostali, ako je vo vnútri poskladaný a čo sme sa popritom naučili.

Čo presne znamená „unikernel"

Bežný broker je program, ktorý beží na operačnom systéme. urMQTT pod sebou operačný systém nemá: samo sa zavedie cez UEFI firmware a bootloader Limine, nastaví si vlastné tabuľky stránok, naprogramuje kontrolér prerušení a časovač, nájde zariadenia virtio cez PCIe, získa adresu cez DHCP a počúva na jedinom porte. Všetko, čo by inak robilo jadro, ovládače, sieťový stack a aplikácia, je tu jeden ELF, ktorý beží na úrovni EL1.

Porovnanie s typickou inštaláciou hovorí samo za seba:

Typický broker na Linuxe urMQTT
Vystavené služby SSH, broker, často aj port pre metriky alebo administráciu iba TCP 8883 (MQTT cez TLS 1.3 s mTLS)
Kód v obraze jadro, userland, libc, OpenSSL, runtime jeden ELF v Ruste (plus vendorovaný SQLite)
Vzdialená správa shell, konfiguračné súbory, aktualizácie balíkov nič. Nová verzia je nový ISO
Pamäť na nečinné spojenie kilobajty (vyrovnávacie pamäte socketov, objekty TLS, heap) cieľ ≤ 512 B
Viacjadrový model vlákna a zámky alebo jedna slučka udalostí vlákno na jadro, bez zdieľaného stavu, spracovanie do konca
Integrita kódu sú možné mapovania, ktoré sú zapisovateľné aj spustiteľné W^X, zamknuté tabuľky stránok, PAC/BTI

Priority sú v tomto poradí: bezpečnosť, škálovateľnosť, viacjadrový výkon, malá stopa a nemenná inštalácia. Keď sú dva ciele v konflikte, vyhráva ten, ktorý je v tomto zozname vyššie.

Kde sme teraz

Projekt je vo fáze pred-alfa, ale uzavretých je sedemnásť vývojových míľnikov, od M0 po M17. Dnes urMQTT obsluhuje MQTT 3.1.1 cez TLS 1.3 s povinnými klientskymi certifikátmi a stav uchováva v SQLite na surovom disku. Stručne, čo už funguje:

  • Jadro: vlastné vektory výnimiek s dekódovanými hláseniami, vlastné tabuľky stránok s vynúteným W^X, ochranné stránky, PAC a BTI tam, kde ich procesor má, GICv3 a GICv2, generický časovač, SMP až do 64 jadier.
  • Zisťovanie hardvéru z DTB alebo ACPI do jedného popisu platformy, s identickým výsledkom z oboch zdrojov.
  • Ovládače: PCIe ECAM, MSI-X, virtio-net, virtio-blk, virtio-scsi a virtio-rng, a CSPRNG zasiaty hardvérovou entropiou.
  • Sieť: vlastný DHCPv4, ARP, ICMP a prísny IPv4, potom vlastný TCP len pre serverovú stranu: SYN cookies, hierarchické koleso časovačov, NewReno, spájanie ACK, bez stavu TIME_WAIT.
  • TLS: iba TLS 1.3, povinné mTLS, identita zariadenia z CN alebo SAN URI; podanie rúk robí rustls a po ňom vlastná vrstva záznamov s AES-128-GCM a ChaCha20-Poly1305. Obnovenie relácie lístkami PSK, zoznam odvolaní, riadenie prijatia už pri podaní rúk.
  • MQTT: kodek bez kopírovania, fuzzovaný a testovaný s pravými klientmi mosquitto; QoS 0 a 1, zástupné znaky, zachované správy, závet (LWT), trvalé relácie, ACL s obmedzením na devices/{id}/#, obmedzenia rýchlosti na zariadenie.
  • Úložisko: SQLite vnútri jadra cez VFS nad surovým diskom, v režime WAL, s kontrolou integrity pri zavádzaní; register zariadení, odvolania, zachované správy, trvalé relácie s frontmi správ pre zariadenia, ktoré sú offline; na každé jadro samostatný telemetrický denník s CRC na záznam a obnovou po páde.
  • Prevádzka a dohľad: strážny časovač pre obslužné rutiny, kontrola stavu, obmedzené logovanie, syslog a statsd cez UDP, prijatie, ktoré prežije búrky opätovných pripojení.
  • Dodanie: bitovo identické opakované zostavenia overené v CI, ISO a surový GPT obraz disku, podpisy minisign, návody pre KVM, Proxmox a Hetzner.

Každý krok je označený míľnikom, ktorý ho priniesol, a súbor docs/PROGRESS.md v repozitári je jediným zdrojom pravdy o tom, čo naozaj funguje.

Architektúra v troch obrázkoch

Celý návrh je popísaný v docs/ARCHITECTURE.md a dôvody každého dôležitejšieho rozhodnutia sú zapísané ako ADR v docs/DECISIONS.md. Tu je prehľad.

Vrstvy

Vrstvy urMQTT: od brokera cez kodek MQTT, TLS, TCP a sieť až po ovládače virtio a architektonickú vrstvu, všetko v jedinom ELF na úrovni EL1.
Vrstvy urMQTT: od brokera cez kodek MQTT, TLS, TCP a sieť až po ovládače virtio a architektonickú vrstvu, všetko v jedinom ELF na úrovni EL1.

Zhora nadol: broker (relácie, strom tém, QoS, zachované správy, závety, ACL, obmedzenia), kodek MQTT, TLS, TCP, sieťová vrstva a potom ovládače. Popri tejto hlavnej ceste stojí úložisko (SQLite a telemetrický denník) a pod všetkým správa pamäte, zisťovanie platformy a konfigurácia, ktorá je v čase zostavenia preložená do konštánt, spolu so vstavaným certifikátom CA, serverovým certifikátom a kľúčom. Hypervízor so zariadeniami virtio je jediné, čo je mimo obrazu.

Vlákno na jadro, bez zdieľaného stavu

Model vykonávania: každé dátové jadro má svoju slučku a svoj diel brokera a najvyššie jadro spúšťa iba SQLite. Jadrá komunikujú výhradne prstencami SPSC.
Model vykonávania: každé dátové jadro má svoju slučku a svoj diel brokera a najvyššie jadro spúšťa iba SQLite. Jadrá komunikujú výhradne prstencami SPSC.

Každé dátové jadro točí vlastnú slučku s vlastným zásobníkom TCP, stavmi TLS, dielom brokera (relácie a strom tém), vyrovnávacou pamäťou heapu a oddielom telemetrie. Jadrá nezdieľajú žiadny meniteľný stav, iba ohraničené prstence bez zámkov, po jednom pre každý usporiadaný pár jadier. Najvyššie jadro spúšťa SQLite a nič iné.

Sieťová karta má dnes jeden pár front, ktorý drží jadro 0. To každý tok MQTT podľa hashu Toeplitz jeho štvorice nasmeruje na jedno z pracovných jadier a posiela to, čo pracovné jadrá vrátia. Relácia žije na svojom domovskom jadre, určenom hashom identifikátora klienta, takže prevzatie, závety a trvanlivosť nikdy neprekračujú hranice jadier. Spojenie, ktoré pristane na inom jadre, si tam ponechá svoj TCP a TLS, a bežný MQTT preposiela domovskému jadru s riadením toku založeným na kreditoch. Každá smerovaná správa sa rozosiela aj na ostatné diely brokera, z ktorých každý drží repliku zachovaných správ.

Tento model drží pohromade tri pravidlá. Spracovanie do konca: prijatý paket sa spracuje celý na jednom jadre, od TCP cez dešifrovanie TLS na mieste, parsovanie MQTT a smerovanie až po šifrovanú odpoveď, bez frontov úloh a bez kopírovania do aplikačných vyrovnávacích pamätí. Prispôsobivé vzorkovanie: pri záťaži sa fronty na príjem aktívne vzorkujú a v pokoji sa jadro vracia k prerušeniam a WFI; obslužné rutiny prerušení iba potvrdia prerušenie a označia prácu. Strážny časovač: tik 10 ms na jadro zachytí obslužné rutiny, ktoré prekročia svoj rozpočet.

Život jedného PUBLISH

Cesta jednej správy PUBLISH s QoS 1: od záznamu TLS na sieťovej karte cez dešifrovanie, kontrolu ACL a smerovanie až po PUBACK spojený s TCP ACK v jedinom segmente.
Cesta jednej správy PUBLISH s QoS 1: od záznamu TLS na sieťovej karte cez dešifrovanie, kontrolu ACL a smerovanie až po PUBACK spojený s TCP ACK v jedinom segmente.

Zariadenie pošle záznam TLS. Sieťová karta ho odovzdá slučke jadra deskriptorom, bez kopírovania. Slučka skontroluje TCP, dešifruje TLS na mieste a parsuje MQTT z požičanej vyrovnávacej pamäte, potom v pamäti skontroluje ACL, obmedzenie rýchlosti a cestu stromom tém. Ak sa iné jadro zaujíma o túto tému, dostane správu na smerovanie s odkazom na obsah a identifikátorom témy; databáza dostane telemetrický záznam alebo aktualizáciu zachovanej správy, v balíku. Odpoveď PUBACK sa zašifruje priamo do odchádzajúcej vyrovnávacej pamäte a spojí sa s TCP ACK, takže zariadeniu odíde jeden segment. Iné jadro stojí správa jedno šifrovanie na odberateľa v okamihu odoslania.

Koľko stojí jedno spojenie

Cieľom je najviac 512 bajtov na nečinné spojenie TLS, s ambíciou 256. Kým spojenie odpočíva, nič sa pre ňu nedrží vo vyrovnávacej pamäti: prijaté dáta sa spracúvajú priamo zo sieťového rámca a vyrovnávacie pamäte na odosielanie, záznamy a MQTT existujú len dovtedy, kým je niečo nedokončené alebo nepotvrdené. Jadro to aj samo meria: presné počítadlá heapu v požadovaných bajtoch aj v blokoch, ktoré zaberajú, zapisované každých desať sekúnd ako heap nad základnou úrovňou na otvorené spojenie.

Časť Veľkosť Ako
Riadiaci blok TCP 96 B zabalené príznaky, 16-bitové RTT/RTO, slot v kolese časovačov, bez vyrovnávacích pamätí v pokoji
Slot v tabuľke TCP 4–8 B iba index spojenia, tabuľka najviac na polovicu plná
Spojenie a stav záznamov TLS 1.3 152 B tajomstvo a poradové číslo na smer (40 B); kľúč a IV sa odvodzujú na záznam
Spojenie MQTT 48 B identita a závet na heape iba dovtedy, kým existujú
Relácia MQTT, horúca podoba 64 B jeden odber v riadku, internované identifikátory uzlov
Odber devices/<id>/cmd/# 0 uzlov stromu uložený relatívne voči identifikátoru relácie, spoločný všetkým zariadeniam

Zmerané pod HVF so štyrmi virtuálnymi jadrami, z toho tri pracovné, pričom každé zariadenie drží spojenie mTLS a jeden odber s QoS 1, vrátane zaokrúhľovania alokátora:

Spojenia Bajtov na spojenie
960 531 B
9 922 494 B
10 197 474 B

Fond sieťových rámcov je pevný, okolo 2 MiB, čo je zhruba 200 B na spojenie pri desaťtisíc spojeniach a okolo 2 B pri milióne. Viac sme zmerať nedokázali: používateľská sieť QEMU na macOS prestala prijímať spojenia pri 10 197, zhruba na hranici 10 240 deskriptorov procesu QEMU. Číslo klesá, keď sa pevné časti rozdeľujú na viac spojení, takže s ich počtom nerastie.

Bezpečnostný model

Bezpečnosť je prvou prioritou a vyhráva všetky konflikty s ostatnými cieľmi. Model má niekoľko vrstiev:

  • Jeden port. TCP 8883, iba TLS 1.3, povinné klientske certifikáty podpísané CA vstavanou do obrazu. Identifikátor klienta MQTT sa musí rovnať identifikátoru zariadenia z certifikátu.
  • Žiadny vstup. Žiadny shell, konzolový vstup, SSH, administračné API, dynamický kód, SQL dostupný cez sieť ani súborový systém.
  • Pamäťová bezpečnosť. Rust, s forbid(unsafe_code) v protokolových balíkoch; každý blok unsafe má komentár // SAFETY:, ktorý kontroluje lint, a na vonkajší vstup neexistuje panika: clippy v balíkoch na dátovej ceste zakazuje unwrap, expect, indexovanie a panic!.
  • Zmierňovanie zneužitia. W^X sa vynucuje kódovaním deskriptorov a bitom SCTLR_EL1.WXN a kontroluje sa pri každom zavedení. Tabuľky stránok sú po zavedení iba na čítanie, bez zapisovateľného aliasu. Dolná polovica adresného priestoru je vypnutá. Každý zásobník má ochranné stránky a výnimky bežia na samostatnom zásobníku. PAC a BTI sa zapínajú, keď ich procesor podporuje, a overujú to dymové testy.
  • Odolnosť voči zneužitiu. SYN cookies; prijatie odmieta nové spojenia, ešte pred akoukoľvek kryptografiou, keď je heap nízky, keď databáza zaostáva, keď je príliš veľa podaní rúk v priebehu na jadro alebo na zdrojovú adresu, alebo keď je rýchlosť podaní rúk príliš vysoká. Obmedzenia rýchlosti na zariadenie, ohraničené fronty, okno TCP viazané na spätný tlak brokera, obmedzené logovanie, strážny časovač a kontrola stavu.
  • Nemennosť. Konfigurácia, CA a serverový kľúč sú vstavané do obrazu. Zmena čohokoľvek znamená nový obraz.

Model hrozieb je zapísaný v docs/SECURITY.md.

Úložisko bez súborového systému

Dáta žijú na samostatnom disku, virtio-blk alebo virtio-scsi, na ktorom nie je súborový systém. Rozloženie je minimálne a vlastné:

LBA 0      [ superblok: magické číslo · verzia rozloženia · uuid · tabuľka oblastí · CRC-32C ]
LBA 8, 16  [ tabuľka veľkostí súborov, sloty A/B (vyhráva najnovší platný) ]
LBA 64     [ SQLite hlavná databáza ½ ][ SQLite WAL ⅛ ][ denník 1 MiB ][ telemetrický denník: 8 oddielov … ]
posledné 4 KiB [ priestor na samokontrolu blokového zariadenia pri zavádzaní ]

SQLite (vendorovaný 3.54.1, s kontrolou odtlačku pri zostavení) je preložený do jadra pomocou clang, bez štandardnej knižnice, a používa pevný heap memsys5. Jeho VFS mapuje tri pevné súbory na oblasti disku. Beží v režime WAL s locking_mode=EXCLUSIVE, takže nepotrebuje index v zdieľanej pamäti, a so synchronous=FULL; ak quick_check pri zavádzaní nájde chybu, systém sa bezpečne zastaví. V databáze sú register zariadení, odvolania, zachované správy a trvalé relácie s frontmi správ QoS 1 pre zariadenia, ktoré nie sú pripojené.

Jadro pre databázu, to s najvyšším číslom, spúšťa SQLite a nič iné. Dátová rovina mu posiela zmeny stavu cez prstenec SPSC bez zámkov; ono ich zbiera do jednej transakcie každých 5 ms alebo každých 512 operácií a potvrdenia vracia druhým prstencom. Prázdny disk sa naformátuje pri prvom zavedení; nič iné sa nikdy nepreformátuje.

Telemetria ide inou cestou. Každý prijatý PUBLISH na témach zo storage.telemetry_topics odchádza do oddielu telemetrického denníka svojho jadra: prstenec segmentov s CRC na záznam, osolený poradovým číslom segmentu, takže sa staré prechody prstenca nikdy znova neobjavia. Jadrá odovzdávajú záznamy databáze vlastným prstencom, bez kopírovania, a ona ich zapisuje každých 5 ms alebo každých 256 KiB. Pri zavádzaní obnova zachová každý zapísaný záznam, odreže nedokončený chvost a pokračuje v novom segmente. Uchovávanie je podľa veľkosti, cez prstenec, aj podľa veku, cez retention_days. Overili sme to s miliónom záznamov a s kill -9 uprostred zápisu.

Čísla

Nástroj na záťaž v tools/loadgen robí tri veci: búrku podaní rúk TLS 1.3 s mTLS a CONNECT, dlhodobé spojenia s PINGREQ, ktoré každú sekundu publikujú telemetriu, a búrky opätovných pripojení. make bench na Apple M4 Pro pod HVF dáva:

Pracovné jadrá podania rúk/s v hosťovi škálovanie cez používateľskú sieť QEMU (spojení/s)
1 862 1,00× 789
2 1 724 2,00× 636
4 3 438 3,99× 536

Číslo v hosťovi, kde sú klient aj server v tom istom virtuálnom stroji a každé pracovné jadro beží samo za seba, ukazuje, že dátová rovina škáluje lineárne. Sieťové číslo je obmedzené jednovláknovou používateľskou sieťou QEMU, nie hosťom; aj to je zapísané ako ADR-032.

Búrky opätovných pripojení testujeme tak, že sa všetky zariadenia pripoja naraz, opakujú odmietnuté pokusy so oneskorením a potom všetky spadnú bez DISCONNECT. Parameter heap_limit_mb= vo vývojovom režime donúti prijatie považovať heap za menší, než je, takže sa búrka väčšia než heap dá vyskúšať s málo socketmi. V jednom takom kole s 3 000 zariadeniami sa pripojilo 1 368 za 36 sekúnd a 5 619 pokusov bolo riadne odmietnutých, pri obmedzení 8 MiB; pamäť sa po búrke vrátila.

Ako pracujeme

Projekt vedie písaná špecifikácia, PROMPT.md, s plánom míľnikov, a každý míľnik sa končí tým istým rituálom: make check a make smoke zelené, jeden commit so značkou M<n>, záznam v docs/PROGRESS.md a ADR pre každé rozhodnutie, ktoré nie je zrejmé. Pravidlá sú krátke a nevyjednávame o nich: žiadna panika na vonkajší vstup, unsafe iba v hardvérových a FFI balíkoch a vždy s komentárom, žiadne alokácie na horúcej ceste, komentár ku každému poradiu atomických operácií, každé obmedzenie pochádza z konfigurácie a zámerné dočasné časti padajú nahlas.

CI robí viac, než by sme stihli ručne: fmt, clippy pre hosta aj pre aarch64-unknown-none, typos, actionlint a shellcheck; testy na Linuxe a macOS na arm64; zostavenie jadra pre vývojovú aj produkčnú konfiguráciu s veľkosťou ELF v súhrne; zavedenie pod QEMU so všetkými scenármi dymového testu a uložením sériových záznamov; cargo-deny pre upozornenia, licencie a zdroje; minútu fuzzingu na každý z jedenástich cieľov a v noci desať minút na cieľ s korpusom v cache. K tomu CodeQL, OpenSSF Scorecard, Dependabot a vydanie s pôvodom SLSA. Každá cudzia akcia je pripnutá na plný commit SHA.

Reprodukovateľnosť chápeme doslovne: make repro zostaví HEAD dvakrát v čerstvých pracovných stromoch a porovná ELF, ISO a surový obraz bajt po bajte. Vydania sú podpísané pomocou minisign a artefakty sa dajú overiť cez gh attestation verify. Produkčný obraz obsahuje súkromný kľúč servera, takže samotný ISO je tajomstvo; obrazy pri vydaniach na GitHube sú vývojové, s dočasnými kľúčmi, a slúžia len na vyskúšanie.

Čo sme sa naučili

Niekoľko lekcií, ktoré zmenili plán:

  • Vlastný TCP sa napokon oplatil. Prototyp bežal na smoltcp a dobre nám slúžil až do M13. Ale server, ktorý drží státisíce spojení, nepotrebuje klientsky TCP, potrebuje SYN cookies, koleso časovačov a stav s 96 bajtmi. V M14 sme smoltcp nahradili vlastným stackom len pre serverovú stranu, s testami simulovanej straty a fuzzingom segmentov.
  • Merajte pamäť zvnútra. Odhady na spojenie boli bezcenné, kým jadro samo nezačalo počítať heap v blokoch alokátora, a nie v požadovaných bajtoch. Až vtedy sme uvideli, kam sa 512 bajtov naozaj podeje, a klesli sme na 494.
  • Nástroj na testovanie je súčasť produktu. Najväčším obmedzením nebolo jadro, ale používateľská sieť QEMU a počet efemérnych portov na vývojovom počítači. Pre sto tisíc spojení a viac treba vmnet-shared na macOS alebo Linux s KVM, rozhraním tap a viacerými klientskymi adresami.
  • SQLite bez operačného systému je možný, ale len za prísnych podmienok: pevný heap, exkluzívne zamykanie bez zdieľanej pamäte, VFS, ktorý nevie o súboroch, a prijatie, ktoré nenechá databázu zaostať.
  • Búrky opätovných pripojení sú normálny stav, nie výnimka. Keď spadne mobilná sieť a vráti sa, tisíce zariadení klopú súčasne. Preto prijatie odmieta spojenie ešte pred akoukoľvek kryptografiou a každé odmietnuté spojenie stojí takmer nič.

Čo bude ďalej

Práca po M17 je plánovaná v troch smeroch a poradie medzi nimi je zapísané v docs/PLAN.md. Nič z toho ešte nie je postavené.

  • Jeden ISO pre viac platforiem. Ten istý súbor urmqtt-<env>-<verzia>.iso a jeden surový obraz GPT, ktoré sa zavádzajú na aarch64 UEFI, x86_64 UEFI a x86_64 BIOS, vo virtuálnych strojoch aj na skutočnom hardvéri, počnúc jedným počítačom Intel. Naďalej zariadenie so všetkým vnútri, reprodukovateľné a podpísané.
  • Surový disk, bez súborového systému. Špecifikácia formátu na úrovni bajtov, hostiteľský nástroj urmqtt-disk, ktorý zdieľa parsery s jadrom, zarovnanie oblastí na 1 MiB, rast disku s dátami, discard pre tenko alokované disky, snímky databázy A/B, kontrola bitov a podľa výberu šifrovanie AES-256-XTS s hardvérovým AES.
  • Dokázateľne bezpečné. Odvolanie a zoznam povolených zariadení za behu cez podpísaný riadiaci kanál, bez nového obrazu; diferenciálne a konformančné testovanie vlastného TLS a TCP; KASLR, ochrana zásobníka, kCFI, MTE a spevnený alokátor; SQLite izolovaný na úrovni EL0; Secure Boot; SBOM a cargo-vet; a nakoniec balík pre externý audit.

Platformy, ktoré ponúkajú iba zariadenia, ktoré nie sú virtio, ako AWS ENA alebo Azure MANA, zatiaľ nie sú podporované. Raspberry Pi 4 a 5 ako hostiteľ KVM, Hetzner CAX a Oracle Ampere A1 sú zdokumentované a podporované kódom, ale ešte neboli vyskúšané na skutočnej službe.

Vyskúšajte

Repozitár je na github.com/zeljan-alduk/urMQTT. S Rustom s pripnutou nightly sadou nástrojov a QEMU stačia make certs, make run a jeden klient mosquitto na prvý PUBLISH cez mTLS na vlastnom počítači. Upozornenie z úvodu platí aj na konci: toto je pred-alfa a všetko, čo funguje, je napísané v docs/PROGRESS.md. Hlásenia chýb, otázky k návrhu a bezpečnostné hlásenia podľa pokynov v SECURITY.md sú vítané. O každom ďalšom míľniku sa tu ozveme.

Komentáre

Pravidlá komentovania

Pravidlá komentovania

Komentáre slúžia na zdieľanie skúseností a otázok k témam blogu. Tieto pravidlá udržiavajú diskusiu užitočnú pre všetkých.

  1. Slušnosť Žiadne urážky, vyhrážky, obťažovanie, nenávistné prejavy ani diskriminácia z akéhokoľvek dôvodu. Kritizujte argument, nie osobu.
  2. K téme Komentár sa má týkať príspevku alebo diskusie pod ním.
  3. Bez reklamy a spamu Žiadna inzercia, reťazové správy ani odkazy bez kontextu. Odkazy a obrázky sú vítané, keď diskusiu obohacujú.
  4. Súkromie ostatných Nezverejňujte osobné údaje iných ľudí: celé mená súkromných osôb, adresy, telefóny, e-maily, fotografie bez súhlasu.
  5. Autorské práva Zverejňujte len obsah, ktorý smiete zdieľať. Pri citovaní uveďte zdroj.
  6. Jedna identita Používajte jednu prezývku a nevydávajte sa za niekoho iného.
  7. Potvrdenie e-mailom Komentár sa zverejní až po potvrdení odkazu zaslaného e-mailom. Adresa sa nezobrazuje a na nič iné sa nepoužíva; nepotvrdené komentáre sa po 48 hodinách mažú.
  8. Moderovanie Komentáre porušujúce pravidlá skrývame alebo mažeme bez upozornenia a diskusiu môžeme uzamknúť. Rozhodnutia moderátorov sú konečné.
  9. Zodpovednosť Za obsah komentára zodpovedá jeho autor. Komentáre nevyjadrujú názory ALDO TECH.
  10. Nahlásenie Nevhodný obsah nahláste na info@aldo.tech.