Kwantumveilige E-mail: Hoe wij versleutelde SQLite-mailboxen gebruiken om uw e-mail veilig te houden
Voorwoord
Important
Onze e-mailservice is 100% open-source en privacygericht door middel van veilige en versleutelde SQLite-mailboxen.
Totdat we IMAP-ondersteuning lanceerden, gebruikten we MongoDB voor onze behoeften aan persistente gegevensopslag.
Deze technologie is geweldig en we gebruiken het nog steeds – maar om encryptie-at-rest met MongoDB te hebben, moet je een provider gebruiken die MongoDB Enterprise aanbiedt, zoals Digital Ocean of Mongo Atlas – of betalen voor een enterprise-licentie (en vervolgens te maken krijgen met vertragingen van het verkoopteam).
Ons team bij Forward Email had een ontwikkelaarsvriendelijke, schaalbare, betrouwbare en versleutelde opslagoplossing nodig voor IMAP-mailboxen. Als open-source ontwikkelaars was het tegen onze principes om een technologie te gebruiken waarvoor je een licentievergoeding moet betalen om de encryptie-at-rest functie te krijgen – dus hebben we geëxperimenteerd, onderzoek gedaan en een nieuwe oplossing vanaf nul ontwikkeld om aan deze behoeften te voldoen.
In plaats van een gedeelde database te gebruiken om uw mailboxen op te slaan, slaan we uw mailboxen individueel op en versleutelen we ze met uw wachtwoord (dat alleen u kent). Onze e-mailservice is zo veilig dat als u uw wachtwoord vergeet, u uw mailbox verliest (en moet herstellen met offline back-ups of opnieuw moet beginnen).
Lees verder terwijl we hieronder dieper ingaan met een vergelijking van e-mailserviceproviders, hoe onze service werkt, onze technologiestack en meer.
Vergelijking van e-mailserviceproviders
Wij zijn de enige 100% open-source en privacygerichte e-mailserviceprovider die individueel versleutelde SQLite-mailboxen opslaat, onbeperkte domeinen, aliassen en gebruikers aanbiedt, en ondersteuning heeft voor uitgaande SMTP, IMAP en POP3:
In tegenstelling tot andere e-mailproviders hoeft u bij Forward Email niet per domein of alias te betalen voor opslag. Opslag wordt gedeeld over uw hele account – dus als u meerdere aangepaste domeinnamen en meerdere aliassen op elk heeft, zijn wij de perfecte oplossing voor u. Houd er rekening mee dat u nog steeds opslaglimieten kunt afdwingen indien gewenst, per domein of alias.
Lees Vergelijking E-mailservices
Hoe werkt het
-
Met uw e-mailclient zoals Apple Mail, Thunderbird, Gmail of Outlook – maakt u verbinding met onze beveiligde IMAP servers met uw gebruikersnaam en wachtwoord:
- Uw gebruikersnaam is uw volledige alias met uw domein, zoals
hello@example.com. - Uw wachtwoord wordt willekeurig gegenereerd en wordt slechts 30 seconden aan u getoond wanneer u klikt op Wachtwoord genereren vanuit Mijn Account Domeinen Aliassen.
- Uw gebruikersnaam is uw volledige alias met uw domein, zoals
-
Zodra je verbonden bent, zal je e-mailclient IMAP-protocolcommando's naar onze IMAP-server sturen om je mailbox synchroon te houden. Dit omvat het schrijven en opslaan van concept-e-mails en andere acties die je mogelijk uitvoert (bijv. een e-mail markeren als Belangrijk of een e-mail markeren als Spam/Ongewenste Mail).
-
Mail exchange-servers (vaak bekend als "MX"-servers) ontvangen nieuwe inkomende e-mail en slaan deze op in je mailbox. Wanneer dit gebeurt, wordt je e-mailclient hiervan op de hoogte gesteld en synchroniseert je mailbox. Onze mail exchange-servers kunnen je e-mail doorsturen naar een of meer ontvangers (inclusief webhooks), je e-mail voor je opslaan in je versleutelde IMAP-opslag bij ons, of beide!
Tip
Geïnteresseerd om meer te leren? Lees hoe je e-mail doorsturen instelt, hoe onze mail exchange-service werkt, of bekijk onze handleidingen.
-
Achter de schermen werkt ons ontwerp voor veilige e-mailopslag op twee manieren om je mailboxen versleuteld te houden en alleen toegankelijk voor jou:
-
Wanneer er nieuwe mail voor je binnenkomt van een afzender, schrijven onze mail exchange-servers naar een individuele, tijdelijke en versleutelde mailbox voor jou.
-
Wanneer je verbinding maakt met onze IMAP-server met je e-mailclient, wordt je wachtwoord vervolgens in het geheugen versleuteld en gebruikt om je mailbox te lezen en te schrijven. Je mailbox kan alleen gelezen en beschreven worden met dit wachtwoord. Houd er rekening mee dat omdat jij de enige bent met dit wachtwoord, alleen jij je mailbox kunt lezen en schrijven wanneer je deze benadert. De volgende keer dat je e-mailclient probeert mail op te halen of te synchroniseren, worden je nieuwe berichten overgebracht van deze tijdelijke mailbox en opgeslagen in je daadwerkelijke mailboxbestand met behulp van je opgegeven wachtwoord. Let op dat deze tijdelijke mailbox daarna wordt geleegd en verwijderd zodat alleen je met een wachtwoord beveiligde mailbox de berichten bevat.
-
Als je verbonden bent met IMAP (bijv. met een e-mailclient zoals Apple Mail of Thunderbird), hoeven we niet naar tijdelijke schijfopslag te schrijven. Je in-memory versleutelde IMAP-wachtwoord wordt in plaats daarvan opgehaald en gebruikt. In realtime, wanneer een bericht aan jou wordt bezorgd, sturen we een WebSocket-verzoek naar alle IMAP-servers om te vragen of ze een actieve sessie voor jou hebben (dit is het ophalen), en vervolgens geven we dat versleutelde in-memory wachtwoord door – zodat we niet naar een tijdelijke mailbox hoeven te schrijven, maar direct naar je daadwerkelijke versleutelde mailbox kunnen schrijven met je versleutelde wachtwoord.
-
-
Back-ups van je versleutelde mailboxen worden dagelijks gemaakt. Je kunt ook op elk moment een nieuwe back-up aanvragen of de laatste back-up downloaden via Mijn Account Domeinen Aliassen. Als je besluit over te stappen naar een andere e-mailservice, kun je eenvoudig je mailboxen en back-ups migreren, downloaden, exporteren en verwijderen wanneer je maar wilt.
Technologieën
Databases
We hebben andere mogelijke database-opslaglagen onderzocht, maar geen enkele voldeed zo goed aan onze eisen als SQLite:
| Database | Encryptie in rust | Sandboxed Mailboxes | Licentie | Used Everywhere |
|---|---|---|---|---|
| SQLite ⭐ | ✅ Ja met SQLite3MultipleCiphers | ✅ | ✅ Public Domain | ✅ |
| MongoDB | ❌ "Alleen beschikbaar in MongoDB Enterprise" | ❌ Relationele database | ❌ AGPL en SSPL-1.0 |
❌ |
| rqlite | ❌ Alleen netwerk | ❌ Relationele database | ✅ MIT |
❌ |
| dqlite | ❌ Niet getest en nog niet ondersteund? | ❌ Niet getest en nog niet ondersteund? | ✅ LGPL-3.0-only |
❌ |
| PostgreSQL | ✅ Ja | ❌ Relationele database | ✅ PostgreSQL (vergelijkbaar met BSD of MIT) |
❌ |
| MariaDB | ✅ Alleen voor InnoDB | ❌ Relationele database | ✅ GPLv2 en BUSL-1.1 |
❌ |
| CockroachDB | ❌ Alleen Enterprise-functie | ❌ Relationele database | ❌ BUSL-1.1 en anderen |
❌ |
Hier is een blogpost die verschillende SQLite database opslagopties vergelijkt in de bovenstaande tabel.
Beveiliging
Te allen tijde gebruiken we encryptie in rust (AES-256), encryptie tijdens transport (TLS), DNS over HTTPS ("DoH") met 🍊 Tangerine, en sqleet (ChaCha20-Poly1305) encryptie op mailboxen. Daarnaast gebruiken we token-gebaseerde tweefactorauthenticatie (in tegenstelling tot SMS, dat vatbaar is voor man-in-the-middle-aanvallen), geroteerde SSH-sleutels met roottoegang uitgeschakeld, exclusieve toegang tot servers via beperkte IP-adressen, en meer. In het geval van een evil maid attack of een rogue medewerker van een derde partij, kan je mailbox nog steeds alleen worden geopend met jouw gegenereerde wachtwoord. Wees gerust, we vertrouwen niet op andere derde partijen dan onze SOC Type 2 compliant serverproviders Cloudflare, DataPacket, Digital Ocean, GitHub en Vultr.
Ons doel is om zo min mogelijk single point of failures te hebben.
Mailboxes
tldr; Onze IMAP-servers gebruiken individueel versleutelde SQLite-databases voor elk van jouw mailboxen.
SQLite is een extreem populaire embedded database – het draait momenteel op je telefoon en computer – en wordt gebruikt door bijna alle grote technologieën.
Bijvoorbeeld, op onze versleutelde servers is er een SQLite database mailbox voor linux@example.com, info@example.com, hello@example.com enzovoort – één voor elk als een .sqlite databasebestand. We noemen de databasebestanden ook niet met het e-mailadres – in plaats daarvan gebruiken we BSON ObjectID en unieke UUID's die niet onthullen van wie de mailbox is of onder welk e-mailadres het valt (bijv. 353a03f21e534321f5d6e267.sqlite).
Elk van deze databases is zelf versleuteld met jouw wachtwoord (dat alleen jij hebt) met behulp van sqleet (ChaCha20-Poly1305). Dit betekent dat je mailboxen individueel versleuteld, zelfvoorzienend, sandboxed en draagbaar zijn.
We hebben SQLite fijn afgestemd met de volgende PRAGMA:
PRAGMA |
Doel |
|---|---|
cipher=chacha20 |
ChaCha20-Poly1305 SQLite database encryptie. Zie better-sqlite3-multiple-ciphers onder Projects voor meer inzicht. |
key="****************" |
Dit is jouw alleen in het geheugen ontsleutelde wachtwoord dat via de IMAP-verbinding van je e-mailclient naar onze server wordt gestuurd. Nieuwe database-instanties worden aangemaakt en gesloten voor elke lees- en schrijfsessie (om sandboxing en isolatie te garanderen). |
journal_mode=WAL |
Write-ahead-log ("WAL") die de prestaties verbetert en gelijktijdige lees-toegang mogelijk maakt. |
busy_timeout=5000 |
Voorkomt write-lock fouten terwijl andere schrijfbewerkingen plaatsvinden. |
synchronous=NORMAL |
Verhoogt de duurzaamheid van transacties zonder risico op datacorruptie. |
foreign_keys=ON |
Zorgt ervoor dat verwijzingen met foreign keys (bijv. een relatie van de ene tabel naar de andere) worden afgedwongen. Standaard staat dit niet aan in SQLite, maar voor validatie en data-integriteit moet dit aan staan. |
encoding='UTF-8' |
Standaard codering om te gebruiken ter bevordering van ontwikkelaarsrust. |
Alle andere standaardinstellingen zijn afkomstig van SQLite zoals gespecificeerd in de officiële PRAGMA-documentatie.
Gelijktijdigheid
tldr; We gebruiken
WebSocketvoor gelijktijdige lees- en schrijfbewerkingen op je versleutelde SQLite-mailboxen.
Lezen
Je e-mailclient op je telefoon kan imap.forwardemail.net oplossen naar een van onze Digital Ocean IP-adressen – en je desktopclient kan een ander IP-adres van een andere provider oplossen.
Ongeacht met welke IMAP-server je e-mailclient verbinding maakt, willen we dat de verbinding in realtime en met 100% nauwkeurigheid uit je database leest. Dit gebeurt via WebSockets.
Schrijven
Schrijven naar je database is iets anders – omdat SQLite een embedded database is en je mailbox standaard in één bestand staat.
We hebben opties onderzocht zoals litestream, rqlite en dqlite hieronder – maar geen van deze voldeed aan onze eisen.
Om schrijven met write-ahead-logging ("WAL") ingeschakeld mogelijk te maken – moeten we ervoor zorgen dat slechts één server ("Primary") hiervoor verantwoordelijk is. WAL versnelt gelijktijdigheid aanzienlijk en maakt één schrijver en meerdere lezers mogelijk.
De Primary draait op de dataservers met de aangekoppelde volumes die de versleutelde mailboxen bevatten. Vanuit distributieperspectief kun je alle individuele IMAP-servers achter imap.forwardemail.net beschouwen als secundaire servers ("Secondary").
We realiseren tweerichtingscommunicatie met WebSockets:
- Primary-servers gebruiken een instantie van ws's
WebSocketServer. - Secondary-servers gebruiken een instantie van ws's
WebSocketclient die is ingepakt met websocket-as-promised en reconnecting-websocket. Deze twee wrappers zorgen ervoor dat deWebSocketopnieuw verbinding maakt en data kan verzenden en ontvangen voor specifieke database-schrijfbewerkingen.
Back-ups
tldr; Back-ups van je versleutelde mailboxen worden dagelijks gemaakt. Je kunt ook direct een nieuwe back-up aanvragen of de laatste back-up op elk moment downloaden via Mijn Account Domeinen Aliassen.
Voor back-ups voeren we elke dag tijdens de IMAP-commandoverwerking simpelweg het SQLite-commando VACUUM INTO uit, waarbij je versleutelde wachtwoord wordt gebruikt vanuit een in-memory IMAP-verbinding. Back-ups worden opgeslagen als er geen bestaande back-up wordt gedetecteerd of als de SHA-256 hash van het bestand is veranderd ten opzichte van de meest recente back-up.
Let op dat we het VACUUM INTO-commando gebruiken in plaats van het ingebouwde backup-commando, omdat als een pagina wordt gewijzigd tijdens een backup-commando, het opnieuw moet beginnen. Het VACUUM INTO-commando maakt een momentopname. Zie deze opmerkingen op GitHub en Hacker News voor meer inzicht.
Daarnaast gebruiken we VACUUM INTO in plaats van backup, omdat het backup-commando de database tijdelijk onversleuteld zou achterlaten totdat rekey wordt uitgevoerd (zie deze GitHub opmerking voor uitleg).
De Secondary geeft via de WebSocket-verbinding opdracht aan de Primary om de back-up uit te voeren – en de Primary ontvangt dan het commando en zal vervolgens:
- Verbinden met je versleutelde mailbox.
- Een schrijflock verkrijgen.
- Een WAL-checkpoint uitvoeren via
wal_checkpoint(PASSIVE). - Het SQLite-commando
VACUUM INTOuitvoeren. - Controleren of het gekopieerde bestand geopend kan worden met het versleutelde wachtwoord (veiligheidsmaatregel).
- Het uploaden naar Cloudflare R2 voor opslag (of je eigen provider als die is opgegeven).
Onthoud dat je mailboxen versleuteld zijn – en hoewel we IP-beperkingen en andere authenticatiemaatregelen hebben voor WebSocket-communicatie – in het geval van een kwaadwillende, kun je er zeker van zijn dat tenzij de WebSocket-payload je IMAP-wachtwoord bevat, het je database niet kan openen.
Er wordt momenteel slechts één back-up per mailbox opgeslagen, maar in de toekomst bieden we mogelijk point-in-time recovery ("PITR").
Zoeken
Onze IMAP-servers ondersteunen het SEARCH-commando met complexe zoekopdrachten, reguliere expressies en meer.
Snelle zoekprestaties zijn te danken aan FTS5 en sqlite-regex.
We slaan Date-waarden op in de SQLite-mailboxen als ISO 8601 strings via Date.prototype.toISOString (met UTC-tijdzone zodat gelijkheidsvergelijkingen correct functioneren).
Indices worden ook opgeslagen voor alle eigenschappen die in zoekopdrachten voorkomen.
Projecten
Hier is een tabel met projecten die we gebruiken in onze broncode en ontwikkelproces (alfabetisch gesorteerd):
| Project | Doel |
|---|---|
| Ansible | DevOps-automatiseringsplatform voor het eenvoudig onderhouden, schalen en beheren van onze gehele servervloot. |
| Bree | Taakplanner voor Node.js en JavaScript met ondersteuning voor cron, data, ms, later en mensvriendelijke formaten. |
| Cabin | Ontwikkelaarsvriendelijke JavaScript- en Node.js-loggingbibliotheek met aandacht voor beveiliging en privacy. |
| Lad | Node.js-framework dat onze gehele architectuur en engineeringontwerp aandrijft met MVC en meer. |
| MongoDB | NoSQL-databaseoplossing die we gebruiken voor het opslaan van alle andere data buiten mailboxen (bijv. je account, instellingen, domeinen en aliasconfiguraties). |
| Mongoose | MongoDB object document modeling ("ODM") die we in onze gehele stack gebruiken. We hebben speciale helpers geschreven die ons in staat stellen om eenvoudig Mongoose met SQLite te blijven gebruiken 🎉 |
| Node.js | Node.js is de open-source, cross-platform JavaScript runtime-omgeving die al onze serverprocessen uitvoert. |
| Nodemailer | Node.js-pakket voor het verzenden van e-mails, het maken van verbindingen en meer. We zijn een officiële sponsor van dit project. |
| Redis | In-memory database voor caching, publish/subscribe-kanalen en DNS over HTTPS-verzoeken. |
| SQLite3MultipleCiphers | Encryptie-extensie voor SQLite om volledige databasebestanden te versleutelen (inclusief de write-ahead-log ("WAL"), journal, rollback, …). |
| SQLiteStudio | Visuele SQLite-editor (die je ook kunt gebruiken) om ontwikkelmailboxen te testen, downloaden en bekijken. |
| SQLite | Embedded databaselaag voor schaalbare, zelfstandige, snelle en robuuste IMAP-opslag. |
| Spam Scanner | Node.js anti-spam, e-mailfiltering en phishingpreventietool (ons alternatief voor Spam Assassin en rspamd). |
| Tangerine | DNS over HTTPS-verzoeken met Node.js en caching via Redis – wat zorgt voor wereldwijde consistentie en nog veel meer. |
| Thunderbird | Ons ontwikkelingsteam gebruikt dit (en raadt dit ook aan) als de voorkeurs e-mailclient om te gebruiken met Forward Email. |
| UTM | Ons ontwikkelingsteam gebruikt dit om virtuele machines voor iOS en macOS te creëren om verschillende e-mailclients (parallel) te testen met onze IMAP- en SMTP-servers. |
| Ubuntu | Modern open-source Linux-gebaseerd serverbesturingssysteem dat onze gehele infrastructuur aandrijft. |
| WildDuck | IMAP-serverbibliotheek – zie de notities over attachment de-duplication en IMAP protocol support. |
| better-sqlite3-multiple-ciphers | Snelle en eenvoudige API-bibliotheek voor Node.js om programmatic met SQLite3 te communiceren. |
| email-templates | Ontwikkelaarsvriendelijk e-mailframework om aangepaste e-mails te maken, te bekijken en te verzenden (bijv. accountmeldingen en meer). |
| json-sql-enhanced | SQL-querybuilder met Mongo-stijl syntax. Dit bespaart ons ontwikkelingsteam tijd omdat we in Mongo-stijl kunnen blijven schrijven over de gehele stack met een database-agnostische aanpak. Het helpt ook SQL-injectieaanvallen te voorkomen door gebruik van queryparameters. |
| knex-schema-inspector | SQL-hulpmiddel om informatie over bestaande databaseschema's te extraheren. Dit stelt ons in staat om eenvoudig te valideren dat alle indices, tabellen, kolommen, constraints en meer geldig zijn en 1:1 overeenkomen met hoe ze zouden moeten zijn. We hebben zelfs geautomatiseerde helpers geschreven om nieuwe kolommen en indexen toe te voegen als er wijzigingen zijn in databaseschema's (met zeer gedetailleerde foutmeldingen). |
| knex | SQL-querybuilder die we alleen gebruiken voor database-migraties en schema-validatie via knex-schema-inspector. |
| mandarin | Automatische i18n zinsvertaling met ondersteuning voor Markdown via de Google Cloud Translation API. |
| mx-connect | Node.js-pakket om verbindingen met MX-servers op te lossen en tot stand te brengen en fouten af te handelen. |
| pm2 | Node.js productieprocesmanager met ingebouwde load balancer (fijn afgesteld voor prestaties). |
| smtp-server | SMTP-serverbibliotheek – we gebruiken dit voor onze mail exchange ("MX") en uitgaande SMTP-servers. |
| ImapTest | Handige tool om IMAP-servers te testen tegen benchmarks en RFC-specificatie IMAP-protocolcompatibiliteit. Dit project is gemaakt door het Dovecot team (een actieve open-source IMAP- en POP3-server sinds juli 2002). We hebben onze IMAP-server uitgebreid getest met deze tool. |
Je kunt andere projecten die we gebruiken vinden in onze broncode op GitHub.
Providers
| Provider | Doel |
|---|---|
| Cloudflare | DNS-provider, health checks, load balancers en back-upopslag met behulp van Cloudflare R2. |
| GitHub | Hosting van broncode, CI/CD en projectbeheer. |
| Digital Ocean | Dedicated server hosting en beheerde databases. |
| Vultr | Dedicated server hosting. |
| DataPacket | Dedicated server hosting. |
Gedachten
Principes
Forward Email is ontworpen volgens deze principes:
- Altijd ontwikkelaarsvriendelijk, gericht op veiligheid en privacy, en transparant zijn.
- Zich houden aan MVC, Unix, KISS, DRY, YAGNI, Twelve Factor, Occam's razor, en dogfooding
- Gericht op de scrappy, bootstrapped en ramen-profitable ontwikkelaar
Experimenten
tldr; Uiteindelijk zijn het gebruik van S3-compatibele objectopslag en/of Virtual Tables technisch niet haalbaar vanwege prestatieproblemen en gevoeligheid voor fouten door geheugenbeperkingen.
We hebben een paar experimenten gedaan die leidden tot onze uiteindelijke SQLite-oplossing zoals hierboven besproken.
Een daarvan was het proberen te gebruiken van rclone en SQLite samen met een S3-compatibele opslaglaag.
Dat experiment leidde ertoe dat we edge cases rondom rclone, SQLite en VFS gebruik beter begrepen en ontdekten:
- Als je de
--vfs-cache-mode writesvlag inschakelt met rclone, dan zijn lezen OK, maar schrijven wordt gecachet.- Als je meerdere IMAP-servers wereldwijd verspreid hebt, dan zal de cache niet synchroon zijn tussen hen tenzij je een enkele schrijver en meerdere luisteraars hebt (bijv. een pub/sub-benadering).
- Dit is ongelooflijk complex en het toevoegen van extra complexiteit zoals dit zal resulteren in meer single points of failure.
- S3-compatibele opslagproviders ondersteunen geen gedeeltelijke bestandswijzigingen – wat betekent dat elke wijziging van het
.sqlitebestand resulteert in een volledige wijziging en her-upload van de database. - Andere oplossingen zoals
rsyncbestaan, maar zijn niet gericht op write-ahead-log ("WAL") ondersteuning – dus we hebben Litestream bekeken. Gelukkig versleutelt ons encryptiegebruik al de WAL bestanden voor ons, dus we hoeven niet op Litestream te vertrouwen daarvoor. We waren echter nog niet zeker van Litestream voor productiegebruik en hebben daar een paar opmerkingen over hieronder. - Het gebruik van deze optie
--vfs-cache-mode writes(de enige manier om SQLite overrclonete gebruiken voor schrijven) zal proberen de hele database vanaf nul in het geheugen te kopiëren – het verwerken van één mailbox van 10 GB is OK, maar het verwerken van meerdere mailboxen met extreem hoge opslag zal ervoor zorgen dat de IMAP-servers geheugenlimieten bereiken enENOMEMfouten, segmentatiefouten en datacorruptie optreden.
- Als je probeert SQLite Virtual Tables te gebruiken (bijv. met s3db) om data live op een S3-compatibele opslaglaag te hebben, dan loop je tegen meerdere problemen aan:
- Lezen en schrijven zal extreem traag zijn omdat S3 API-eindpunten moeten worden aangesproken met HTTP
GET,PUT,HEADenPOSTmethoden. - Ontwikkelingstests toonden aan dat het overschrijden van 500K-1M+ records op glasvezelinternet nog steeds beperkt wordt door de doorvoersnelheid van schrijven en lezen naar S3-compatibele providers. Bijvoorbeeld, onze ontwikkelaars draaiden
forloops om zowel sequentiële SQLINSERTstatements als bulk schrijfoperaties uit te voeren. In beide gevallen was de prestatie verbazingwekkend traag. - Virtual tables kunnen geen indexen hebben,
ALTER TABLEstatements, en andere beperkingen – wat leidt tot vertragingen van 1-2 minuten of meer afhankelijk van de hoeveelheid data. - Objecten werden onversleuteld opgeslagen en er is geen native encryptieondersteuning beschikbaar.
- Lezen en schrijven zal extreem traag zijn omdat S3 API-eindpunten moeten worden aangesproken met HTTP
- We hebben ook het gebruik van sqlite-s3vfs onderzocht, wat conceptueel en technisch vergelijkbaar is met het vorige punt (dus dezelfde problemen heeft). Een mogelijkheid zou zijn om een aangepaste
sqlite3build te gebruiken met encryptie zoals wxSQLite3 (die we momenteel gebruiken in onze oplossing hierboven) via het aanpassen van het setup-bestand. - Een andere mogelijke aanpak was het gebruik van de multiplex extensie, maar dit heeft een limiet van 32 GB en zou complexe bouw- en ontwikkelingsproblemen veroorzaken.
ALTER TABLEstatements zijn vereist (dus dit sluit het gebruik van Virtual Tables volledig uit). We hebbenALTER TABLEstatements nodig zodat onze hook metknex-schema-inspectorcorrect werkt – wat ervoor zorgt dat data niet corrupt raakt en opgehaalde rijen kunnen worden omgezet naar geldige documenten volgens onzemongooseschema definities (inclusief constraints, variabele types en arbitraire datavalidatie).- Bijna alle S3-compatibele projecten gerelateerd aan SQLite in de open-source gemeenschap zijn in Python (en niet JavaScript, wat we voor 100% van onze stack gebruiken).
- Compressiebibliotheken zoals sqlite-zstd (zie comments) zien er veelbelovend uit, maar zijn mogelijk nog niet klaar voor productiegebruik. In plaats daarvan is compressie aan de applicatiezijde op datatypes zoals
String,Object,Map,Array,SetenBuffereen schonere en makkelijkere aanpak (en ook makkelijker te migreren, omdat we eenBooleanvlag of kolom kunnen opslaan – of zelfsPRAGMAuser_version=1voor compressie ofuser_version=0voor geen compressie als databasemetadata).- Gelukkig hebben we al attachment de-duplicatie geïmplementeerd in onze IMAP-server opslag – dus elk bericht met dezelfde bijlage bewaart niet meerdere kopieën van de bijlage – in plaats daarvan wordt één bijlage opgeslagen voor meerdere berichten en threads in een mailbox (en wordt vervolgens een externe referentie gebruikt).
- Het project Litestream, een SQLite replicatie- en back-upoplossing, is zeer veelbelovend en we zullen het waarschijnlijk in de toekomst gebruiken.
- Niet om de auteur(s) te kort te doen – want we houden van hun werk en bijdragen aan open-source al meer dan tien jaar – maar uit praktijkgebruik blijkt dat er mogelijk veel problemen en potentieel dataverlies door gebruik kunnen zijn.
- Back-up herstel moet soepel en triviaal zijn. Het gebruik van een oplossing zoals MongoDB met
mongodumpenmongoexportis niet alleen omslachtig, maar ook tijdrovend en complex qua configuratie.- SQLite databases maken het eenvoudig (het is één bestand).
- We wilden een oplossing ontwerpen waarbij gebruikers hun mailbox op elk moment kunnen meenemen en vertrekken.
- Simpele Node.js commando’s zoals
fs.unlink('mailbox.sqlite'))en het is permanent verwijderd van de schijf. - We kunnen op vergelijkbare wijze een S3-compatibele API gebruiken met HTTP
DELETEom snapshots en back-ups eenvoudig te verwijderen voor gebruikers.
- Simpele Node.js commando’s zoals
- SQLite was de eenvoudigste, snelste en meest kosteneffectieve oplossing.
Gebrek aan alternatieven
Voor zover wij weten, zijn er geen andere e-maildiensten die op deze manier zijn ontworpen noch open-source zijn.
Wij denken dat dit mogelijk komt door bestaande e-maildiensten die legacy-technologie in productie hebben met spaghetti code 🍝.
De meeste, zo niet alle, bestaande e-maildienstverleners zijn ofwel closed-source of adverteren als open-source, maar in werkelijkheid is alleen hun front-end open-source.
Het meest gevoelige deel van e-mail (de daadwerkelijke opslag/IMAP/SMTP-interactie) wordt volledig op de back-end (server) gedaan, en niet op de front-end (client).
Probeer Forward Email uit
Meld je vandaag nog aan op https://forwardemail.net! 🚀