Approfondimento: come utilizziamo le caselle di posta SQLite crittografate con sicurezza quantistica per il nostro servizio di posta elettronica sicuro e incentrato sulla privacy

A differenza di altri servizi di posta elettronica , ci assicuriamo che solo tu abbia accesso alla tua casella di posta in ogni momento.

Prefazione

tldr; Il nostro servizio di posta elettronica è 100% open source e incentrato sulla privacy tramite caselle di posta SQLite sicure e crittografate.

Fino al lancio Supporto IMAP, abbiamo utilizzato MongoDB per le nostre esigenze di archiviazione persistente dei dati.

Questa tecnologia è straordinaria e la usiamo ancora oggi, ma per avere la crittografia dei dati inattivi con MongoDB è necessario utilizzare un provider che offre MongoDB Enterprise, come Digital Ocean o Mongo Atlas, oppure pagare una licenza aziendale (e successivamente dovranno lavorare con la latenza del team di vendita).

Il nostro team di Inoltra email necessitava di una soluzione di archiviazione semplice da usare per gli sviluppatori, scalabile, affidabile e crittografata per le caselle di posta IMAP. In quanto sviluppatori open source, l'utilizzo di una tecnologia che richiede il pagamento di una tariffa di licenza per ottenere la funzionalità di crittografia dei dati inattivi era contro i nostri principi – e così abbiamo sperimentato, ricercato e sviluppato da zero una nuova soluzione per risolvere queste esigenze.

Invece di utilizzare un database condiviso per archiviare le tue caselle di posta, archiviamo e crittografiamo individualmente le tue caselle di posta con la tua password (che solo tu possiedi). Il nostro servizio di posta elettronica è così sicuro che se dimentichi la password perderai la tua casella di posta (e devi eseguire il ripristino con backup offline o ricominciare da capo).

Continua a leggere mentre facciamo un'analisi approfondita di seguito con a confronto tra fornitori di servizi di posta elettronica, come funziona il nostro servizio, il nostro stack tecnologicoe altro ancora.

Confronto tra fornitori di servizi di posta elettronica

Siamo l'unico fornitore di servizi di posta elettronica open source al 100% e incentrato sulla privacy che archivia caselle di posta SQLite crittografate individualmente, offre domini, alias e utenti illimitati e dispone del supporto SMTP, IMAP e POP3 in uscita:

A differenza di altri provider di posta elettronica, con Inoltra email non è necessario pagare per l'archiviazione in base al dominio o all'alias. Lo spazio di archiviazione è condiviso nell'intero account, quindi se disponi di più nomi di dominio personalizzati e più alias su ciascuno, allora siamo la soluzione perfetta per te. Tieni presente che puoi comunque applicare limiti di archiviazione, se lo desideri, in base al dominio o all'alias.

Leggi Confronto dei servizi di posta elettronica

Come funziona

  1. Utilizzando il tuo client di posta elettronica come Apple Mail, Thunderbird, Gmail o Outlook, ti connetti al nostro sistema sicuro IMAP server utilizzando il tuo nome utente e password:

    • Il tuo nome utente è il tuo alias completo con il tuo dominio come hello@example.com.
    • La tua password viene generata casualmente e ti viene mostrata solo per 30 secondi quando fai clic Genera password da Il mio account domini Alias.
  2. Una volta connesso, il tuo client di posta invierà Comandi del protocollo IMAP al nostro server IMAP per mantenere sincronizzata la tua casella di posta. Ciò include la scrittura e l'archiviazione di bozze di email e altre azioni che potresti eseguire (ad esempio etichettare un'email come importante o contrassegnare un'email come spam/posta indesiderata).

  3. I server di scambio di posta (comunemente noti come server "MX") ricevono la nuova posta elettronica in entrata e la archiviano nella tua casella di posta. Quando ciò accade, il tuo client di posta elettronica riceverà una notifica e sincronizzerà la tua casella di posta. I nostri server di scambio di posta possono inoltrare la tua email a uno o più destinatari (inclusi webhook), archivia la tua email per te nel tuo archivio IMAP crittografato presso di noi, o entrambi!

    Interessato a saperne di più? Leggere come impostare l'inoltro della posta elettronica, come funziona il nostro servizio di scambio postao visualizzare le nostre guide.

  4. Dietro le quinte, il nostro design di archiviazione sicura della posta elettronica funziona in due modi per mantenere le tue caselle di posta crittografate e accessibili solo a te:

    • Quando ricevi nuova posta da un mittente, i nostri server di scambio di posta scrivono per te in una casella di posta individuale, temporanea e crittografata.

      sequenceDiagram
          autonumber
          actor Sender
          Sender->>MX: Inbound message received for your alias (e.g. you@yourdomain.com).
          MX->>SQLite: Message is stored in a temporary mailbox.
          Note over MX,SQLite: Forwards to other recipients and webhooks configured.
          MX->>Sender: Success!
      
    • Quando ti connetti al nostro server IMAP con il tuo client di posta elettronica, la tua password viene quindi crittografata in memoria e utilizzata per leggere e scrivere nella tua casella di posta. La tua casella di posta può essere letta e scritta solo con questa password. Tieni presente che poiché sei l'unico con questa password, solo tu può leggere e scrivere nella tua casella di posta quando accedi ad essa. La prossima volta che il tuo client di posta tenta di eseguire il polling per la posta o sincronizzazioni, i tuoi nuovi messaggi verranno trasferiti da questa casella di posta temporanea e archiviati nel file della casella di posta reale utilizzando la password fornita. Tieni presente che questa casella di posta temporanea viene successivamente eliminata ed eliminata in modo che solo la tua casella di posta protetta da password contenga i messaggi.

    • Se sei connesso a IMAP (ad esempio utilizzando un client di posta elettronica come Apple Mail o Thunderbird), non è necessario scrivere sull'archivio temporaneo del disco. La tua password IMAP crittografata in memoria viene invece recuperata e utilizzata. In tempo reale, quando un messaggio tenta di esserti recapitato, inviamo una richiesta WebSocket a tutti i server IMAP chiedendo loro se hanno una sessione attiva per te (questa è la parte di recupero), e successivamente la passeremo password in memoria crittografata: quindi non abbiamo bisogno di scrivere su una casella di posta temporanea, possiamo scrivere sulla tua casella di posta crittografata effettiva utilizzando la tua password crittografata.

      sequenceDiagram
          autonumber
          actor You
          You->>IMAP: You connect to IMAP server using an email client.
          IMAP->>SQLite: Transfer message from temporary mailbox to your alias' mailbox.
          Note over IMAP,SQLite: Your alias' mailbox is only available in-memory using IMAP password.
          SQLite->>IMAP: Retrieves messages as requested by email client.
          IMAP->>You: Success!
      
  5. Backup delle tue caselle di posta crittografate vengono effettuati quotidianamente. Puoi anche richiedere un nuovo backup in qualsiasi momento o scaricare il backup più recente da Il mio account domini Alias. Se decidi di passare a un altro servizio di posta elettronica, puoi facilmente migrare, scaricare, esportare ed eliminare le tue caselle di posta e i tuoi backup in qualsiasi momento.

Tecnologie

Banche dati

Abbiamo esplorato altri possibili livelli di archiviazione del database, tuttavia nessuno ha soddisfatto i nostri requisiti tanto quanto SQLite:

Banca datiCrittografia a riposoSandbox Cassette postaliLicenzaUsato ovunque
SQLite✅ Sì con SQLite3MultipleCiphers✅ Dominio pubblico
MongoDB"Disponibile solo in MongoDB Enterprise"❌Database relazionale❌AGPL e SSPL-1.0
rqliteSolo rete❌Database relazionaleMIT
dqliteNon testato e non ancora supportato?Non testato e non ancora supportato?LGPL-3.0-only
PostgreSQL❌Database relazionalePostgreSQL (simile a BSD o MIT)
MariaDBSolo per InnoDB❌Database relazionaleGPLv2 e BUSL-1.1
Scarafaggio DBFunzionalità riservata alle aziende❌Database relazionaleBUSL-1.1 e altri

Ecco un post di blog che mette a confronto diverse opzioni di archiviazione del database SQLite nella tabella sopra.

Sicurezza

In ogni momento usiamo crittografia a riposo (AES-256), crittografia in transito (TLS), DNS su HTTPS ("DoH") utilizzando 🍊 mandarino, e sqlet (ChaCha20-Poly1305) crittografia sulle cassette postali. Inoltre utilizziamo l'autenticazione a due fattori basata su token (al contrario degli SMS che sono sospettabili). attacchi man-in-the-middle), chiavi SSH ruotate con accesso root disabilitato, accesso esclusivo ai server tramite indirizzi IP limitati e altro ancora.

Nel caso di un attacco della cameriera malvagia o dipendente disonesto di un fornitore terzo, la tua casella di posta può ancora essere aperta solo con la password generata. Stai tranquillo: non facciamo affidamento su fornitori di terze parti diversi dai nostri fornitori di server di reclamo SOC di tipo 2 di Cloudflare, Digital Ocean e Vultr.

Il nostro obiettivo è averne meno singolo punto di fallimento possibile.

Cassette postali

tldr; I nostri server IMAP utilizzano database SQLite crittografati individualmente per ciascuna delle tue caselle di posta.

SQLite è estremamente popolare database incorporato – è attualmente in esecuzione sul tuo telefono e computer – e utilizzato da quasi tutte le principali tecnologie.

Ad esempio, sui nostri server crittografati è presente una casella di posta del database SQLite per linux@example.com, info@example.com, hello@example.com e così via – uno per ciascuno come a .sqlite file della banca dati. Non nominiamo nemmeno i file del database con l'indirizzo e-mail: utilizziamo invece BSON ObjectID e UUID univoci generati che non condividono a chi appartiene la casella di posta o sotto quale indirizzo e-mail si trova (ad es. 353a03f21e534321f5d6e267.sqlite).

Ciascuno di questi database viene crittografato utilizzando la tua password (che solo tu possiedi). sqlet (ChaCha20-Poly1305). Ciò significa che le tue caselle di posta sono crittografate individualmente, autonome, sandboxe portatile.

Abbiamo ottimizzato SQLite con quanto segue PRAGMA:

PRAGMAScopo
cipher=chacha20Crittografia del database SQLite ChaCha20-Poly1305. Riferimento better-sqlite3-multiple-ciphers Sotto Progetti per maggiori informazioni.
key="****************"Questa è la tua password decrittografata solo in memoria che viene trasmessa attraverso la connessione IMAP del tuo client di posta elettronica al nostro server. Nuove istanze del database vengono create e chiuse per ogni sessione di lettura e scrittura (al fine di garantire sandboxing e isolamento).
journal_model=WALRegistro write-ahead ("WAL") che aumenta le prestazioni e consente l'accesso in lettura simultaneo.
busy_timeout=5000Previene gli errori di blocco della scrittura mentre sono in corso altre scritture.
synchronous=NORMALAumenta la durabilità delle transazioni senza rischio di corruzione dei dati.
foreign_keys=ONImpone l'applicazione dei riferimenti a chiavi esterne (ad esempio una relazione da una tabella a un'altra). Per impostazione predefinita, questo non è attivato in SQLite, ma per la convalida e l'integrità dei dati dovrebbe essere abilitato.
encoding='UTF-8'Codifica predefinita da utilizzare per garantire la sanità mentale dello sviluppatore.

Tutti gli altri valori predefiniti provengono da SQLite come specificato dal file documentazione ufficiale PRAGMA.

Concorrenza

tldr; Noi usiamo rclone e WebSocket per letture e scritture simultanee sulle tue caselle di posta SQLite crittografate.

Legge

Il tuo client di posta elettronica sul tuo telefono potrebbe risolversi imap.forwardemail.net a uno dei nostri indirizzi IP Digital Ocean – e il tuo client desktop potrebbe risolvere un IP separato da un altro fornitore del tutto.

Indipendentemente dal server IMAP a cui si connette il tuo client di posta elettronica, vogliamo che la connessione legga dal tuo database in tempo reale con una precisione del 100%:

  • Ciò si ottiene utilizzando rclone insieme a --vfs-cache-mode off (il predefinito).

  • Invece di utilizzare la cache del disco locale, la cache viene letta direttamente dal montaggio remoto (il tuo database) in tempo reale.

  • Nel caso in cui non sia possibile trovare il file locale, ciò lo indica rclone impossibile montarlo o presenta un problema. In questo caso usiamo a WebSocket fallback per le letture (che riduce leggermente le prestazioni, ma mantiene comunque l'integrità del servizio).

  • Ciascuno dei nostri server è configurato per montarsi con coerenza e avvisarci in tempo reale di eventuali errori.

Scrive

Scrivere nel tuo database è leggermente diverso, poiché SQLite è un database incorporato e la tua casella di posta risiede in un singolo file per impostazione predefinita.

Avevamo esplorato opzioni come litestream, rqlite, e dqlite di seguito, tuttavia nessuno di questi ha soddisfatto i nostri requisiti.

Per eseguire scritture con registrazione write-ahead ("WAL") abilitato: dobbiamo garantire che solo un server ("Primario") sia responsabile di ciò. WAL accelera drasticamente la concorrenza e consente uno scrittore e più lettori.

Il Primario è in esecuzione sui server di dati con i volumi montati contenenti le caselle di posta crittografate. Dal punto di vista della distribuzione, potresti considerare tutti i singoli server IMAP dietro imap.forwardemail.net essere server secondari ("Secondari").

Realizziamo una comunicazione bidirezionale con WebSocket:

  • I server primari utilizzano un'istanza di w'S WebSocketServer server.
  • I server secondari utilizzano un'istanza di w'S WebSocket client con cui è avvolto websocket-come-promesso e riconnessione-websocket. Questi due involucri assicurano che il WebSocket si riconnette e può inviare e ricevere dati per scritture di database specifiche.

Backup

tldr; I backup delle tue caselle di posta crittografate vengono effettuati quotidianamente. Puoi anche richiedere immediatamente un nuovo backup o scaricare il backup più recente in qualsiasi momento da Il mio account domini Alias.

Per i backup, eseguiamo semplicemente SQLite VACUUM INTO comando ogni giorno durante l'elaborazione del comando IMAP, che sfrutta la password crittografata da una connessione IMAP in memoria. I backup vengono archiviati se non viene rilevato alcun backup esistente o se il file SHA-256 l'hash è cambiato nel file rispetto al backup più recente.

Si noti che usiamo il VACUUM INTO comando rispetto al built-in backup comando perché se una pagina viene modificata durante a backup operazione di comando, è necessario ricominciare da capo. IL VACUUM INTO il comando scatterà uno snapshot. Vedi questi commenti su Git Hub e Notizie sugli hacker per maggiori informazioni.

Inoltre usiamo VACUUM INTO al contrario di backup, perché il backup il comando lascerebbe il database non crittografato per un breve periodo fino a quando rekey viene richiamato (vedi questo GitHub commento per approfondimento).

Il Secondario istruirà il Primario sul WebSocket connessione per eseguire il backup – e il Primario riceverà quindi il comando per farlo e successivamente:

  1. Connettiti alla tua casella di posta crittografata.
  2. Ottieni un blocco di scrittura.
  3. Esegui un checkpoint WAL tramite wal_checkpoint(PASSIVE).
  4. Corri il VACUUM INTO Comando SQLite.
  5. Assicurarsi che il file copiato possa essere aperto con la password crittografata (salvaguardia/dummyproofing).
  6. Caricalo su Cloudflare R2 per l'archiviazione (o sul tuo provider se specificato).
  7. Comprimi il file di backup risultante con gzip.
  8. Caricalo su Cloudflare R2 per l'archiviazione (o sul tuo provider se specificato).

Ricorda che le tue caselle di posta sono crittografate e, sebbene disponiamo di restrizioni IP e altre misure di autenticazione per la comunicazione WebSocket, in caso di malintenzionato, puoi essere certo che, a meno che il payload WebSocket non abbia la tua password IMAP, non potrà aprire il tuo database .

Al momento viene archiviato un solo backup per casella di posta, ma in futuro potremmo offrire il ripristino temporizzato ("PITR").

I nostri server IMAP supportano il SEARCH comando con query complesse, espressioni regolari e altro ancora.

Le prestazioni di ricerca veloci sono grazie a FTS5 e sqlite-regex.

Conserviamo Date valori nelle cassette postali SQLite come ISO 8601 stringhe tramite Date.prototype.toISOString (con fuso orario UTC affinché i confronti di uguaglianza funzionino correttamente).

Vengono inoltre archiviati gli indici per tutte le proprietà presenti nelle query di ricerca.

Progetti

Ecco una tabella che descrive i progetti che utilizziamo nel nostro codice sorgente e nel processo di sviluppo (in ordine alfabetico):

ProgettoScopo
AnsiblePiattaforma di automazione DevOps per mantenere, scalare e gestire con facilità il nostro intero parco di server.
BreePianificatore di processi per Node.js e JavaScript con supporto cron, date, ms, successivo e intuitivo.
CabinaLibreria di registrazione JavaScript e Node.js intuitiva per gli sviluppatori che tiene conto della sicurezza e della privacy.
PermettereFramework Node.js che alimenta la nostra intera architettura e progettazione ingegneristica con MVC e altro ancora.
MongoDBSoluzione di database NoSQL che utilizziamo per archiviare tutti gli altri dati al di fuori delle caselle di posta (ad esempio il tuo account, impostazioni, domini e configurazioni di alias).
MangustaMongoDB object document modeling ("ODM") che utilizziamo in tutto il nostro stack. Abbiamo scritto aiutanti speciali che ci consentono semplicemente di continuare a utilizzare Mangusta con SQLite 🎉
Nodo.jsNode.js è l'ambiente runtime JavaScript open source e multipiattaforma che esegue tutti i nostri processi server.
Nota mailerPacchetto Node.js per l'invio di e-mail, la creazione di connessioni e altro ancora. Siamo sponsor ufficiale di questo progetto.
RedisDatabase in memoria per memorizzazione nella cache, canali di pubblicazione/sottoscrizione e richieste DNS su HTTPS.
SQLite3MultipleCiphersEstensione di crittografia per SQLite per consentire la crittografia di interi file di database (incluso il log write-ahead ("WAL"), diario, rollback, ...).
SQLiteStudioEditor Visual SQLite (che potresti anche utilizzare) per testare, scaricare e visualizzare le caselle di posta di sviluppo.
SQLiteLivello di database integrato per uno storage IMAP scalabile, autonomo, veloce e resiliente.
Scanner antispamNode.js anti-spam, filtro email e strumento di prevenzione del phishing (la nostra alternativa a Assassino dello spam e rsspamd).
mandarinoRichieste DNS su HTTPS con Node.js e memorizzazione nella cache utilizzando Redis, che garantisce coerenza globale e molto altro ancora.
Uccello di tuonoIl nostro team di sviluppo lo utilizza (e lo consiglia anche) come il client di posta elettronica preferito da utilizzare con Inoltra email.
UTMIl nostro team di sviluppo utilizza queste macchine virtuali per iOS e macOS per testare diversi client di posta elettronica (in parallelo) con i nostri server IMAP e SMTP.
UbuntuModerno sistema operativo server open source basato su Linux che alimenta tutta la nostra infrastruttura.
Anatra selvaticaLibreria del server IMAP: vedere le note su deduplicazione degli allegati e Supporto del protocollo IMAP.
codici-multipli-meglio-sqlite3Libreria API veloce e semplice per Node.js per interagire con SQLite3 a livello di programmazione.
modelli di posta elettronicaFramework di posta elettronica intuitivo per gli sviluppatori per creare, visualizzare in anteprima e inviare e-mail personalizzate (ad esempio notifiche sull'account e altro).
json-sqlGeneratore di query SQL che utilizza la sintassi in stile Mongo. Ciò fa risparmiare tempo al nostro team di sviluppo poiché possiamo continuare a scrivere in stile Mongo sull'intero stack con un approccio indipendente dal database. Aiuta anche a evitare attacchi SQL injection utilizzando parametri di query.
knex-schema-ispettoreUtilità SQL per estrarre informazioni sullo schema del database esistente. Ciò ci consente di verificare facilmente che tutti gli indici, le tabelle, le colonne, i vincoli e altro sono validi e lo sono 1:1 con come dovrebbero essere. Abbiamo anche scritto helper automatizzati per aggiungere nuove colonne e indici se vengono apportate modifiche agli schemi del database (con avvisi di errore estremamente dettagliati).
knexGeneratore di query SQL che utilizziamo solo per le migrazioni di database e la convalida dello schema knex-schema-inspector.
mandarinoAutomatico i18n traduzione di frasi con supporto per l'utilizzo di Markdown API di traduzione di Google Cloud.
mx-connectPacchetto Node.js per risolvere e stabilire connessioni con server MX e gestire gli errori.
pm2Gestore del processo di produzione Node.js con bilanciatore del carico integrato (messo a punto per le prestazioni).
server smtpLibreria server SMTP: la utilizziamo per il nostro scambio di posta ("MX") e per i server SMTP in uscita.
ImapTestStrumento utile per testare i server IMAP rispetto ai benchmark e alla compatibilità del protocollo IMAP delle specifiche RFC. Questo progetto è stato creato da Colombaia team (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 in cui utilizziamo il nostro codice sorgente su GitHub.

Fornitori

FornitoreScopo
CloudflareProvider DNS, controlli di integrità, bilanciatori del carico e archiviazione di backup utilizzando Cloudflare R2.
Oceano DigitaleHosting di server dedicati, archiviazione a blocchi SSD e database gestiti.
VultrHosting di server dedicati e archiviazione a blocchi SSD.

Pensieri

I principi

Forward Email è progettato secondo questi principi:

  1. Sii sempre favorevole agli sviluppatori, attento alla sicurezza, alla privacy e trasparente.
  2. Aderire a MVC, Unix, KISS, DRY, YAGNI, Dodici fattori, rasoio di Occam, e cibo per cani
  3. Scegli come target gli scrappy, bootstrap e ramen-redditizio sviluppatore

Esperimenti

tldr; In definitiva, l'utilizzo dello storage di oggetti compatibile con S3 e/o delle tabelle virtuali non è tecnicamente fattibile per motivi di prestazioni ed è soggetto a errori a causa delle limitazioni di memoria.

Abbiamo effettuato alcuni esperimenti che hanno portato alla nostra soluzione SQLite finale, come discusso sopra.

Uno di questi era provare a usare rclone e SQLite insieme a un livello di archiviazione compatibile con S3.

Questo esperimento ci ha portato a comprendere e scoprire ulteriormente casi limite riguardanti rclone, SQLite e VFS utilizzo:

  • Se abiliti --vfs-cache-mode writes flag con rclone, le letture andranno bene, tuttavia le scritture verranno memorizzate nella cache.
    • Se disponi di più server IMAP distribuiti a livello globale, la cache sarà disattivata su di essi a meno che tu non abbia un singolo scrittore e più ascoltatori (ad esempio un approccio pub/sub).
    • Questo è incredibilmente complesso e l'aggiunta di ulteriore complessità come questa si tradurrà in più singoli punti di errore.
    • I fornitori di storage compatibili con S3 non supportano modifiche parziali ai file, il che significa che qualsiasi modifica del file .sqlite comporterà una modifica completa e il ricaricamento del database.
    • Altre soluzioni come rsync esistono, ma non sono focalizzati sul log write-ahead ("WAL") supporto, quindi abbiamo finito per recensire Litestream. Fortunatamente il nostro utilizzo della crittografia crittografa già il file WAL file per noi, quindi non abbiamo bisogno di fare affidamento su Litestream per questo. Tuttavia non eravamo ancora sicuri di Litestream per l'uso in produzione e di seguito abbiamo alcune note al riguardo.
    • Utilizzando questa opzione di --vfs-cache-mode writes (IL soltanto modo di utilizzare SQLite rclone per le scritture) tenterà di copiare l'intero database da zero in memoria: la gestione di una casella di posta da 10 GB è OK, tuttavia la gestione di più caselle di posta con spazio di archiviazione eccessivamente elevato causerà limitazioni di memoria e ENOMEM errori, errori di segmentazione e danneggiamento dei dati.
  • Se provi a utilizzare SQLite Tabelle virtuali (ad esempio utilizzando s3db) per avere i dati attivi su un livello di archiviazione compatibile con S3, si verificheranno molti altri problemi:
    • Le operazioni di lettura e scrittura saranno estremamente lente poiché gli endpoint API S3 dovranno essere colpiti con HTTP GET, PUT, HEAD, e POST metodi.
    • I test di sviluppo hanno dimostrato che superare i 500.000-1 milione di record su Internet in fibra è ancora limitato dalla velocità di scrittura e lettura verso i provider compatibili con S3. Ad esempio, i nostri sviluppatori hanno eseguito for loop per eseguire entrambi gli SQL sequenziali INSERT istruzioni e quelle che scrivono in blocco grandi quantità di dati. In entrambi i casi la performance è stata incredibilmente lenta.
    • Tavoli virtuali non può avere indici, ALTER TABLE dichiarazioni e altro limitazioni – che porta a ritardi fino a 1-2 minuti o più a seconda della quantità di dati.
    • Gli oggetti sono stati archiviati non crittografati e non è immediatamente disponibile alcun supporto di crittografia nativa.
  • Abbiamo anche esplorato l'utilizzo sqlite-s3vfs che è simile concettualmente e tecnicamente al punto precedente (quindi presenta gli stessi problemi). Una possibilità sarebbe quella di utilizzare un'abitudine sqlite3 build avvolto con crittografia come wxSQLite3 (che attualmente utilizziamo nella nostra soluzione sopra) through modifica del file di installazione.
  • Un altro potenziale approccio era utilizzare il file estensione multiplex, tuttavia questo ha una limitazione di 32 GB e richiederebbe complessi grattacapi di costruzione e sviluppo.
  • ALTER TABLE sono richieste istruzioni (quindi questo esclude completamente l'utilizzo delle tabelle virtuali). Abbiamo bisogno ALTER TABLE dichiarazioni in ordine per il nostro hook with knex-schema-inspector funzionare correttamente – il che garantisce che i dati non vengano danneggiati e che le righe recuperate possano essere convertite in documenti validi secondo il nostro mongoose definizioni di schema (che include vincolo, tipo di variabile e convalida arbitraria dei dati).
  • Quasi tutti i progetti compatibili con S3 relativi a SQLite nella comunità open source sono in Python (e non in JavaScript che utilizziamo per il 100% del nostro stack).
  • Librerie di compressione come sqlite-zstd (Vedere Commenti) sembrano promettenti, ma potrebbe non essere ancora pronto per l'utilizzo in produzione. Invece la compressione lato applicazione su tipi di dati come String, Object, Map, Array, Set, e Buffer sarà un approccio più pulito e semplice (ed è anche più facile da migrare, poiché potremmo archiviare un file Boolean flag o colonna – o addirittura utilizzare PRAGMA user_version=1 per compressione o user_version=0 senza compressione come metadati del database).
    • Fortunatamente abbiamo già implementato la deduplicazione degli allegati nel nostro archivio del server IMAP – quindi ogni messaggio con lo stesso allegato non manterrà una copia dell'allegato – invece un singolo allegato viene archiviato per più messaggi e thread in una casella di posta (e in una casella estranea viene successivamente utilizzato il riferimento).
  • Il progetto Litestream, che è una soluzione di replica e backup di SQLite, è molto promettente e molto probabilmente lo utilizzeremo in futuro.
  • Il ripristino del backup deve essere semplice e banale. Utilizzando una soluzione come MongoDB con mongodump e mongoexport non è solo noioso, ma richiede molto tempo e presenta complessità di configurazione.
    • I database SQLite lo rendono semplice (è un singolo file).
    • Volevamo progettare una soluzione in cui gli utenti potessero prendere la propria casella di posta e andarsene in qualsiasi momento.
      • Semplici comandi Node.js a fs.unlink('mailbox.sqlite')) e viene cancellato definitivamente dalla memoria del disco.
      • Allo stesso modo possiamo utilizzare un'API compatibile con S3 con HTTP DELETE per rimuovere facilmente istantanee e backup per gli utenti.
    • SQLite era la soluzione più semplice, veloce ed economica.

Mancanza di alternative

Per quanto ne sappiamo, nessun altro servizio di posta elettronica è progettato in questo modo né è open source.

Noi penso che questo potrebbe essere dovuto ai servizi di posta elettronica esistenti con tecnologia legacy in produzione codice spaghetti 🍝.

La maggior parte, se non tutti, i fornitori di servizi di posta elettronica esistenti sono closed-source o pubblicizzati come open-source, ma in realtà solo il loro front-end è open source.

La parte più sensibile dell'e-mail (l'effettiva interazione di archiviazione/IMAP/SMTP) è tutto fatto sul back-end (server), e non sul front-end (client).

Prova Inoltra e-mail

Iscriviti oggi a https://forwardemail.net! 🚀