Email Resistente al Quantum: Come utilizziamo cassette postali SQLite criptate per mantenere la tua email sicura
Prefazione
Important
Il nostro servizio email è 100% open-source e focalizzato sulla privacy tramite cassette postali SQLite sicure e criptate.
Fino al lancio del supporto IMAP, utilizzavamo MongoDB per le nostre esigenze di archiviazione dati persistente.
Questa tecnologia è straordinaria e la usiamo ancora oggi – ma per avere la crittografia a riposo con MongoDB è necessario utilizzare un provider che offra MongoDB Enterprise, come Digital Ocean o Mongo Atlas – oppure pagare una licenza enterprise (e di conseguenza dover gestire i tempi di risposta del team commerciale).
Il nostro team di Forward Email aveva bisogno di una soluzione di archiviazione crittografata, scalabile, affidabile e amichevole per gli sviluppatori per le cassette postali IMAP. Come sviluppatori open-source, usare una tecnologia per cui è necessario pagare una licenza per ottenere la crittografia a riposo andava contro i nostri principi – così abbiamo sperimentato, ricercato e sviluppato una nuova soluzione da zero per soddisfare queste esigenze.
Invece di usare un database condiviso per memorizzare le tue cassette postali, le memorizziamo e crittografiamo individualmente con la tua password (che solo tu possiedi). Il nostro servizio email è così sicuro che se dimentichi la tua password, perdi la tua casella (e devi recuperare con backup offline o ricominciare da capo).
Continua a leggere mentre approfondiamo con un confronto tra provider di servizi email, come funziona il nostro servizio, la nostra tecnologia e altro.
Confronto tra provider di servizi email
Siamo l’unico provider di servizi email 100% open-source e focalizzato sulla privacy che memorizza cassette postali SQLite criptate individualmente, offre domini, alias e utenti illimitati, e supporta SMTP in uscita, IMAP e POP3:
A differenza di altri provider email, con Forward Email non devi pagare per lo spazio di archiviazione su base per dominio o alias. Lo spazio è condiviso su tutto il tuo account – quindi se hai più nomi di dominio personalizzati e più alias per ciascuno, siamo la soluzione perfetta per te. Nota che puoi comunque imporre limiti di archiviazione se desideri su base per dominio o alias.
Leggi il Confronto tra Servizi Email
Come funziona
-
Usando il tuo client email come Apple Mail, Thunderbird, Gmail o Outlook – ti connetti ai nostri server IMAP sicuri usando il tuo nome utente e password:
- Il tuo nome utente è il tuo alias completo con il dominio, ad esempio
hello@example.com. - La tua password è generata casualmente e mostrata solo a te per 30 secondi quando clicchi su Genera Password da Il Mio Account Domini Alias.
- Il tuo nome utente è il tuo alias completo con il dominio, ad esempio
-
Una volta connesso, il tuo client di posta invierà comandi del protocollo IMAP al nostro server IMAP per mantenere la tua casella di posta sincronizzata. Questo include la scrittura e la memorizzazione di bozze di email e altre azioni che potresti fare (ad esempio, etichettare un'email come Importante o contrassegnare un'email come Spam/Posta Indesiderata).
-
I server di scambio mail (comunemente noti come server "MX") ricevono nuove email in arrivo e le memorizzano nella tua casella di posta. Quando ciò accade, il tuo client di posta viene notificato e sincronizza la tua casella. I nostri server di scambio mail possono inoltrare la tua email a uno o più destinatari (inclusi i webhook), memorizzare la tua email per te nel tuo spazio IMAP crittografato con noi, o entrambi!
Tip
Interessato a saperne di più? Leggi come configurare l'inoltro email, come funziona il nostro servizio di scambio mail, o consulta le nostre guide.
-
Dietro le quinte, il nostro design di archiviazione email sicura funziona in due modi per mantenere le tue caselle di posta crittografate e accessibili solo da te:
-
Quando arriva una nuova mail per te da un mittente, i nostri server di scambio mail scrivono in una casella di posta individuale, temporanea e crittografata per te.
-
Quando ti connetti al nostro server IMAP con il tuo client di posta, la tua password viene crittografata in memoria e usata per leggere e scrivere nella tua casella di posta. La tua casella può essere letta e scritta solo con questa password. Tieni presente che, poiché sei l'unico a possedere questa password, solo tu puoi leggere e scrivere nella tua casella quando la stai utilizzando. La prossima volta che il tuo client di posta tenterà di controllare la posta o sincronizzarsi, i nuovi messaggi verranno trasferiti da questa casella temporanea e memorizzati nel file della tua casella reale usando la password fornita. Nota che questa casella temporanea viene poi svuotata e cancellata in modo che solo la tua casella protetta da password contenga i messaggi.
-
Se sei connesso a IMAP (ad esempio usando un client di posta come Apple Mail o Thunderbird), allora non è necessario scrivere su uno storage temporaneo su disco. La tua password IMAP crittografata in memoria viene invece recuperata e usata. In tempo reale, quando un messaggio sta per essere consegnato a te, inviamo una richiesta WebSocket a tutti i server IMAP chiedendo se hanno una sessione attiva per te (questa è la parte di fetch), e successivamente passeremo quella password crittografata in memoria – così non dobbiamo scrivere in una casella temporanea, possiamo scrivere direttamente nella tua casella crittografata usando la tua password crittografata.
-
-
I backup delle tue caselle di posta crittografate vengono effettuati quotidianamente. Puoi anche richiedere un nuovo backup in qualsiasi momento o scaricare l'ultimo backup da Il Mio Account Domini Alias. Se decidi di passare a un altro servizio email, puoi facilmente migrare, scaricare, esportare e cancellare le tue caselle e i backup in qualsiasi momento.
Tecnologie
Database
Abbiamo esplorato altri possibili livelli di archiviazione database, tuttavia nessuno ha soddisfatto le nostre esigenze quanto SQLite:
| Database | Crittografia a riposo | Caselle di posta Sandboxed | Licenza | Usato Ovunque |
|---|---|---|---|---|
| SQLite ⭐ | ✅ Sì con SQLite3MultipleCiphers | ✅ | ✅ Pubblico Dominio | ✅ |
| MongoDB | ❌ "Disponibile solo in MongoDB Enterprise" | ❌ Database relazionale | ❌ AGPL e SSPL-1.0 |
❌ |
| rqlite | ❌ Solo rete | ❌ Database relazionale | ✅ MIT |
❌ |
| dqlite | ❌ Non testato e non ancora supportato? | ❌ Non testato e non ancora supportato? | ✅ LGPL-3.0-only |
❌ |
| PostgreSQL | ✅ Sì | ❌ Database relazionale | ✅ PostgreSQL (simile a BSD o MIT) |
❌ |
| MariaDB | ✅ Solo per InnoDB | ❌ Database relazionale | ✅ GPLv2 e BUSL-1.1 |
❌ |
| CockroachDB | ❌ Funzionalità solo Enterprise | ❌ Database relazionale | ❌ BUSL-1.1 e altri |
❌ |
Ecco un post sul blog che confronta diverse opzioni di archiviazione del database SQLite nella tabella sopra.
Sicurezza
In ogni momento utilizziamo crittografia a riposo (AES-256), crittografia in transito (TLS), DNS over HTTPS ("DoH") usando 🍊 Tangerine, e la crittografia sqleet (ChaCha20-Poly1305) sulle caselle di posta. Inoltre utilizziamo l'autenticazione a due fattori basata su token (invece di SMS che è suscettibile a attacchi man-in-the-middle), chiavi SSH ruotate con accesso root disabilitato, accesso esclusivo ai server tramite indirizzi IP limitati e altro ancora. In caso di un attacco evil maid o di un dipendente infedele di un fornitore terzo, la tua casella di posta può comunque essere aperta solo con la password che hai generato tu. Stai tranquillo, non ci affidiamo a nessun fornitore terzo oltre ai nostri provider di server conformi SOC Type 2 come Cloudflare, DataPacket, Digital Ocean, GitHub e Vultr.
Il nostro obiettivo è avere il minor numero possibile di punti singoli di guasto.
Caselle di posta
tldr; I nostri server IMAP utilizzano database SQLite crittografati individualmente per ciascuna delle tue caselle di posta.
SQLite è un database embedded estremamente popolare – attualmente è in esecuzione sul tuo telefono e computer – e utilizzato da quasi tutte le principali tecnologie.
Ad esempio, sui nostri server crittografati c’è un database SQLite per la casella linux@example.com, info@example.com, hello@example.com e così via – uno per ciascuna come file database .sqlite. Non nominiamo i file database con l’indirizzo email – invece usiamo BSON ObjectID e UUID unici generati che non rivelano a chi appartiene la casella o quale indirizzo email rappresentano (es. 353a03f21e534321f5d6e267.sqlite).
Ognuno di questi database è crittografato usando la tua password (che solo tu possiedi) tramite sqleet (ChaCha20-Poly1305). Questo significa che le tue caselle sono crittografate individualmente, autonome, sandboxed e portatili.
Abbiamo ottimizzato SQLite con i seguenti PRAGMA:
PRAGMA |
Scopo |
|---|---|
cipher=chacha20 |
Crittografia del database SQLite ChaCha20-Poly1305. Consulta better-sqlite3-multiple-ciphers sotto Projects per maggiori dettagli. |
key="****************" |
Questa è la tua password decrittata solo in memoria che viene passata tramite la connessione IMAP del tuo client email al nostro server. Nuove istanze di database vengono create e chiuse per ogni sessione di lettura e scrittura (per garantire sandboxing e isolamento). |
journal_mode=WAL |
Write-ahead-log ("WAL") che migliora le prestazioni e permette accessi di lettura concorrenti. |
busy_timeout=5000 |
Previene errori di blocco in scrittura mentre altre scritture sono in corso. |
synchronous=NORMAL |
Aumenta la durabilità delle transazioni senza rischio di corruzione dati. |
foreign_keys=ON |
Impone che i riferimenti alle chiavi esterne (es. una relazione da una tabella a un’altra) siano rispettati. Di default non è attivato in SQLite, ma per la validazione e integrità dei dati dovrebbe essere abilitato. |
encoding='UTF-8' |
Codifica predefinita da usare per garantire coerenza agli sviluppatori. |
Tutti gli altri valori predefiniti provengono da SQLite come specificato nella documentazione ufficiale PRAGMA.
Concorrenza
tldr; Usiamo
WebSocketper letture e scritture concorrenti nelle tue cassette postali SQLite criptate.
Letture
Il tuo client email sul telefono potrebbe risolvere imap.forwardemail.net in uno dei nostri indirizzi IP Digital Ocean – e il tuo client desktop potrebbe risolvere un IP separato da un diverso provider.
Indipendentemente da quale server IMAP il tuo client email si connetta, vogliamo che la connessione legga dal tuo database in tempo reale con il 100% di accuratezza. Questo viene fatto tramite WebSockets.
Scritture
Scrivere nel tuo database è un po' diverso – dato che SQLite è un database embedded e la tua cassetta postale risiede in un singolo file di default.
Abbiamo esplorato opzioni come litestream, rqlite e dqlite di seguito – tuttavia nessuna di queste ha soddisfatto i nostri requisiti.
Per eseguire scritture con il write-ahead-logging ("WAL") abilitato – dobbiamo assicurarci che solo un server ("Primario") sia responsabile di farlo. WAL accelera drasticamente la concorrenza e permette un solo scrittore e più lettori.
Il Primario è in esecuzione sui server dati con i volumi montati contenenti le cassette postali criptate. Dal punto di vista della distribuzione, potresti considerare tutti i singoli server IMAP dietro imap.forwardemail.net come server secondari ("Secondari").
Realizziamo una comunicazione bidirezionale con WebSockets:
- I server Primari usano un'istanza del server
WebSocketServerdi ws. - I server Secondari usano un'istanza client
WebSocketdi ws avvolta con websocket-as-promised e reconnecting-websocket. Questi due wrapper assicurano che ilWebSocketsi ricolleghi e possa inviare e ricevere dati per scritture specifiche nel database.
Backup
tldr; I backup delle tue cassette postali criptate vengono effettuati quotidianamente. Puoi anche richiedere istantaneamente un nuovo backup o scaricare l'ultimo backup in qualsiasi momento da Il Mio Account Domini Alias.
Per i backup, eseguiamo semplicemente il comando SQLite VACUUM INTO ogni giorno durante l'elaborazione dei comandi IMAP, che sfrutta la tua password criptata da una connessione IMAP in memoria. I backup vengono salvati se non viene rilevato un backup esistente o se l'hash SHA-256 è cambiato sul file rispetto all'ultimo backup più recente.
Nota che usiamo il comando VACUUM INTO invece del comando backup integrato perché se una pagina viene modificata durante un'operazione di comando backup, allora deve ricominciare da capo. Il comando VACUUM INTO scatta un'istantanea. Vedi questi commenti su GitHub e Hacker News per maggiori dettagli.
Inoltre usiamo VACUUM INTO invece di backup, perché il comando backup lascerebbe il database non criptato per un breve periodo fino a quando non viene invocato rekey (vedi questo commento GitHub commento per approfondimenti).
Il Secondario istruirà il Primario tramite la connessione WebSocket per eseguire il backup – e il Primario riceverà il comando per farlo e successivamente:
- Si connetterà alla tua cassetta postale criptata.
- Acquisirà un lock di scrittura.
- Eseguirà un checkpoint WAL tramite
wal_checkpoint(PASSIVE). - Eseguirà il comando SQLite
VACUUM INTO. - Verificherà che il file copiato possa essere aperto con la password criptata (protezione/garanzia).
- Lo caricherà su Cloudflare R2 per l'archiviazione (o sul tuo provider se specificato).
Ricorda che le tue caselle di posta sono criptate – e mentre abbiamo restrizioni IP e altre misure di autenticazione in atto per la comunicazione WebSocket – in caso di un attore malevolo, puoi stare tranquillo che a meno che il payload WebSocket non contenga la tua password IMAP, non può aprire il tuo database.
Al momento viene memorizzato un solo backup per casella di posta, ma in futuro potremmo offrire il recupero puntuale ("PITR").
Ricerca
I nostri server IMAP supportano il comando SEARCH con query complesse, espressioni regolari e altro.
Le prestazioni di ricerca rapide sono grazie a FTS5 e sqlite-regex.
Memorizziamo i valori Date nelle caselle SQLite come stringhe ISO 8601 tramite Date.prototype.toISOString (con fuso orario UTC affinché le comparazioni di uguaglianza funzionino correttamente).
Sono inoltre memorizzati indici per tutte le proprietà presenti nelle query di ricerca.
Progetti
Ecco una tabella che illustra i progetti che utilizziamo nel nostro codice sorgente e nel processo di sviluppo (ordinati alfabeticamente):
| Progetto | Scopo |
|---|---|
| Ansible | Piattaforma di automazione DevOps per mantenere, scalare e gestire con facilità l'intera flotta di server. |
| Bree | Scheduler di job per Node.js e JavaScript con supporto per cron, date, ms, later e formati umani. |
| Cabin | Libreria di logging JavaScript e Node.js amichevole per sviluppatori, con attenzione a sicurezza e privacy. |
| Lad | Framework Node.js che alimenta tutta la nostra architettura e design ingegneristico con MVC e altro. |
| MongoDB | Soluzione database NoSQL che usiamo per memorizzare tutti gli altri dati al di fuori delle caselle di posta (es. il tuo account, impostazioni, domini e configurazioni alias). |
| Mongoose | Object document modeling ("ODM") per MongoDB che usiamo in tutto il nostro stack. Abbiamo scritto helper speciali che ci permettono di continuare a usare Mongoose con SQLite 🎉 |
| Node.js | Node.js è l'ambiente di runtime JavaScript open-source e multipiattaforma che esegue tutti i nostri processi server. |
| Nodemailer | Pacchetto Node.js per inviare email, creare connessioni e altro. Siamo sponsor ufficiali di questo progetto. |
| Redis | Database in-memory per caching, canali publish/subscribe e richieste DNS over HTTPS. |
| SQLite3MultipleCiphers | Estensione di crittografia per SQLite che permette di criptare interi file di database (inclusi write-ahead-log ("WAL"), journal, rollback, …). |
| SQLiteStudio | Editor visuale SQLite (che potresti anche usare) per testare, scaricare e visualizzare caselle di posta di sviluppo. |
| SQLite | Livello di database embedded per uno storage IMAP scalabile, autonomo, veloce e resiliente. |
| Spam Scanner | Strumento Node.js anti-spam, filtro email e prevenzione phishing (nostra alternativa a Spam Assassin e rspamd). |
| Tangerine | Richieste DNS over HTTPS con Node.js e caching usando Redis – che garantisce coerenza globale e molto altro. |
| Thunderbird | Il nostro team di sviluppo usa questo (e lo raccomanda) come client email preferito da usare con Forward Email. |
| UTM | Il nostro team di sviluppo usa questo per creare macchine virtuali per iOS e macOS al fine di testare diversi client email (in parallelo) con i nostri server IMAP e SMTP. |
| Ubuntu | Sistema operativo server moderno open-source basato su Linux che alimenta tutta la nostra infrastruttura. |
| WildDuck | Libreria server IMAP – vedi le sue note su de-duplicazione allegati e supporto protocollo IMAP. |
| better-sqlite3-multiple-ciphers | Libreria API veloce e semplice per Node.js per interagire programmaticamente con SQLite3. |
| email-templates | Framework email amichevole per sviluppatori per creare, visualizzare in anteprima e inviare email personalizzate (es. notifiche account e altro). |
| json-sql-enhanced | Costruttore di query SQL usando sintassi in stile Mongo. Questo fa risparmiare tempo al nostro team di sviluppo poiché possiamo continuare a scrivere in stile Mongo in tutto lo stack con un approccio agnostico al database. Aiuta anche a evitare attacchi di SQL injection usando parametri di query. |
| knex-schema-inspector | Utility SQL per estrarre informazioni sullo schema di database esistente. Questo ci permette di validare facilmente che tutti gli indici, tabelle, colonne, vincoli e altro siano validi e corrispondano 1:1 a come dovrebbero essere. Abbiamo anche scritto helper automatici per aggiungere nuove colonne e indici se vengono fatte modifiche agli schemi di database (con avvisi di errore estremamente dettagliati). |
| knex | Costruttore di query SQL che usiamo solo per migrazioni di database e validazione schema tramite knex-schema-inspector. |
| mandarin | Traduzione automatica di frasi i18n con supporto per Markdown usando Google Cloud Translation API. |
| mx-connect | Pacchetto Node.js per risolvere e stabilire connessioni con server MX e gestire errori. |
| pm2 | Gestore di processi di produzione Node.js con bilanciatore di carico integrato (ottimizzato per le prestazioni). |
| smtp-server | Libreria server SMTP – la usiamo per i nostri server di scambio mail ("MX") e SMTP in uscita. |
| ImapTest | Strumento utile per testare server IMAP rispetto a benchmark e compatibilità con la specifica RFC del protocollo IMAP. Questo progetto è stato creato dal team di Dovecot (un server IMAP e POP3 open-source attivo da luglio 2002). Abbiamo testato ampiamente il nostro server IMAP con questo strumento. |
Puoi trovare altri progetti che utilizziamo in il nostro codice sorgente su GitHub.
Provider
| Provider | Scopo |
|---|---|
| Cloudflare | Provider DNS, controlli di integrità, bilanciatori di carico e storage di backup usando Cloudflare R2. |
| GitHub | Hosting del codice sorgente, CI/CD e gestione del progetto. |
| Digital Ocean | Hosting di server dedicati e database gestiti. |
| Vultr | Hosting di server dedicati. |
| DataPacket | Hosting di server dedicati. |
Considerazioni
Principi
Forward Email è progettato secondo questi principi:
- Essere sempre orientato agli sviluppatori, con attenzione alla sicurezza, alla privacy e alla trasparenza.
- Attenersi a MVC, Unix, KISS, DRY, YAGNI, Twelve Factor, Rasoio di Occam e dogfooding
- Rivolgersi agli sviluppatori intraprendenti, autofinanziati e ramen-profitable
Esperimenti
tldr; In definitiva, l’uso di storage oggetti compatibile con S3 e/o Tabelle Virtuali non è tecnicamente fattibile per motivi di prestazioni ed è soggetto a errori a causa di limitazioni di memoria.
Abbiamo condotto alcuni esperimenti che ci hanno portato alla nostra soluzione finale con SQLite come discusso sopra.
Uno di questi è stato provare a usare rclone e SQLite insieme a un livello di storage compatibile con S3.
Questo esperimento ci ha portato a comprendere meglio e scoprire casi limite riguardanti l’uso di rclone, SQLite e VFS:
- Se abiliti il flag
--vfs-cache-mode writescon rclone, allora le letture andranno bene, tuttavia le scritture verranno memorizzate nella cache.- Se hai più server IMAP distribuiti globalmente, allora la cache sarà disallineata tra loro a meno che tu non abbia un singolo scrittore e più ascoltatori (ad esempio un approccio pub/sub).
- Questo è incredibilmente complesso e aggiungere qualsiasi complessità ulteriore come questa comporterà più punti singoli di guasto.
- I provider di storage compatibili con S3 non supportano modifiche parziali ai file – il che significa che ogni modifica al file
.sqlitecomporterà una modifica completa e un nuovo caricamento del database. - Esistono altre soluzioni come
rsync, ma non sono focalizzate sul supporto del write-ahead-log ("WAL") – quindi abbiamo finito per esaminare Litestream. Fortunatamente il nostro uso della crittografia già cifra i file WAL per noi, quindi non dobbiamo fare affidamento su Litestream per questo. Tuttavia non eravamo ancora sicuri di Litestream per l’uso in produzione e abbiamo alcune note a riguardo più avanti. - Usare questa opzione
--vfs-cache-mode writes(l’unico modo per usare SQLite surcloneper scritture) tenterà di copiare l’intero database da zero in memoria – gestire una casella da 10 GB va bene, ma gestire più caselle con uno storage estremamente elevato farà sì che i server IMAP incontrino limitazioni di memoria e erroriENOMEM, fault di segmentazione e corruzione dei dati.
- Se provi a usare le Tabelle Virtuali di SQLite (ad esempio usando s3db) per avere dati direttamente su uno storage compatibile con S3, incontrerai diversi altri problemi:
- Le letture e scritture saranno estremamente lente poiché gli endpoint API S3 dovranno essere colpiti con metodi HTTP
GET,PUT,HEADePOST. - I test di sviluppo hanno mostrato che superare 500K-1M+ record su internet in fibra è ancora limitato dalla velocità di scrittura e lettura verso provider compatibili con S3. Ad esempio, i nostri sviluppatori hanno eseguito cicli
forper fare sia istruzioni SQLINSERTsequenziali sia scritture massive di grandi quantità di dati. In entrambi i casi le prestazioni erano incredibilmente lente. - Le tabelle virtuali non possono avere indici, istruzioni
ALTER TABLEe altre limitazioni – il che porta a ritardi di 1-2 minuti o più a seconda della quantità di dati. - Gli oggetti venivano memorizzati non criptati e non è disponibile un supporto nativo per la crittografia.
- Le letture e scritture saranno estremamente lente poiché gli endpoint API S3 dovranno essere colpiti con metodi HTTP
- Abbiamo anche esplorato l’uso di sqlite-s3vfs che è simile concettualmente e tecnicamente al punto precedente (quindi ha gli stessi problemi). Una possibilità sarebbe usare una build personalizzata di
sqlite3avvolta con crittografia come wxSQLite3 (che usiamo attualmente nella nostra soluzione sopra) tramite modifica del file di setup. - Un altro approccio potenziale era usare l’estensione multiplex, tuttavia questa ha una limitazione di 32 GB e richiederebbe costruzioni complesse e problemi di sviluppo.
- Le istruzioni
ALTER TABLEsono necessarie (quindi questo esclude completamente l’uso delle Tabelle Virtuali). Abbiamo bisogno delle istruzioniALTER TABLEaffinché il nostro hook conknex-schema-inspectorfunzioni correttamente – il che garantisce che i dati non vengano corrotti e che le righe recuperate possano essere convertite in documenti validi secondo le nostre definizioni di schemamongoose(che includono vincoli, tipi di variabili e validazione arbitraria dei dati). - Quasi tutti i progetti open-source relativi a SQLite compatibili con S3 sono in Python (e non in JavaScript che usiamo per il 100% del nostro stack).
- Le librerie di compressione come sqlite-zstd (vedi commenti) sembrano promettenti, ma potrebbero non essere ancora pronte per l’uso in produzione. Invece la compressione lato applicazione su tipi di dati come
String,Object,Map,Array,SeteBuffersarà un approccio più pulito e semplice (e più facile da migrare, dato che potremmo memorizzare un flag o colonnaBoolean– o anche usarePRAGMAuser_version=1per la compressione ouser_version=0per nessuna compressione come metadati del database).- Fortunatamente abbiamo già implementato la de-duplicazione degli allegati nel nostro storage del server IMAP – quindi ogni messaggio con lo stesso allegato non mantiene una copia dell’allegato – invece un singolo allegato è memorizzato per più messaggi e thread in una casella (e viene successivamente usato un riferimento esterno).
- Il progetto Litestream, che è una soluzione di replica e backup per SQLite, è molto promettente e probabilmente lo useremo in futuro.
- Non per sminuire l’autore/autori – perché amiamo il loro lavoro e contributi all’open-source da oltre un decennio – tuttavia dall’uso reale sembra che ci possano essere molti problemi e potenziali perdite di dati dall’uso.
- Il ripristino del backup deve essere senza attriti e banale. Usare una soluzione come MongoDB con
mongodumpemongoexportnon è solo tedioso, ma richiede molto tempo e ha complessità di configurazione.- I database SQLite lo rendono semplice (è un singolo file).
- Volevamo progettare una soluzione in cui gli utenti potessero prendere la loro casella e andarsene in qualsiasi momento.
- Comandi Node.js semplici come
fs.unlink('mailbox.sqlite')e viene cancellato definitivamente dallo storage su disco. - Possiamo similmente usare un’API compatibile con S3 con HTTP
DELETEper rimuovere facilmente snapshot e backup per gli utenti.
- Comandi Node.js semplici come
- SQLite è stata la soluzione più semplice, veloce e conveniente.
Mancanza di alternative
A nostra conoscenza, nessun altro servizio email è progettato in questo modo né è open-source.
Pensiamo che ciò possa essere dovuto al fatto che i servizi email esistenti utilizzano tecnologie legacy in produzione con spaghetti code 🍝.
La maggior parte, se non tutti, i fornitori di servizi email esistenti sono o closed-source o si pubblicizzano come open-source, ma in realtà solo il loro front-end è open-source.
La parte più sensibile dell'email (la vera e propria memorizzazione/interazione IMAP/SMTP) avviene tutta sul back-end (server), e non sul front-end (client).
Prova Forward Email
Iscriviti oggi su https://forwardemail.net! 🚀