Quantenresistente E-Mail: So verwenden wir verschlüsselte SQLite-Postfächer, um Ihre E-Mails zu schützen

Vorwort
Important
Unser E-Mail-Dienst ist 100 % Open Source und bietet durch sichere und verschlüsselte SQLite-Postfächer einen hohen Datenschutz.
Bis wir IMAP-Unterstützung gestartet haben, haben wir MongoDB für unsere Anforderungen an die dauerhafte Datenspeicherung verwendet.
Diese Technologie ist erstaunlich und wir verwenden sie noch heute. Um jedoch mit MongoDB eine Verschlüsselung im Ruhezustand zu erreichen, müssen Sie einen Anbieter nutzen, der MongoDB Enterprise anbietet, wie etwa Digital Ocean oder Mongo Atlas, oder für eine Enterprise-Lizenz bezahlen (und anschließend mit der Latenz des Vertriebsteams arbeiten).
Unser Team bei E-Mail weiterleiten benötigte eine entwicklerfreundliche, skalierbare, zuverlässige und verschlüsselte Speicherlösung für IMAP-Postfächer. Als Open-Source-Entwickler war die Nutzung einer Technologie, für die eine Lizenzgebühr für die Verschlüsselung ruhender Daten erforderlich ist, für Unsere Prinzipien ein Problem. Daher experimentierten, forschten und entwickelten wir von Grund auf eine neue Lösung, um diese Anforderungen zu erfüllen.
Anstatt Ihre Postfächer in einer gemeinsamen Datenbank zu speichern, speichern und verschlüsseln wir sie einzeln mit Ihrem Passwort (das nur Sie haben). Unser E-Mail-Dienst ist so sicher, dass Sie Ihr Postfach verlieren, wenn Sie Ihr Passwort vergessen (und es mithilfe von Offline-Backups wiederherstellen oder von vorne beginnen müssen).
Lesen Sie weiter, während wir unten einen tieferen Einblick in Vergleich von E-Mail-Dienstanbietern, So funktioniert unser Service, Unser Technologie-Stack und mehr nehmen.
Vergleich der E-Mail-Dienstanbieter
Wir sind der einzige 100 % Open Source- und datenschutzorientierte E-Mail-Dienstanbieter, der individuell verschlüsselte SQLite-Postfächer speichert, eine unbegrenzte Anzahl an Domänen, Aliasnamen und Benutzern anbietet und ausgehende SMTP-, IMAP- und POP3-Dienste unterstützt:
Im Gegensatz zu anderen E-Mail-Anbietern müssen Sie bei Forward Email nicht pro Domain oder Alias für Speicherplatz bezahlen. Der Speicherplatz wird für Ihr gesamtes Konto gemeinsam genutzt. Wenn Sie also mehrere benutzerdefinierte Domainnamen und jeweils mehrere Aliase haben, sind wir die perfekte Lösung für Sie. Beachten Sie, dass Sie bei Bedarf weiterhin Speicherlimits pro Domain oder Alias festlegen können.
Wie funktioniert es
- Mit Ihrem E-Mail-Client wie Apple Mail, Thunderbird, Gmail oder Outlook stellen Sie mit Ihrem Benutzernamen und Passwort eine Verbindung zu unseren sicheren IMAP-Servern her:
- Ihr Benutzername ist Ihr vollständiger Alias mit Ihrer Domain, z. B.
hello@example.com
. - Ihr Passwort wird zufällig generiert und Ihnen nur 30 Sekunden lang angezeigt, wenn Sie unter Mein Konto Domains Aliase auf Passwort generieren klicken.
-
Sobald die Verbindung hergestellt ist, sendet Ihr E-Mail-Client IMAP-Protokollbefehle an unseren IMAP-Server, um Ihr Postfach synchron zu halten. Dies umfasst das Schreiben und Speichern von E-Mail-Entwürfen sowie weitere Aktionen (z. B. das Kennzeichnen einer E-Mail als wichtig oder als Spam/Junk-Mail).
-
Mail-Exchange-Server (auch „MX“-Server genannt) empfangen neue E-Mails und speichern sie in Ihrem Postfach. Ihr E-Mail-Client wird benachrichtigt und synchronisiert Ihr Postfach. Unsere Mail-Exchange-Server können Ihre E-Mails an einen oder mehrere Empfänger (einschließlich Webhooks) weiterleiten, sie in Ihrem verschlüsselten IMAP-Speicher bei uns speichern oder beides!
Tip
Möchten Sie mehr erfahren? Lesen Sie So richten Sie die E-Mail-Weiterleitung ein, So funktioniert unser Mail-Exchange-Service oder sehen Sie sich unsere Guides an.
- Hinter den Kulissen sorgt unser sicheres E-Mail-Speicherdesign auf zwei Arten dafür, dass Ihre Postfächer verschlüsselt bleiben und nur Sie darauf zugreifen können:
-
Wenn neue E-Mails von einem Absender für Sie eingehen, schreiben unsere Mail-Exchange-Server diese für Sie in ein individuelles, temporäres und verschlüsseltes Postfach.
-
Wenn Sie sich mit Ihrem E-Mail-Client mit unserem IMAP-Server verbinden, wird Ihr Passwort verschlüsselt und zum Lesen und Schreiben in Ihrem Postfach verwendet. Nur mit diesem Passwort kann Ihr Postfach gelesen und beschrieben werden. Da Sie der Einzige mit diesem Passwort sind, können nur Sie Ihr Postfach lesen und beschreiben, wenn Sie darauf zugreifen. Beim nächsten Abruf oder bei der Synchronisierung Ihres E-Mail-Clients werden Ihre neuen Nachrichten aus diesem temporären Postfach übertragen und mit Ihrem angegebenen Passwort in Ihrem aktuellen Postfach gespeichert. Beachten Sie, dass dieses temporäre Postfach anschließend gelöscht wird, sodass nur Ihr passwortgeschütztes Postfach die Nachrichten enthält.
Wenn Sie mit IMAP verbunden sind (z. B. über einen E-Mail-Client wie Apple Mail oder Thunderbird), müssen wir nicht in den temporären Speicher schreiben. Stattdessen wird Ihr verschlüsseltes IMAP-Passwort im Speicher abgerufen und verwendet. Sobald eine Nachricht an Sie zugestellt werden soll, senden wir in Echtzeit eine WebSocket-Anfrage an alle IMAP-Server und fragen nach, ob eine aktive Sitzung für Sie besteht (dies ist der Abrufvorgang). Anschließend leiten wir das verschlüsselte Passwort im Speicher weiter. So müssen wir nicht in ein temporäres Postfach schreiben, sondern können mit Ihrem verschlüsselten Passwort in Ihr tatsächlich verschlüsseltes Postfach schreiben.
```mermaid
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!
```
- Backups Ihrer verschlüsselten Postfächer werden täglich erstellt. Sie können jederzeit ein neues Backup anfordern oder das neueste Backup von Mein Konto Domains Aliase herunterladen. Wenn Sie zu einem anderen E-Mail-Dienst wechseln, können Sie Ihre Postfächer und Backups jederzeit problemlos migrieren, herunterladen, exportieren und löschen.
Technologien
Datenbanken
Wir haben andere mögliche Datenbankspeicherebenen untersucht, aber keine hat unsere Anforderungen so gut erfüllt wie SQLite:
Datenbank | Verschlüsselung ruhender Daten | Sandboxed Postfächer | Lizenz | Used Everywhere |
---|---|---|---|---|
SQLite :Stern: | :weißes_Häkchen: Ja mit SQLite3MultipleCiphers | :weißes Häkchen: | :weißes Häkchen: Gemeinfrei | :weißes Häkchen: |
MongoDB | ❌ "Available in MongoDB Enterprise only" | ❌ Relationale Datenbank | ❌ AGPL und SSPL-1.0 |
:X: |
rqlite | ❌ Network only | ❌ Relationale Datenbank | :weißes Häkchen: MIT |
:X: |
dqlite | ❌ Untested and not yet supported? | ❌ Untested and not yet supported? | :weißes Häkchen: LGPL-3.0-only |
:X: |
PostgreSQL | :weißes Häkchen: Yes | ❌ Relationale Datenbank | :weißes_Häkchen: PostgreSQL (ähnlich wie BSD oder MIT ) |
:X: |
MariaDB | :weißes Häkchen: For InnoDB only | ❌ Relationale Datenbank | :weißes Häkchen: GPLv2 und BUSL-1.1 |
:X: |
CockroachDB | ❌ Enterprise-only feature | ❌ Relationale Datenbank | ❌ BUSL-1.1 und andere |
:X: |
Hier ist ein Blogbeitrag, der mehrere SQLite-Datenbankspeicheroptionen vergleicht in der obigen Tabelle.
Sicherheit
Wir verwenden stets die Verschlüsselungsmethoden Verschlüsselung im Ruhezustand (AES-256), Verschlüsselung während der Übertragung (TLS), DNS über HTTPS („DoH“) mit 🍊 Mandarine und sqleet (ChaCha20-Poly1305) für Postfächer. Zusätzlich nutzen wir tokenbasierte Zwei-Faktor-Authentifizierung (im Gegensatz zu SMS, die anfällig für Man-in-the-Middle-Angriffe ist), rotierte SSH-Schlüssel mit deaktiviertem Root-Zugriff, exklusiven Zugriff auf Server über eingeschränkte IP-Adressen und mehr.
Im Falle eines Angriff des bösen Dienstmädchens oder eines betrügerischen Mitarbeiters eines Drittanbieters kann Ihr Postfach weiterhin nur mit Ihrem generierten Passwort geöffnet werden. Seien Sie versichert, wir verlassen uns auf keine anderen Drittanbieter als unsere SOC Typ 2-konformen Serveranbieter Cloudflare, DataPacket, Digital Ocean und Vultr.
Unser Ziel ist es, so wenig einzelner Fehlerpunkt wie möglich zu haben.
Postfächer
tldr; Unsere IMAP-Server verwenden für jedes Ihrer Postfächer individuell verschlüsselte SQLite-Datenbanken.
SQLite ist ein äußerst beliebtes eingebettete Datenbank – sie läuft derzeit auf Ihrem Telefon und Computer – und wird von fast allen wichtigen Technologien verwendet.
Auf unseren verschlüsselten Servern gibt es beispielsweise ein SQLite-Datenbankpostfach für linux@example.com
, info@example.com
, hello@example.com
usw. – jeweils eines als .sqlite
-Datenbankdatei. Wir benennen die Datenbankdateien auch nicht nach der E-Mail-Adresse – stattdessen verwenden wir BSON ObjectID und generierte eindeutige UUIDs, die weder verraten, wem das Postfach gehört, noch unter welcher E-Mail-Adresse es sich befindet (z. B. 353a03f21e534321f5d6e267.sqlite
).
Jede dieser Datenbanken ist mit Ihrem Passwort (das nur Sie haben) unter Verwendung von sqleet (ChaCha20-Poly1305) verschlüsselt. Das bedeutet, dass Ihre Postfächer einzeln verschlüsselt, in sich geschlossen (Sandbox und portierbar sind.
Wir haben SQLite mit dem folgenden PRAGMA feinabgestimmt:
PRAGMA |
Zweck |
---|---|
cipher=chacha20 |
ChaCha20-Poly1305 SQLite database encryption. Weitere Informationen finden Sie unter better-sqlite3-multiple-ciphers unter Projects. |
key="****************" |
Dies ist Ihr entschlüsseltes, ausschließlich im Speicher gespeichertes Passwort, das über die IMAP-Verbindung Ihres E-Mail-Clients an unseren Server weitergeleitet wird. Für jede Lese- und Schreibsitzung werden neue Datenbankinstanzen erstellt und geschlossen (um Sandboxing und Isolation zu gewährleisten). |
journal_model=WAL |
Write-Ahead-Protokoll ("WAL") which boosts performance and allows concurrent read access. |
busy_timeout=5000 |
Verhindert Schreibsperrenfehler while other writes are taking place. |
synchronous=NORMAL |
Erhöht die Dauerhaftigkeit von Transaktionen without data corruption risk. |
foreign_keys=ON |
Erzwingt, dass Fremdschlüsselreferenzen (z. B. eine Beziehung von einer Tabelle zu einer anderen) erzwungen werden. By default this is not turned on in SQLite, sollte aber zur Validierung und Datenintegrität aktiviert werden. |
encoding='UTF-8' |
Default encoding zur Gewährleistung der geistigen Gesundheit des Entwicklers. |
Alle anderen Standardwerte stammen von SQLite, wie im offizielle PRAGMA-Dokumentation angegeben.
Parallelität
tldr; Wir verwenden
WebSocket
für gleichzeitige Lese- und Schreibvorgänge in Ihren verschlüsselten SQLite-Postfächern.
liest
Ihr E-Mail-Client auf Ihrem Telefon löst möglicherweise imap.forwardemail.net
in eine unserer Digital Ocean-IP-Adressen auf – und Ihr Desktop-Client löst möglicherweise eine separate IP von einem ganz anderen Anbieter auf.
Unabhängig davon, mit welchem IMAP-Server Ihr E-Mail-Client eine Verbindung herstellt, möchten wir, dass die Verbindung Ihre Datenbank in Echtzeit und mit 100%iger Genauigkeit liest. Dies geschieht über WebSockets.
schreibt
Das Schreiben in Ihre Datenbank verläuft etwas anders, da SQLite eine eingebettete Datenbank ist und Ihr Postfach standardmäßig in einer einzigen Datei gespeichert ist.
Wir haben Optionen wie litestream
, rqlite
und dqlite
unten untersucht – jedoch erfüllte keine davon unsere Anforderungen.
Um Schreibvorgänge mit aktiviertem Write-Ahead-Logging ("WAL") durchzuführen, muss sichergestellt werden, dass nur ein Server ("Primary") dafür zuständig ist. WAL beschleunigt die Parallelität drastisch und ermöglicht einen Schreiber und mehrere Leser.
Der Primärserver läuft auf den Datenservern mit den eingebundenen Volumes, die die verschlüsselten Postfächer enthalten. Aus Verteilungssicht können Sie alle einzelnen IMAP-Server hinter imap.forwardemail.net
als Sekundärserver („Secondary“) betrachten.
Wir erreichen eine bidirektionale Kommunikation mit WebSockets:
- Primäre Server verwenden eine Instanz des
WebSocketServer
-Servers von ws. - Sekundäre Server verwenden eine Instanz des
WebSocket
-Clients von ws, der mit WebSocket wie versprochen und Wiederverbindung-WebSocket umschlossen ist. Diese beiden Wrapper stellen sicher, dassWebSocket
die Verbindung wiederherstellt und Daten für bestimmte Datenbankschreibvorgänge senden und empfangen kann.
Sicherungen
tldr; Backups Ihrer verschlüsselten Postfächer werden täglich erstellt. Sie können auch sofort ein neues Backup anfordern oder das neueste Backup jederzeit unter Mein Konto Domains Aliase herunterladen.
Für Backups führen wir täglich während der IMAP-Befehlsverarbeitung den SQLite-Befehl VACUUM INTO
aus. Dieser nutzt Ihr verschlüsseltes Passwort aus einer IMAP-Verbindung im Arbeitsspeicher. Backups werden gespeichert, wenn kein vorhandenes Backup erkannt wird oder sich der SHA-256-Hash der Datei im Vergleich zum letzten Backup geändert hat.
Beachten Sie, dass wir den Befehl VACUUM INTO
anstelle des integrierten Befehls backup
verwenden, da eine Seite, die während der Ausführung des Befehls backup
geändert wird, neu gestartet werden muss. Der Befehl VACUUM INTO
erstellt einen Snapshot. Weitere Informationen finden Sie in den Kommentaren zu GitHub und Hacker-News.
Darüber hinaus verwenden wir VACUUM INTO
anstelle von backup
, da der Befehl backup
die Datenbank für einen kurzen Zeitraum unverschlüsselt lassen würde, bis rekey
aufgerufen wird (weitere Informationen finden Sie in diesem GitHub Kommentar).
Der Sekundärserver weist den Primärserver über die Verbindung WebSocket
an, die Sicherung auszuführen. Der Primärserver erhält dann den entsprechenden Befehl und führt anschließend Folgendes aus:
- Verbinden Sie sich mit Ihrem verschlüsselten Postfach.
- Erlangen Sie eine Schreibsperre.
- Führen Sie einen WAL-Checkpoint über
wal_checkpoint(PASSIVE)
aus. - Führen Sie den SQLite-Befehl
VACUUM INTO
aus. - Stellen Sie sicher, dass die kopierte Datei mit dem verschlüsselten Passwort geöffnet werden kann (Schutz vor Dummy-Verletzung).
- Laden Sie die Datei zur Speicherung auf Cloudflare R2 hoch (oder bei Ihrem eigenen Anbieter, falls angegeben).
Denken Sie daran, dass Ihre Postfächer verschlüsselt sind. Obwohl wir für die WebSocket-Kommunikation IP-Einschränkungen und andere Authentifizierungsmaßnahmen eingerichtet haben, können Sie im Falle eines Angriffs durch einen böswilligen Akteur sicher sein, dass die WebSocket-Nutzlast Ihre Datenbank nicht öffnen kann, sofern sie nicht über Ihr IMAP-Passwort verfügt.
Derzeit wird nur eine Sicherung pro Postfach gespeichert, aber in Zukunft bieten wir möglicherweise eine zeitpunktbezogene Wiederherstellung („PITR“) an.
Suche
Unsere IMAP-Server unterstützen den Befehl SEARCH
mit komplexen Abfragen, regulären Ausdrücken und mehr.
Die schnelle Suchleistung ist FTS5 und SQLite-Regex zu verdanken.
Wir speichern Date
-Werte in den SQLite-Postfächern als ISO 8601-Zeichenfolgen über Date.prototype.toISOString (mit UTC-Zeitzone, damit Gleichheitsvergleiche ordnungsgemäß funktionieren).
Außerdem werden für alle Eigenschaften, die in Suchanfragen vorkommen, Indizes gespeichert.
Projekte
Hier ist eine Tabelle mit einer Übersicht über die Projekte, die wir in unserem Quellcode und Entwicklungsprozess verwenden (alphabetisch sortiert):
Projekt | Zweck |
---|---|
Ansible | DevOps-Automatisierungsplattform zur einfachen Wartung, Skalierung und Verwaltung unserer gesamten Serverflotte. |
Bree | Job-Scheduler für Node.js und JavaScript mit Cron, Dates, MS, Later und benutzerfreundlicher Unterstützung. |
Cabin | Entwicklerfreundliche JavaScript- und Node.js-Protokollierungsbibliothek mit Blick auf Sicherheit und Datenschutz. |
Lad | Node.js-Framework, das unsere gesamte Architektur und unser technisches Design mit MVC und mehr unterstützt. |
MongoDB | NoSQL-Datenbanklösung, die wir zum Speichern aller anderen Daten außerhalb von Postfächern verwenden (z. B. Ihr Konto, Ihre Einstellungen, Domänen und Aliaskonfigurationen). |
Mongoose | MongoDB Object Document Modeling („ODM“), das wir in unserem gesamten Stack verwenden. Wir haben spezielle Helfer geschrieben, die es uns ermöglichen, Mongoose mit SQLite einfach weiterzuverwenden. 🎉 |
Node.js | Node.js ist die plattformübergreifende Open-Source-JavaScript-Laufzeitumgebung, in der alle unsere Serverprozesse ausgeführt werden. |
Nodemailer | Node.js-Paket zum Senden von E-Mails, Erstellen von Verbindungen und mehr. Wir sind offizieller Sponsor dieses Projekts. |
Redis | In-Memory-Datenbank für Caching, Publish/Subscribe-Kanäle und DNS-over-HTTPS-Anfragen. |
SQLite3MultipleCiphers | Verschlüsselungserweiterung für SQLite, um die Verschlüsselung ganzer Datenbankdateien (einschließlich Write-Ahead-Log ("WAL"), Journal, Rollback usw.) zu ermöglichen. |
SQLiteStudio | Visueller SQLite-Editor (den Sie auch verwenden können) zum Testen, Herunterladen und Anzeigen von Entwicklungspostfächern. |
SQLite | Eingebettete Datenbankebene für skalierbaren, eigenständigen, schnellen und belastbaren IMAP-Speicher. |
Spam Scanner | Node.js-Tool zum Anti-Spam, zur E-Mail-Filterung und zur Phishing-Prävention (unsere Alternative zu Spam Assassin und rspamd). |
Tangerine | DNS-über-HTTPS-Anfragen mit Node.js und Caching mit Redis – das gewährleistet globale Konsistenz und vieles mehr. |
Thunderbird | Unser Entwicklungsteam verwendet dies (und empfiehlt dies auch) als bevorzugten E-Mail-Client zur Verwendung mit Forward Email. |
UTM | Unser Entwicklungsteam erstellt damit virtuelle Maschinen für iOS und macOS, um verschiedene E-Mail-Clients (parallel) mit unseren IMAP- und SMTP-Servern zu testen. |
Ubuntu | Modernes Open-Source-Serverbetriebssystem auf Linux-Basis, das unsere gesamte Infrastruktur betreibt. |
WildDuck | IMAP-Serverbibliothek – siehe die Hinweise zu attachment de-duplication und IMAP protocol support. |
better-sqlite3-multiple-ciphers | Schnelle und einfache API-Bibliothek für Node.js zur programmgesteuerten Interaktion mit SQLite3. |
email-templates | Entwicklerfreundliches E-Mail-Framework zum Erstellen, Anzeigen einer Vorschau und Senden von benutzerdefinierten E-Mails (z. B. Kontobenachrichtigungen und mehr). |
json-sql-enhanced | SQL-Abfragegenerator mit Mongo-Syntax. Dies spart unserem Entwicklungsteam Zeit, da wir weiterhin im gesamten Stack im Mongo-Stil schreiben können und dabei einen datenbankunabhängigen Ansatz verfolgen. Außerdem hilft es, SQL-Injection-Angriffe durch die Verwendung von Abfrageparametern zu vermeiden. |
knex-schema-inspector | SQL-Dienstprogramm zum Extrahieren von Informationen zum vorhandenen Datenbankschema. So können wir einfach überprüfen, ob alle Indizes, Tabellen, Spalten, Constraints usw. gültig sind und 1:1 wie vorgesehen sind. Wir haben sogar automatisierte Hilfsprogramme entwickelt, um neue Spalten und Indizes hinzuzufügen, wenn Änderungen an Datenbankschemata vorgenommen werden (mit äußerst detaillierter Fehlerwarnung). |
knex | SQL-Abfrage-Generator, den wir nur für Datenbankmigrationen und Schemavalidierung über knex-schema-inspector verwenden. |
mandarin | Automatische i18n-Phrasenübersetzung mit Unterstützung für Markdown mithilfe von Google Cloud Translation API. |
mx-connect | Node.js-Paket zum Auflösen und Herstellen von Verbindungen mit MX-Servern und zur Fehlerbehandlung. |
pm2 | Node.js-Produktionsprozessmanager mit integriertem Load Balancer (fine-tuned für Leistung). |
smtp-server | SMTP-Serverbibliothek – wir verwenden diese für unseren Mailaustausch („MX“) und unsere ausgehenden SMTP-Server. |
ImapTest | Nützliches Tool zum Testen von IMAP-Servern anhand von Benchmarks und der Kompatibilität des IMAP-Protokolls gemäß der RFC-Spezifikation. Dieses Projekt wurde vom Dovecot-Team (einem aktiven Open-Source-IMAP- und POP3-Server seit Juli 2002) erstellt. Wir haben unseren IMAP-Server mit diesem Tool ausführlich getestet. |
Weitere von uns verwendete Projekte finden Sie in unser Quellcode auf GitHub.
Anbieter
Anbieter | Zweck |
---|---|
Cloudflare | DNS-Anbieter, Integritätsprüfungen, Lastenausgleich und Sicherungsspeicher verwenden Cloudflare R2. |
Digital Ocean | Dediziertes Server-Hosting und verwaltete Datenbanken. |
Vultr | Dediziertes Server-Hosting. |
DataPacket | Dediziertes Server-Hosting. |
Gedanken
Grundsätze
Forward Email ist nach diesen Prinzipien konzipiert:
- Seien Sie stets entwicklerfreundlich, sicherheits- und datenschutzorientiert und transparent.
- Halten Sie sich an MVC, Unix, KISS, DRY, YAGNI, Zwölf Faktor, Ockhams Rasiermesser und Hundefutter.
- Sprechen Sie kämpferische, fleißige und Ramen-profitabel Entwickler an.
Experimente
tldr; Letztendlich ist die Verwendung von S3-kompatiblem Objektspeicher und/oder virtuellen Tabellen aus Leistungsgründen technisch nicht machbar und aufgrund von Speicherbeschränkungen fehleranfällig.
Wir haben einige Experimente durchgeführt, die zu unserer endgültigen SQLite-Lösung geführt haben, wie oben beschrieben.
Eine davon bestand darin, die Verwendung von rclone und SQLite zusammen mit einer S3-kompatiblen Speicherschicht auszuprobieren.
Durch dieses Experiment konnten wir die Verwendung von rclone, SQLite und VFS besser verstehen und Randfälle entdecken:
- Wenn Sie das Flag
--vfs-cache-mode writes
mit rclone aktivieren, sind Lesevorgänge zwar möglich, Schreibvorgänge werden jedoch zwischengespeichert. - Wenn Sie mehrere global verteilte IMAP-Server haben, ist der Cache auf allen Servern deaktiviert, es sei denn, Sie verwenden einen einzelnen Schreiber und mehrere Listener (z. B. einen Pub/Sub-Ansatz).
- Dies ist äußerst komplex, und jede zusätzliche Komplexität führt zu weiteren Single Points of Failure.
- S3-kompatible Speicheranbieter unterstützen keine partiellen Dateiänderungen. Das bedeutet, dass jede Änderung der Datei
.sqlite
eine vollständige Änderung und einen erneuten Upload der Datenbank zur Folge hat. - Es gibt zwar auch andere Lösungen wie
rsync
, diese bieten jedoch keine Unterstützung für Write-Ahead-Log („WAL“). Daher haben wir uns für Litestream entschieden. Glücklicherweise verschlüsselt unsere Verschlüsselung die WAL-Dateien bereits für uns, sodass wir hierfür nicht auf Litestream angewiesen sind. Wir waren jedoch noch nicht überzeugt von Litestream für den Produktionseinsatz und haben dazu unten einige Anmerkungen. - Bei Verwendung der Option
--vfs-cache-mode writes
(die einzige Möglichkeit, SQLite anstelle vonrclone
für Schreibvorgänge zu verwenden) wird versucht, die gesamte Datenbank von Grund auf im Arbeitsspeicher zu kopieren. Die Verwaltung eines 10-GB-Postfachs ist in Ordnung, die Verwaltung mehrerer Postfächer mit extrem hohem Speicherbedarf führt jedoch dazu, dass die IMAP-Server an Speicherbeschränkungen undENOMEM
-Fehler, Segmentierungsfehler und Datenbeschädigungen stoßen. - Wenn Sie versuchen, SQLite Virtuelle Tische (z. B. mit s3db) zu verwenden, um Daten live auf einer S3-kompatiblen Speicherebene zu speichern, treten weitere Probleme auf:
- Lese- und Schreibvorgänge sind extrem langsam, da S3-API-Endpunkte mit den HTTP-Methoden
.sqlite
0,.sqlite
1,.sqlite
2 und.sqlite
3 angesprochen werden müssen. - Entwicklungstests zeigten, dass die Verarbeitung von mehr als 500.000–1.000.000 Datensätzen im Glasfaser-Internet immer noch durch den Durchsatz beim Schreiben und Lesen an S3-kompatible Anbieter begrenzt ist. Beispielsweise führten unsere Entwickler
.sqlite
4-Schleifen aus, um sowohl sequenzielle SQL-Anweisungen.sqlite
5 als auch Anweisungen zum Massenschreiben großer Datenmengen auszuführen. In beiden Fällen war die Leistung extrem langsam. - Virtuelle Tabellen können keine Indizes,
.sqlite
6-Anweisungen und.sqlite
7.sqlite
8 enthalten – was je nach Datenmenge zu Verzögerungen von 1–2 Minuten oder mehr führt. - Objekte wurden unverschlüsselt gespeichert, und es ist keine native Verschlüsselungsunterstützung verfügbar.
- Wir haben auch die Verwendung von
.sqlite
9 untersucht, das konzeptionell und technisch dem vorherigen Punkt ähnelt (und daher dieselben Probleme aufweist). Eine Möglichkeit wäre die Verwendung eines benutzerdefiniertenrsync
0-Builds, der mit einer Verschlüsselung wiersync
1 (die wir derzeit in unserer obigen Lösung verwenden) bisrsync
2 umhüllt ist. - Ein anderer möglicher Ansatz wäre die Verwendung von
rsync
3, die jedoch auf 32 GB beschränkt ist und einen komplexen Erstellungs- und Entwicklungsaufwand erfordern würde. rsync
4-Anweisungen sind erforderlich (daher ist die Verwendung virtueller Tabellen vollständig ausgeschlossen). Wir benötigenrsync
5-Anweisungen, damit unser Hook mitrsync
6 ordnungsgemäß funktioniert. Dadurch wird sichergestellt, dass Daten nicht beschädigt werden und abgerufene Zeilen gemäß unserenrsync
7-Schemadefinitionen (einschließlich Einschränkung, Variablentyp und beliebiger Datenvalidierung) in gültige Dokumente konvertiert werden können.- Fast alle S3-kompatiblen Projekte mit SQLite in der Open-Source-Community basieren auf Python (und nicht auf JavaScript, das wir für 100 % unseres Stacks verwenden).
- Komprimierungsbibliotheken wie
rsync
8 (siehersync
9) sehen vielversprechend aus, aber __PROTECTED_LINK_189__0. Stattdessen ist die anwendungsseitige Komprimierung von Datentypen wie __PROTECTED_LINK_189__1, __PROTECTED_LINK_189__2, __PROTECTED_LINK_189__3, __PROTECTED_LINK_189__4, __PROTECTED_LINK_189__5 und __PROTECTED_LINK_189__6 ein saubererer und einfacherer Ansatz (und lässt sich auch leichter migrieren, da wir ein __PROTECTED_LINK_189__7-Flag oder eine __PROTECTED_LINK_189__7-Spalte speichern oder sogar __PROTECTED_LINK_189__8, __PROTECTED_LINK_189__9 zur Komprimierung oder __PROTECTED_LINK_190__0 für keine Komprimierung als Datenbankmetadaten verwenden können). - Glücklicherweise ist in unserem IMAP-Serverspeicher bereits eine Deduplizierung von Anhängen implementiert. Daher wird nicht für jede Nachricht mit demselben Anhang eine Kopie des Anhangs gespeichert. Stattdessen wird ein einzelner Anhang für mehrere Nachrichten und Threads in einem Postfach gespeichert (und anschließend eine Fremdreferenz verwendet).
- Das Projekt Litestream, eine SQLite-Replikations- und Backup-Lösung, ist sehr vielversprechend und wird von uns höchstwahrscheinlich auch in Zukunft genutzt.
- Wir möchten die Autoren nicht herabwürdigen – wir schätzen ihre Arbeit und ihre Beiträge zu Open Source seit über einem Jahrzehnt –, doch in der Praxis zeigt sich, dass es __PROTECTED_LINK_190__1 und __PROTECTED_LINK_190__2 gibt.
- Die Wiederherstellung von Backups muss reibungslos und einfach erfolgen. Die Verwendung einer Lösung wie MongoDB mit __PROTECTED_LINK_190__3 und __PROTECTED_LINK_190__4 ist nicht nur mühsam, sondern auch zeitintensiv und konfigurationsintensiv.
- SQLite-Datenbanken vereinfachen dies (es handelt sich um eine einzelne Datei).
- Wir wollten eine Lösung entwickeln, mit der Benutzer ihr Postfach jederzeit öffnen und verlassen können.
- Einfache Node.js-Befehle an __PROTECTED_LINK_190__5 – und es wird dauerhaft vom Festplattenspeicher gelöscht.
- Wir können eine S3-kompatible API mit HTTP __PROTECTED_LINK_190__6 verwenden, um Snapshots und Backups für Benutzer einfach zu entfernen.
- SQLite war die einfachste, schnellste und kostengünstigste Lösung.
Mangel an Alternativen
Unseres Wissens sind keine anderen E-Mail-Dienste so konzipiert und auch keine Open Source.
Wir glauben, dass dies daran liegen könnte, dass bei vorhandenen E-Mail-Diensten veraltete Technologie mit Spaghetti-Code 🍝 in der Produktion ist.
Die meisten, wenn nicht alle bestehenden E-Mail-Dienstanbieter sind entweder Closed Source oder werden als Open Source beworben, aber in Wirklichkeit ist nur ihr Front-End Open Source.
Der sensibelste Teil einer E-Mail (die eigentliche Speicherung/IMAP/SMTP-Interaktion) wird vollständig auf dem Back-End (Server) und nicht auf dem Front-End (Client) durchgeführt.
Probieren Sie „E-Mail weiterleiten“ aus
Melden Sie sich noch heute bei https://forwardemail.net! 🚀 an