← Blog

· 18 min di lettura #rust#mqtt#iot#unikernel#open source

urMQTT su un vero VPS: ISO, handshake da 0,24 ms, disco proprio e kernel rinforzato

Che cosa è successo alle tre promesse del primo articolo su urMQTT (un solo ISO, disco raw senza file system, sicurezza dimostrabile) dopo i primi quattro giorni di sviluppo, con misure, tabelle e l'elenco di ciò che non è ancora finito.

Nel primo articolo su urMQTT abbiamo descritto un unikernel che è un broker MQTT, fino alla milestone M17, e abbiamo chiuso con tre promesse sotto il titolo "Che cosa viene dopo": un solo ISO che si avvia su più piattaforme, un disco raw senza file system e una sicurezza che si possa dimostrare, non solo dichiarare. Allora nulla di tutto questo era stato costruito. Questo articolo segue che cosa è successo a ciascuna promessa, nello stesso ordine di prima: che cosa avevamo pianificato, che cosa abbiamo costruito, che cosa ci ha sorpreso e che cosa è ancora aperto. Lungo la strada mostreremo anche quanto tempo è servito, perché fa parte della storia.

Una premessa: il progetto è ancora pre-alfa. I numeri nel testo misurano codice e test, non la maturità in produzione, e la prima pubblicazione è volutamente limitata ai VPS con KVM. Il bare metal resta per dopo.

Come si presenta nel tempo

Il primo commit risale al 28 ottobre 2026 alle 23:48 (M0). Al 31 ottobre alle 23:00 il repository conta 119 commit, distribuiti come 3, 39, 38 e 39 per giorno di calendario. Diciamo subito anche come sia possibile: il progetto è costruito con Claude Code, e i commit portano trailer Co-Authored-By: Claude. Quattro giorni di calendario di storia non significano che una persona abbia scritto 90 000 righe in quattro giorni; significano che piano, implementazione, test e ADR vengono scritti in cicli brevi e chiusi, e che ogni passo termina con lo stesso rituale di verifica di prima. I numeri qui sotto parlano della quantità di codice e di test, non di quanto lavoro reale ci sia dietro tutto questo.

Crescita del progetto nell'arco di quattro giorni con le milestone da M0 a oggi: migliaia di righe di Rust (da 1,6 a 89,8), numero di funzioni #[test] (da 27 a 739) e numero di ADR (da 13 a 104), con le barre dei commit per giorno (39, 38 e 39 per il 29, 30 e 31 ottobre).
Crescita del progetto nell'arco di quattro giorni con le milestone da M0 a oggi: migliaia di righe di Rust (da 1,6 a 89,8), numero di funzioni #[test] (da 27 a 739) e numero di ADR (da 13 a 104), con le barre dei commit per giorno (39, 38 e 39 per il 29, 30 e 31 ottobre).

Il grafico mostra tre curve che crescono quasi insieme, ed è proprio l'intenzione: test e decisioni scritte seguono il codice, non restano indietro. La pendenza è massima il 29 ottobre, quando nasce l'intero percorso dal kernel al broker. In seguito le righe si aggiungono più lentamente, ma i test crescono più in fretta del codice (27 test su 1,6 migliaia di righe all'inizio, 739 su 89,8 migliaia oggi).

Milestone Commit Ora Righe di Rust Test ADR
M0 9412a9c 28.10. 23:48 1 592 27 13
M5 a61083b 29.10. 01:32 9 314 88 24
M9 4be8cc9 29.10. 02:21 15 729 149 28
M11 4800904 29.10. 03:43 22 737 180 30
M13 a558d5e 29.10. 05:22 26 556 193 32
M17 7df4f98 29.10. 08:48 33 504 232 36
S1 ecf72ec 30.10. 00:46 41 910 299 45
X8 fb1504a 30.10. 19:08 56 341 456 59
PERF 76f7c36 31.10. 14:19 72 511 618 76
oggi HEAD 31.10. 23:00 89 790 739 104

Le righe sono tutti i file .rs al di fuori di vendor/ e fuzz/, i test sono funzioni #[test]. Che cosa ha aggiunto ciascuna fase, in base alla data nella storia di git:

Data Milestone Che cosa è stato aggiunto
29.10. da M0 a M17 kernel, rete, TLS, broker, SQLite, più core, TCP proprio, rinforzo, rilascio riproducibile
29.10. sera e 30.10. da X0 a X10, S1, H2, H3 (X0 inizia il 29.10. alle 20:54) port su x86_64, ISO universale, un solo disco e ISO di auto-installazione, controlli TLS, client ostili
31.10. da O1 a O4, T1, PERF, H4, H5, H9, da S2 a S6 visibilità e console tramite MQTT, modalità live e diagnostica, SNTP, ottimizzazioni, rinforzo, verifica, supply chain, archiviazione

Promessa 1: un solo ISO per più piattaforme

Che cosa avevamo pianificato. Un unico file che si avvia su UEFI aarch64, UEFI x86_64 e BIOS x86_64. Che cosa abbiamo costruito. Il port su x86_64 (da X0 a X10) e un ISO universale con il bootloader Limine, un unico ISO ibrido da cui si avviano tutte queste combinazioni; gli smoke test lo avviano su quattro macchine virtuali. Il menu ha tre voci: urMQTT (modalità live, gira dalla RAM, non scrive nulla sul disco), installazione sul disco della macchina su cui è avviato (l'installazione scrive GPT e dati, poi spegne la macchina) e Diagnostica (rilevamento dell'hardware e misure).

Il menu di avvio dell'ISO, catturato sul VPS: le voci "urMQTT", "Install urMQTT on this machine's disk" e "Diagnostic: hardware detection and benchmarks" con il conto alla rovescia per l'avvio automatico. L'immagine proviene da un ISO di prova con un conto alla rovescia più lungo; il valore predefinito è 10 secondi.
Il menu di avvio dell'ISO, catturato sul VPS: le voci "urMQTT", "Install urMQTT on this machine's disk" e "Diagnostic: hardware detection and benchmarks" con il conto alla rovescia per l'avvio automatico. L'immagine proviene da un ISO di prova con un conto alla rovescia più lungo; il valore predefinito è 10 secondi.

Il primo bersaglio reale è stato un VPS, non un computer fisico: la decisione è che la prima versione supporti solo VPS (KVM), mentre il bare metal arriva dopo. Abbiamo provato su un VPS Contabo con processore AMD EPYC (famiglia 23, Zen 1), 4 vCPU e 8 GiB di RAM, con rete virtio-net e disco virtio-scsi. Il primo tentativo ci ha sorpreso: l'ISO collegato come CD virtuale avviava la voce predefinita, l'immagine di produzione si è rifiutata di servire da un supporto di sola lettura e si è riavviata, così abbiamo ottenuto un ciclo infinito di menu, kernel, reset senza nulla di leggibile. Oggi un errore fatale nell'immagine di produzione lascia un messaggio sulla console per 60 secondi prima del riavvio e, da un supporto ottico, segnala che l'avvio è avvenuto da un supporto di sola lettura e si ferma. La modalità live in RAM (O3) ha poi aggirato il problema per il caso comune.

La voce Diagnostica è nata da questa esperienza: una macchina che non vediamo dobbiamo poterla interrogare su ciò che ha. Stampa CPU, RAM, rete, dischi e dispositivi PCI, misura la banda della memoria, il disco e la crittografia, e le stesse misure le emette come JSON sulla porta seriale. La scrittura su disco è consentita solo nello spazio non allocato e solo dopo aver digitato WIPE; nell'immagine qui sotto è stata saltata.

Schermata di diagnostica su un VPS Contabo (AMD EPYC, KVM, 4 vCPU): sistema, memoria, disco, dispositivi PCI, banda e latenza della RAM e misure crittografiche, tra cui 244 us per handshake mTLS, X25519 48 us, firma ECDSA 35,7 us e verifica 107 us.
Schermata di diagnostica su un VPS Contabo (AMD EPYC, KVM, 4 vCPU): sistema, memoria, disco, dispositivi PCI, banda e latenza della RAM e misure crittografiche, tra cui 244 us per handshake mTLS, X25519 48 us, firma ECDSA 35,7 us e verifica 107 us.

Che cosa è ancora aperto. L'hardware reale. Dopo la prima versione arriva il bare metal (avvio da USB, NVMe e AHCI, scheda di rete di un computer vero), insieme a IOMMU e Secure Boot, perché senza IOMMU un dispositivo malevolo o difettoso può scrivere su tutta la memoria. In questa versione non affermiamo nulla al riguardo.

L'handshake: da 1,2 ms a 0,24 ms

La prima misura della diagnostica sul VPS ha dato un numero scomodo: l'handshake mTLS, solo la crittografia lato server, richiedeva 1,2 ms. Su aarch64 usavamo già le istruzioni hardware AES e SHA, ma x86_64 non aveva nulla di simile per la chiave pubblica: RustCrypto è portabile e constant-time, e quindi anche lento. Tre modifiche lo hanno ridotto.

  • Per P-256 abbiamo adottato l'assembly nistz256 di OpenSSL e ring (ADR-130), con tabelle a base fissa per la firma e per la verifica delle firme della CA (ADR-110, ADR-111).
  • X25519 è stato riscritto su quattro arti a 64 bit con le istruzioni MULX/ADX (ADR-131).
  • Dopodiché abbiamo profilato anche il resto (ADR-132, ADR-200).
Handshake sul VPS: 1200 us prima, 237 us dopo assembly e tabelle; confronto A/B di memcpy nella stessa esecuzione, 278,8 us con il vecchio, 229,4 us con il nuovo; e prima e dopo per X25519 (da 146 a 48 us), firma ECDSA (da 673 a 34 us) e verifica (da 309 a 90 us).
Handshake sul VPS: 1200 us prima, 237 us dopo assembly e tabelle; confronto A/B di memcpy nella stessa esecuzione, 278,8 us con il vecchio, 229,4 us con il nuovo; e prima e dopo per X25519 (da 146 a 48 us), firma ECDSA (da 673 a 34 us) e verifica (da 309 a 90 us).
Misura sul VPS (server, microsecondi) Prima Dopo
handshake mTLS, tutta la crittografia 1200 circa 240 (237 nella misura del grafico, 244 nell'immagine)
X25519 146 48
firma ECDSA 673 34
verifica ECDSA 309 90 (107 nell'immagine)
handshake, vecchio memcpy, stesso boot 278,8 229,4 (-17,7%)

I numeri variano di circa il 10% da un'esecuzione all'altra, quindi abbiamo annotato un intervallo anziché un singolo valore. Nel complesso è circa un quinto del tempo di CPU per un handshake.

Che cosa abbiamo imparato su memcpy. Quando la crittografia è scesa, il profilo ha mostrato qualcosa che non ci aspettavamo: le funzioni mem* (memcpy, memmove, memset) consumavano il 7% dell'handshake, dal 13 al 39% del percorso dei record TLS (39% per 64 B, 13% per 4 KiB) e dal 17 al 34% della distribuzione dei PUBLISH. Le abbiamo sostituite con assembly SSE2 per x86_64 (ADR-200), con test differenziali rispetto all'implementazione di riferimento per tutte le dimensioni, gli allineamenti e le sovrapposizioni. Per chiamata sono da 55 a 75 cicli contro da 7 a 12 per 1–64 byte.

A sinistra: la quota di tempo del server nelle funzioni mem* prima della riscrittura (handshake 7%, record TLS 64 B 39%, 256 B 37%, 1 KiB 24%, distribuzione 17–34%). A destra: di quanto è più veloce ciascun percorso dopo (handshake 17,7%, 64 B 26,4%, 256 B 19,6%, 1 KiB 16,1%, 4 KiB 6,6%, distribuzione 7–34%).
A sinistra: la quota di tempo del server nelle funzioni mem* prima della riscrittura (handshake 7%, record TLS 64 B 39%, 256 B 37%, 1 KiB 24%, distribuzione 17–34%). A destra: di quanto è più veloce ciascun percorso dopo (handshake 17,7%, 64 B 26,4%, 256 B 19,6%, 1 KiB 16,1%, 4 KiB 6,6%, distribuzione 7–34%).
Percorso Quota di mem* prima Più veloce dopo
handshake 7% 17,7%
record TLS 64 B 39% 26,4%
record TLS 256 B 37% 19,6%
record TLS 1 KiB 24% 16,1%
record TLS 4 KiB 13% 6,6%
distribuzione dei messaggi dal 17 al 34% dal 7 al 34%

Come leggere il grafico: più piccolo è il record, maggiore è la parte di tempo dedicata alla copia, e quindi maggiore è il guadagno. Per i messaggi piccoli, che sono la maggior parte del traffico MQTT, è questo che conta.

Che cosa questo non significa. Su x86_64 nativo abbiamo misurato OpenSSL 3.5.5 solo come riferimento per l'assembly (ADR-130), non come confronto fra prodotti. Il confronto Linux più Mosquitto sullo stesso VPS (attività X11) non l'abbiamo ancora fatto. Per questo non affermiamo che urMQTT sia più veloce di Linux: non è stato misurato. I numeri qui sopra confrontano urMQTT con se stesso.

Il sovraccarico è stato il secondo risultato. Sul VPS, da un singolo Mac (RTT 35 ms), 128 client hanno prodotto 618 handshake al secondo, 256 client 393 e 512 client 67, con migliaia di connessioni rifiutate. Non era un plateau, ma un crollo. Le cause le abbiamo trovate nel codice (due sono confermate in QEMU/HVF, sul VPS non si sono potute riprodurre), più di una insieme: una connessione rifiutata riportava il client oltre il segmento successivo che portava un SYN cookie valido, il rifiuto con RST diceva al client di riprovare subito, e la ricezione era O(coda). La correzione (da ADR-080 a ADR-082) scarta il SYN che non sarebbe stato accettato, ricorda i flussi rifiutati, mantiene la ricezione in O(1) e conta gli handshake per core. È possibile (ipotesi, non verificata) che parte della causa fosse anche sul client: lo strumento di carico chiudeva per primo, per cui un singolo Mac con 16 384 porte effimere e un TIME_WAIT di 30 secondi era limitato a circa 550 connessioni al secondo. Per questo il vero limite del server non l'abbiamo ancora misurato.

Promessa 2: disco raw, ma con cura

Che cosa avevamo pianificato. Mantenere il layout proprio senza file system e aggiungere tutto ciò che un file system di solito offre: allineamento, crescita, discard, copie di sicurezza e verifiche. Perché non un file system. Ne abbiamo discusso e la decisione è confermata: urMQTT scrive un solo database, un solo log di telemetria e metadati propri, non servono directory, permessi né nomi di file, e ogni strato in più sarebbe altro codice nella parte fidata e un altro modo in cui una scrittura può sparire in silenzio. Il disco è GPT con una partizione ESP e una partizione dati urMQTT, su cui sta il layout proprio.

Che cosa abbiamo costruito (da S2 a S6).

  • Layout v2 (S2). Topologia del disco, allineamento a 1 MiB o alla dimensione I/O ottimale, blocchi fisici interi, coppia A/B di superblocchi con generazione (ADR-140). Il layout v1 il kernel lo rifiuta con un messaggio chiaro, e lo migra lo strumento offline urmqtt-disk migrate (ADR-141): per impostazione predefinita è una prova a secco, si copia e solo dopo si passa alla nuova versione, con ripristino e iniezione di errori a ogni scrittura.
  • Crescita (S3). All'avvio il disco può crescere (mai ridursi), e su virtio-blk anche durante il funzionamento, tramite l'interrupt di cambio di configurazione (ADR-142, ADR-143).
  • Discard e write-zeroes (S4). I dischi thin provisioned restituiscono lo spazio all'host. In un test il file qcow2 sull'host è sceso da 62 a 16 MiB dopo la scadenza dei segmenti di telemetria, e il ripristino non si fida mai del contenuto che è stato scartato.
  • Copia di sicurezza del database su disco (S5). Copia A/B con l'API di backup online di SQLite a passi di 16 pagine: il passo più lungo 4,6 ms contro 445 ms quando si copia in una sola chiamata. I commit durante la copia hanno avuto un massimo di 2,4 ms contro 2,2 ms senza copia. Se quick_check all'avvio fallisce, il database viene ripristinato dalla copia.
  • Scrubbing e avvio limitato (S6). Lo scrubber legge il disco con un budget I/O limitato e segnala i record danneggiati, mentre l'avvio legge solo il segmento più recente di ogni partizione, così il tempo di avvio non cresce con la dimensione della regione di telemetria. Con questo abbiamo chiuso un problema che avevamo calcolato in anticipo: su un disco grande il ripristino completo richiederebbe da minuti a decine di minuti.

L'intero gruppo di smoke test per l'archiviazione passa su entrambe le architetture: 79 riusciti, 0 falliti, su aarch64 sotto HVF e su x86_64 sotto TCG. Abbiamo misurato anche che S4 non ha rallentato il database: 53,3 mila inserimenti al secondo in batch prima e dopo, senza differenza misurabile.

Che cosa ci ha sorpreso. Quanto di un layout "semplice" sia fatto di casi limite: virtio-scsi e virtio-blk riportano la topologia in modi diversi, e una scrittura incompleta a metà migrazione deve sempre lasciare almeno una versione valida. Per questo ogni scrittura sul percorso di migrazione e di crescita è passata dall'iniezione di errori.

Che cosa è ancora aperto. Le pagine di SQLite non hanno checksum, quindi un bit modificato all'interno di un valore in una riga il database non lo rileva; i record di telemetria e il contenuto delle copie hanno un CRC e vengono individuati. La cifratura del disco (S7) non è finita.

Promessa 3: sicurezza dimostrabile, per quanto ci riesca

Rinforzo (H4). L'allocatore azzera la memoria liberata e la verifica al riutilizzo, rileva il double free, collega i puntatori della free list con XOR e azzera le chiavi alla liberazione (ADR-170). Protezione dello stack (-Zstack-protector=strong, 1315 funzioni, mentre SQLite con -fstack-protector-strong, ADR-171). I report di errore in produzione non contengono registri né indirizzi (ADR-172). KASLR su entrambe le architetture: il kernel è PIE e Limine lo sposta di circa 19 bit, mentre heap, stack e finestra MMIO sono posizionati in modo casuale (ADR-173). Su aarch64 MTE marca l'heap (ADR-174), ma solo sotto TCG: HVF e x86 non ce l'hanno. kCFI lo abbiamo valutato e non l'abbiamo adottato perché il compilatore sul nightly fissato va in crash con un errore interno; IOMMU è rinviato insieme al bare metal (ADR-175, ADR-176).

Il costo è misurato, non presunto. Sul percorso dell'handshake (dp-bench, aarch64 HVF, handshake completi TLS 1.3 + mTLS + CONNECT):

Passo 1 core 4 core Variazione
senza rinforzo 1941 7620
+ allocatore 1898 7429 da -2,2% a -2,5%
+ protezione dello stack 1845 7243 insieme da -4,9% a -5%
+ PIE e marcatura circa 1800 circa 6750 su un computer carico, rumoroso

Nel complesso, quindi, il costo sul percorso dell'handshake è circa il 5% per le parti misurate in modo pulito, e con PIE e marcatura risulta circa il 7% su un core e circa l'11% su quattro, ma questa misura è rumorosa. La riteniamo accettabile, ma non l'abbiamo ripetuta sul VPS x86_64.

Vale la pena confrontarlo con il numero del primo articolo (862 handshake al secondo su un solo core). Lo stesso strumento oggi, con il motore di cifratura hardware su aarch64 (X0b) e una serie di ottimizzazioni arrivate da allora, dà 1941 prima del rinforzo. Non abbiamo isolato il contributo di ogni modifica, quindi sulla causa non affermiamo nulla.

Come è stato verificato, e che cosa no. H5 ha aggiunto Miri su un sottoinsieme di crate host, dimostrazioni con Kani, sanitizer, un model-fuzzer per le ACL e report di copertura. Kani ha dimostrato record_len in TLS, parse in TCP e due aritmetiche della timer wheel. Non è dimostrato (tempo scaduto): entrambi i decoder MQTT, entrambi i parsing della configurazione e il comportamento della timer wheel; il job CI per Kani quindi non è ancora bloccante. Miri non può eseguire assembly. Supply chain (H9): SBOM CycloneDX con 215 componenti, cargo-vet passa con 39 revisioni complete e 140 eccezioni, e cargo-deny è configurato per trattare gli avvisi di vulnerabilità come fallimento della CI (questi job CI finora sono stati provati solo in locale, non su GitHub, e il test negativo non è stato eseguito), insieme a VULNERABILITY-HANDLING.md. Lo stato onesto: delle 67 versioni di crate di terzi collegate al kernel, 53 sono eccezioni, non revisioni. Vet dimostra che l'insieme delle dipendenze non può cambiare senza una differenza visibile, non che il TCB sia stato revisionato. Una nostra revisione di un crate non l'abbiamo scritta.

SNTP (T1) è in questo senso una piccola storia di sicurezza: è opzionale, solo verso server IPv4 privati, con salto massimo e con la condizione che le fonti concordino (mediana, maggioranza entro un secondo). Un orologio che chiunque sul percorso può spostare non è un orologio di cui ci si possa fidare per la validità dei certificati.

Sul Mac: aarch64 nativo e x86_64 in emulazione

Sviluppiamo su un Mac, e questo ha due modi di eseguire lo stesso codice, molto diversi tra loro.

aarch64 sotto HVF x86_64 sotto TCG
Che cos'è esecuzione nativa, velocità vicina a quella di un processore reale QEMU emula le istruzioni
Handshake nel guest circa 0,58 ms (misurato la prima volta intorno a M13); dp-bench oggi 1941/s per core circa 3,3 ms
Scenari smoke TLS veloci circa 15 minuti per scenario
MTE no (su HVF non c'è) x86 non ce l'ha; la marcatura dell'heap funziona solo per un guest aarch64 sotto TCG
A che cosa serve misure reali correttezza: il percorso x86 viene verificato, i numeri non sono prestazioni

La regola è semplice: i numeri sotto TCG sono emulazione e non li citiamo come prestazioni. Le prestazioni x86 le misuriamo solo su un VPS vero. Per questo i numeri crittografici qui sopra vengono dal VPS Contabo, non dal Mac.

Lezioni

  • Misurate su una macchina reale prima di ottimizzare. Il primo approccio è stato ottimizzare ciò che pensavamo fosse lento; solo la diagnostica sul VPS ha mostrato 1,2 ms e dove va a finire esattamente il tempo.
  • Il sovraccarico è una funzionalità a sé. Un sistema veloce sotto carico può crollare oltre di esso; rifiutare deve costare meno che accettare.
  • Il profilo sorprende. Il maggior guadagno singolo per i messaggi piccoli non era nella crittografia, ma nella copia della memoria.
  • Un disco senza file system richiede più lavoro, non meno. Ciò che un file system di solito offre (allineamento, crescita, discard, copie, verifiche) dobbiamo scriverlo e verificarlo da soli, ogni passo con iniezione di errori.
  • Onestà nei numeri. Le misure di memoria su un VPS condiviso variano fino a 10 volte tra le esecuzioni e non dicono nulla sul codice, quindi non le riportiamo. I numeri crittografici sono stabili entro circa il 10%.
  • La velocità di sviluppo non è maturità. Test e ADR crescono insieme al codice, ma quattro giorni non sono un vero esercizio.

Che cosa viene dopo

  • H6: SQLite isolato a livello EL0, così che un errore nel database non apra il kernel.
  • H7: il resto della sicurezza del tempo (NTS e gestione dei salti); SNTP è solo il primo passo.
  • X11: confronto con Linux e Mosquitto sullo stesso VPS, solo allora ha senso parlare di velocità relativa.
  • Rilascio: la prima pubblicazione per VPS (KVM), con artefatti firmati e istruzioni.
  • Dopo il rilascio: bare metal (da X12 a X16), IOMMU e Secure Boot, e cifratura del disco.

Il codice è su github.com/zeljan-alduk/urMQTT, e docs/PROGRESS.md resta l'unica fonte di verità su ciò che funziona davvero. Pre-alfa, come prima; segnalazioni di errori e di sicurezza secondo le indicazioni in SECURITY.md sono benvenute.

Commenti

Regole dei commenti

Regole dei commenti

I commenti servono a condividere esperienze e domande sui temi del blog. Queste regole mantengono la discussione utile per tutti.

  1. Cortesia Niente insulti, minacce, molestie, incitamento all'odio o discriminazione per qualsiasi motivo. Criticate l'argomento, non la persona.
  2. In tema Un commento deve riguardare l'articolo o la discussione che lo segue.
  3. Niente pubblicità o spam Niente pubblicità, catene di messaggi o link senza contesto. Link e immagini sono benvenuti quando arricchiscono la discussione.
  4. Privacy altrui Non pubblicate dati personali di altri: nomi completi di privati, indirizzi, telefoni, e-mail, foto senza consenso.
  5. Diritto d'autore Pubblicate solo contenuti che potete condividere. Citando, indicate la fonte.
  6. Una sola identità Usate un solo nickname e non spacciatevi per qualcun altro.
  7. Conferma via e-mail Un commento viene pubblicato solo dopo la conferma del link inviato via e-mail. L'indirizzo non viene mostrato né usato per altro; i commenti non confermati vengono eliminati dopo 48 ore.
  8. Moderazione I commenti che violano le regole vengono nascosti o eliminati senza preavviso e una discussione può essere bloccata. Le decisioni dei moderatori sono definitive.
  9. Responsabilità L'autore è responsabile del contenuto del commento. I commenti non riflettono le opinioni di ALDO TECH.
  10. Segnalazioni Segnalate i contenuti inappropriati a info@aldo.tech.