Verschlüsselte SQLite-Postfächer für Ihre Privatsphäre
Im Gegensatz zu anderen E-Mail-Diensten stellen wir sicher, dass nur Sie jederzeit Zugriff auf Ihr Postfach haben .
- Suchseite
- Inhaltsverzeichnis
Vorwort
tldr; Unser E-Mail-Service ist 100 % Open Source und datenschutzorientiert durch sichere und verschlüsselte SQLite-Postfächer.
Bis wir starteten IMAP-Unterstützung, haben wir MongoDB für unsere persistenten Datenspeicheranforderungen verwendet.
Diese Technologie ist erstaunlich und wir verwenden sie auch heute noch – aber um Verschlüsselung im Ruhezustand mit MongoDB zu haben, müssen Sie einen Anbieter nutzen, der MongoDB Enterprise anbietet, wie z. B. Digital Ocean oder Mongo Atlas – oder für eine Unternehmenslizenz bezahlen (und müssen anschließend mit der Latenz des Vertriebsteams arbeiten).
Unser Team bei Email weiterleiten benötigte eine entwicklerfreundliche, skalierbare, zuverlässige und verschlüsselte Speicherlösung für IMAP-Postfächer. Als Open-Source-Entwickler war es dagegen, eine Technologie zu verwenden, für die man eine Lizenzgebühr zahlen muss, um die Funktion „Encryption-at-Rest“ zu erhalten unsere Prinzipien – und so haben wir experimentiert, geforscht und von Grund auf eine neue Lösung entwickelt, um diese Anforderungen zu erfüllen.
Anstatt eine gemeinsame Datenbank zum Speichern Ihrer Postfächer zu verwenden, speichern und verschlüsseln wir Ihre Postfächer einzeln mit Ihrem Passwort (das nur Sie haben). Unser E-Mail-Service ist so sicher, dass Ihr Postfach verloren geht, wenn Sie Ihr Passwort vergessen (und müssen mit Offline-Backups wiederhergestellt werden oder von vorne beginnen).
Lesen Sie weiter, während wir weiter unten einen tiefen Einblick in a nehmen Vergleich von E-Mail-Dienstleistern, wie unser Service funktioniert, Unser Technologie-Stack, und mehr.
Vergleich von E-Mail-Dienstanbietern
Wir sind der einzige zu 100 % Open-Source- und datenschutzorientierte E-Mail-Dienstanbieter, der individuell verschlüsselte SQLite-Postfächer speichert, unbegrenzte Domänen, Aliase und Benutzer bietet und ausgehende SMTP-, IMAP- und POP3-Unterstützung bietet:
Im Gegensatz zu anderen E-Mail-Anbietern müssen Sie bei Forward Email nicht für die Speicherung pro Domain oder Alias bezahlen. Der Speicher wird für Ihr gesamtes Konto gemeinsam genutzt. Wenn Sie also mehrere benutzerdefinierte Domänennamen und jeweils mehrere Aliase haben, sind wir die perfekte Lösung für Sie. Beachten Sie, dass Sie bei Bedarf weiterhin Speicherbeschränkungen pro Domäne oder Alias erzwingen können.
Lesen Sie den E-Mail-Service-Vergleich
Wie funktioniert es
-
Mit Ihrem E-Mail-Client wie Apple Mail, Thunderbird, Gmail oder Outlook stellen Sie eine Verbindung zu unserem sicheren E-Mail-Programm her IMAP Servern mit Ihrem Benutzernamen und Passwort:
- Ihr Benutzername ist Ihr vollständiger Alias mit Ihrer Domain, z
hello@example.com
. - Ihr Passwort wird zufällig generiert und Ihnen beim Klicken nur 30 Sekunden lang angezeigt Generiere Passwort aus Mein Konto Domänen Aliase.
- Ihr Benutzername ist Ihr vollständiger Alias mit Ihrer Domain, z
-
Sobald die Verbindung hergestellt ist, sendet Ihr E-Mail-Client IMAP-Protokollbefehle an unseren IMAP-Server, um Ihr Postfach synchron zu halten. Dazu gehören das Schreiben und Speichern von E-Mail-Entwürfen und andere Aktionen, die Sie möglicherweise durchführen (z. B. das Kennzeichnen einer E-Mail als „Wichtig“ oder das Markieren einer E-Mail als Spam/Junk-Mail).
-
Mail-Exchange-Server (allgemein als „MX“-Server bekannt) empfangen neue eingehende E-Mails und speichern sie in Ihrem Postfach. In diesem Fall wird Ihr E-Mail-Client benachrichtigt und Ihr Postfach synchronisiert. Unsere Mail-Exchange-Server können Ihre E-Mail an einen oder mehrere Empfänger weiterleiten (einschließlich Webhooks), speichern Sie Ihre E-Mails für Sie in Ihrem verschlüsselten IMAP-Speicher bei uns, oder beides!
Möchten Sie mehr erfahren? Lesen So richten Sie die E-Mail-Weiterleitung ein, wie unser Mail-Exchange-Service funktioniert, oder ansehen unsere Guides.
-
Hinter den Kulissen funktioniert unser sicheres E-Mail-Speicherdesign auf zwei Arten, damit Ihre Postfächer verschlüsselt bleiben und nur Sie darauf zugreifen können:
-
Wenn für Sie neue E-Mails von einem Absender eingehen, schreiben unsere Mail-Exchange-Server für Sie in ein individuelles, temporäres und verschlüsseltes Postfach.
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!
-
Wenn Sie mit Ihrem E-Mail-Client eine Verbindung zu unserem IMAP-Server herstellen, wird Ihr Passwort im Speicher verschlüsselt und zum Lesen und Schreiben in Ihr Postfach verwendet. Mit diesem Passwort kann Ihr Postfach nur gelesen und beschrieben werden. Denken Sie daran, dass Sie der Einzige mit diesem Passwort sind. nur du Sie können Ihr Postfach lesen und darauf schreiben, wenn Sie darauf zugreifen. Wenn Ihr E-Mail-Client das nächste Mal versucht, E-Mails oder Synchronisierungen abzurufen, werden Ihre neuen Nachrichten aus diesem temporären Postfach übertragen und mit Ihrem angegebenen Passwort in Ihrer eigentlichen Postfachdatei gespeichert. Beachten Sie, dass dieses temporäre Postfach anschließend bereinigt und 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 auf den temporären Festplattenspeicher schreiben. Stattdessen wird Ihr im Speicher verschlüsseltes IMAP-Passwort abgerufen und verwendet. Wenn eine Nachricht an Sie zugestellt werden soll, senden wir in Echtzeit eine WebSocket-Anfrage an alle IMAP-Server und fragen sie, ob sie eine aktive Sitzung für Sie haben (dies ist der Abrufteil), und leiten diese anschließend weiter verschlüsseltes In-Memory-Passwort – damit wir nicht in ein temporäres Postfach schreiben müssen, können wir mit Ihrem verschlüsselten Passwort in Ihr tatsächlich verschlüsseltes Postfach schreiben.
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 hergestellt. Sie können auch jederzeit ein neues Backup anfordern oder das neueste Backup von herunterladen Mein Konto Domänen Aliase. Wenn Sie sich entscheiden, zu einem anderen E-Mail-Dienst zu wechseln, können Sie Ihre Postfächer und Backups jederzeit problemlos migrieren, herunterladen, exportieren und löschen.
Technologien
Datenbanken
Wir haben andere mögliche Datenbankspeicherschichten untersucht, aber keine entsprach unseren Anforderungen so gut wie SQLite:
Datenbank | Verschlüsselung im Ruhezustand | Sandboxed Postfächer | Lizenz | Überall im Einsatz |
---|---|---|---|---|
SQLite ⭐ | ✅ Ja mit SQLite3MultipleCiphers | ✅ | ✅ Gemeinfrei | ✅ |
MongoDB | ❌ „Nur in MongoDB Enterprise verfügbar“ | ❌ Relationale Datenbank | ❌ AGPL und SSPL-1.0 | ❌ |
rqlite | ❌ Nur Netzwerk | ❌ Relationale Datenbank | ✅ MIT | ❌ |
dqlite | ❌ Ungetestet und noch nicht unterstützt? | ❌ Ungetestet und noch nicht unterstützt? | ✅ LGPL-3.0-only | ❌ |
PostgreSQL | ✅ Ja | ❌ Relationale Datenbank | ✅ PostgreSQL (ähnlich zu BSD oder MIT ) | ❌ |
MariaDB | ✅ Nur für InnoDB | ❌ Relationale Datenbank | ✅ GPLv2 und BUSL-1.1 | ❌ |
KakerlakeDB | ❌ Funktion nur für Unternehmen | ❌ Relationale Datenbank | ❌ BUSL-1.1 und andere | ❌ |
Hier ist ein Blogbeitrag, der mehrere SQLite-Datenbankspeicheroptionen vergleicht in der Tabelle oben.
Sicherheit
Zu jeder Zeit verwenden wir Verschlüsselung im Ruhezustand (AES-256), Verschlüsselung während der Übertragung (TLS), DNS über HTTPS („DoH“) mit 🍊 Mandarine, und sqleet (ChaCha20-Poly1305) Verschlüsselung auf Postfächern. Darüber hinaus verwenden wir eine tokenbasierte Zwei-Faktor-Authentifizierung (im Gegensatz zu SMS, die verdächtig ist). Man-in-the-Middle-Angriffe), rotierte SSH-Schlüssel mit deaktiviertem Root-Zugriff, exklusiver Zugriff auf Server über eingeschränkte IP-Adressen und mehr.
Im Falle eines böser Dienstmädchenangriff oder betrügerischer Mitarbeiter eines Drittanbieters, Ihr Postfach kann weiterhin nur mit Ihrem generierten Passwort geöffnet werden. Seien Sie versichert, dass wir uns nicht auf andere Drittanbieter als unsere SOC-Typ-2-Beschwerdeserveranbieter Cloudflare, Digital Ocean und Vultr verlassen.
Unser Ziel ist es, möglichst wenige zu haben Single Point of Failures wie möglich.
Postfächer
tldr; Unsere IMAP-Server nutzen individuell verschlüsselte SQLite-Datenbanken für jedes Ihrer Postfächer.
SQLite ist äußerst beliebt 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
und so weiter – eine für jeden als .sqlite
Datenbankdatei. Wir benennen die Datenbankdateien auch nicht mit der E-Mail-Adresse – stattdessen verwenden wir BSON ObjectID und generierte eindeutige UUIDs, die nicht verraten, wem das Postfach gehört oder unter welcher E-Mail-Adresse es sich befindet (z. B. 353a03f21e534321f5d6e267.sqlite
).
Jede dieser Datenbanken wird mit Ihrem Passwort (das nur Sie haben) verschlüsselt sqleet (ChaCha20-Poly1305). Das bedeutet, dass Ihre Postfächer individuell verschlüsselt, in sich geschlossen und Sandkasten, und tragbar.
Wir haben SQLite wie folgt optimiert PRAGMA:
PRAGMA | Zweck |
---|---|
cipher=chacha20 | ChaCha20-Poly1305 SQLite-Datenbankverschlüsselung. Referenz better-sqlite3-multiple-ciphers unter Projekte für mehr Einblick. |
key="****************" | Dabei handelt es sich um Ihr entschlüsseltes In-Memory-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 sicherzustellen). |
journal_model=WAL | Write-Ahead-Protokoll ("WAL") Dies steigert die Leistung und ermöglicht den gleichzeitigen Lesezugriff. |
busy_timeout=5000 | Verhindert Schreibsperrfehler während andere Schreibvorgänge stattfinden. |
synchronous=NORMAL | Erhöht die Haltbarkeit von Transaktionen ohne das Risiko einer Datenkorruption. |
foreign_keys=ON | Erzwingt, dass Fremdschlüsselreferenzen (z. B. eine Beziehung von einer Tabelle zu einer anderen) erzwungen werden. Standardmäßig ist dies in SQLite nicht aktiviert, aber für die Validierung und Datenintegrität sollte es aktiviert sein. |
encoding='UTF-8' | Standardkodierung zu verwenden, um die Vernunft der Entwickler sicherzustellen. |
Alle anderen Standardeinstellungen stammen von SQLite, wie in angegeben offizielle PRAGMA-Dokumentation.
Parallelität
tldr; Wir gebrauchen
WebSocket
für gleichzeitige Lese- und Schreibvorgänge in Ihren verschlüsselten SQLite-Postfächern.
Liest
Möglicherweise löst sich Ihr E-Mail-Client auf Ihrem Telefon auf imap.forwardemail.net
zu einer unserer Digital Ocean IP-Adressen – und Ihr Desktop-Client löst möglicherweise eine separate IP von einer anderen auf Anbieter insgesamt.
Unabhängig davon, mit welchem IMAP-Server sich Ihr E-Mail-Client verbindet, 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 ist etwas anders – da SQLite eine eingebettete Datenbank ist und Ihr Postfach standardmäßig in einer einzigen Datei gespeichert ist.
Wir hatten Optionen erkundet wie litestream
, rqlite
, und dqlite
unten – jedoch entsprach keines davon unseren Anforderungen.
Um Schreibvorgänge mit Write-Ahead-Logging durchzuführen ("WAL") aktiviert – wir müssen sicherstellen, dass nur ein Server ("Primär") dafür verantwortlich ist. WAL beschleunigt die Parallelität drastisch und ermöglicht einen Autor und mehrere Leser.
Der Primärserver wird auf den Datenservern ausgeführt, wobei die bereitgestellten Volumes die verschlüsselten Postfächer enthalten. Aus Sicht der Verteilung könnten Sie alle einzelnen IMAP-Server dahinter berücksichtigen imap.forwardemail.net
sekundäre Server zu sein („Sekundär“).
Wir erreichen eine wechselseitige Kommunikation mit WebSockets:
- Primärserver verwenden eine Instanz von ws'S
WebSocketServer
Server. - Sekundärserver verwenden eine Instanz von ws'S
WebSocket
Client, der umschlossen ist websocket-wie-versprochen und erneute Verbindung zum WebSocket. Diese beiden Wrapper sorgen dafür, dass dieWebSocket
stellt die Verbindung wieder her und kann Daten für bestimmte Datenbankschreibvorgänge senden und empfangen.
Backups
tldr; Es werden täglich Backups Ihrer verschlüsselten Postfächer erstellt. Sie können auch sofort ein neues Backup anfordern oder jederzeit das neueste Backup herunterladen Mein Konto Domänen Aliase.
Für Backups führen wir einfach SQLite aus VACUUM INTO
Befehl jeden Tag während der IMAP-Befehlsverarbeitung, die Ihr verschlüsseltes Passwort aus einer speicherinternen IMAP-Verbindung nutzt. Backups werden gespeichert, wenn kein vorhandenes Backup erkannt wird oder wenn die SHA-256 Der Hash der Datei hat sich im Vergleich zur letzten Sicherung geändert.
Beachten Sie, dass wir die verwenden VACUUM INTO
Befehl im Gegensatz zum integrierten backup
Befehl, denn wenn eine Seite während a geändert wird backup
Befehlsoperation, dann muss es von vorne beginnen. Der VACUUM INTO
Der Befehl erstellt einen Schnappschuss. Siehe diese Kommentare auf GitHub und Hacker-News für mehr Einblick.
Zusätzlich verwenden wir VACUUM INTO
im Gegensatz zu backup
, weil das backup
Der Befehl würde die Datenbank für kurze Zeit unverschlüsselt lassen, bis rekey
aufgerufen wird (siehe diesen GitHub Kommentar zur Einsicht).
Die Sekundarstufe wird die Primarstufe über das informieren WebSocket
Verbindung, um das Backup auszuführen – und der Primary erhält dann den Befehl dazu und wird anschließend:
- Stellen Sie eine Verbindung zu Ihrem verschlüsselten Postfach her.
- Erwerben Sie eine Schreibsperre.
- Führen Sie einen WAL-Checkpoint über aus
wal_checkpoint(PASSIVE)
. - Führen Sie das aus
VACUUM INTO
SQLite-Befehl. - Stellen Sie sicher, dass die kopierte Datei mit dem verschlüsselten Passwort geöffnet werden kann (Sicherung/Dummyproofing).
- Laden Sie es zur Speicherung auf Cloudflare R2 hoch (oder auf Ihren eigenen Anbieter, falls angegeben).
Denken Sie daran, dass Ihre Postfächer verschlüsselt sind – und obwohl wir IP-Beschränkungen und andere Authentifizierungsmaßnahmen für die WebSocket-Kommunikation eingerichtet haben – können Sie im Falle eines böswilligen Akteurs sicher sein, dass Ihre Datenbank nicht geöffnet werden kann, wenn die WebSocket-Payload nicht über Ihr IMAP-Passwort verfügt .
Derzeit wird nur ein Backup pro Postfach gespeichert, aber in Zukunft bieten wir möglicherweise eine Point-in-Time-Wiederherstellung an ("PITR").
Suche
Unsere IMAP-Server unterstützen das SEARCH
Befehl mit komplexen Abfragen, regulären Ausdrücken und mehr.
Eine schnelle Suchleistung ist zu verdanken FTS5 und SQLite-Regex.
Wir speichern Date
Werte in den SQLite-Postfächern als ISO 8601 Saiten über Date.prototype.toISOString (mit UTC-Zeitzone, damit Gleichheitsvergleiche ordnungsgemäß funktionieren).
Für alle Eigenschaften, die in Suchanfragen enthalten sind, werden auch Indizes gespeichert.
Projekte
Hier ist eine Tabelle mit Projekten, die wir in unserem Quellcode und Entwicklungsprozess verwenden (alphabetisch sortiert):
Projekt | Zweck |
---|---|
Ansible | DevOps-Automatisierungsplattform für die einfache Wartung, Skalierung und Verwaltung unserer gesamten Serverflotte. |
Bree | Jobplaner für Node.js und JavaScript mit Cron, Dates, MS, Later und benutzerfreundlicher Unterstützung. |
Kabine | Entwicklerfreundliche JavaScript- und Node.js-Protokollierungsbibliothek mit Blick auf Sicherheit und Datenschutz. |
Junge | 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 Alias-Konfigurationen). |
Mungo | MongoDB-Objektdokumentmodellierung („ODM“), die wir in unserem gesamten Stack verwenden. Wir haben spezielle Helfer geschrieben, die es uns ermöglichen, einfach weiter zu verwenden Mungo mit SQLite 🎉 |
Node.js | Node.js ist die plattformübergreifende Open-Source-JavaScript-Laufzeitumgebung, die alle unsere Serverprozesse ausführt. |
Notizmailer | 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-über-HTTPS-Anfragen. |
SQLite3MultipleCiphers | Verschlüsselungserweiterung für SQLite, um die Verschlüsselung ganzer Datenbankdateien zu ermöglichen (einschließlich des Write-Ahead-Protokolls ("WAL"), Journal, Rollback, …). |
SQLiteStudio | Visueller SQLite-Editor (den Sie auch verwenden können) zum Testen, Herunterladen und Anzeigen von Entwicklungspostfächern. |
SQLite | Eingebettete Datenbankschicht für skalierbare, eigenständige, schnelle und belastbare IMAP-Speicherung. |
Spam-Scanner | Node.js Anti-Spam-, E-Mail-Filter- und Phishing-Präventionstool (unsere Alternative zu Spam-Attentäter und rspamd). |
Mandarine | DNS-über-HTTPS-Anfragen mit Node.js und Caching mit Redis – das sorgt für globale Konsistenz und vieles mehr. |
Donnervogel | Unser Entwicklungsteam verwendet dies (und empfiehlt es auch) als Der bevorzugte E-Mail-Client zur Verwendung mit Forward Email. |
UTM | Unser Entwicklungsteam nutzt diese Erstellung virtueller 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 antreibt. |
Wilde Ente | IMAP-Serverbibliothek – siehe Hinweise dazu Deduplizierung von Anhängen und Unterstützung des IMAP-Protokolls. |
besser-sqlite3-mehrere-Chiffren | Schnelle und einfache API-Bibliothek für Node.js zur programmgesteuerten Interaktion mit SQLite3. |
E-Mail-Vorlagen | Entwicklerfreundliches E-Mail-Framework zum Erstellen, Vorschau und Senden benutzerdefinierter E-Mails (z. B. Kontobenachrichtigungen und mehr). |
JSON-SQL | SQL-Abfrage-Builder mit Syntax im Mongo-Stil. Dies spart unserem Entwicklungsteam Zeit, da wir mit einem datenbankunabhängigen Ansatz weiterhin im Mongo-Stil über den gesamten Stack schreiben können. Es hilft auch, SQL-Injection-Angriffe durch die Verwendung von Abfrageparametern zu vermeiden. |
Knex-Schema-Inspektor | SQL-Dienstprogramm zum Extrahieren von Informationen über das vorhandene Datenbankschema. Dadurch können wir ganz einfach überprüfen, ob alle Indizes, Tabellen, Spalten, Einschränkungen und mehr gültig sind und sind 1:1 damit, wie sie sein sollten. Wir haben sogar automatisierte Hilfsprogramme geschrieben, um neue Spalten und Indizes hinzuzufügen, wenn Änderungen an Datenbankschemata vorgenommen werden (auch mit äußerst detaillierter Fehlerwarnung). |
Knex | SQL-Abfrage-Builder, den wir nur für Datenbankmigrationen und Schemavalidierungen verwenden knex-schema-inspector . |
Mandarin | Automatisch i18n Phrasenübersetzung mit Unterstützung für Markdown Google Cloud Translation API. |
mx-verbinden | Node.js-Paket zum Auflösen und Herstellen von Verbindungen mit MX-Servern und zum Behandeln von Fehlern. |
Uhr2 | Node.js-Produktionsprozessmanager mit integriertem Load Balancer (fein abgestimmt für Leistung). |
SMTP-Server | SMTP-Serverbibliothek – wir verwenden diese für unseren Mail-Austausch („MX“) und ausgehende SMTP-Server. |
ImapTest | Nützliches Tool zum Testen von IMAP-Servern anhand von Benchmarks und zur Kompatibilität des IMAP-Protokolls der RFC-Spezifikation. Dieses Projekt wurde von erstellt Taubenschlag Team (ein aktiver Open-Source-IMAP- und POP3-Server seit Juli 2002). Wir haben unseren IMAP-Server mit diesem Tool ausgiebig getestet. |
Hier finden Sie weitere Projekte, in denen wir zum Einsatz kommen Unser Quellcode auf GitHub.
Anbieter
Anbieter | Zweck |
---|---|
Wolkenflare | Verwendung von DNS-Anbietern, Gesundheitsprüfungen, Lastausgleichsdiensten und Sicherungsspeicher Cloudflare R2. |
Digitaler Ozean | Dediziertes Server-Hosting, SSD-Blockspeicher und verwaltete Datenbanken. |
Vultr | Dediziertes Server-Hosting und SSD-Blockspeicher. |
Gedanken
Prinzipien
„E-Mail weiterleiten“ ist nach diesen Grundsätzen konzipiert:
- Seien Sie stets entwicklerfreundlich, sicherheits- und datenschutzorientiert und transparent.
- Sich an etw. halten MVC, Unix, KISS, DRY, YAGNI, Zwölf Faktor, Ockhams Rasiermesser, und Hundefutter
- Zielen Sie auf die Scrappy-, Bootstrapped- und Ramen-profitabel Entwickler
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 führten, wie oben beschrieben.
Eine davon war, es mit zu versuchen rclone und SQLite zusammen mit einer S3-kompatiblen Speicherschicht.
Dieses Experiment führte uns dazu, Randfälle rund um rclone, SQLite und besser zu verstehen und zu entdecken VFS Verwendung:
- Wenn Sie aktivieren
--vfs-cache-mode writes
Flag mit rclone, dann sind Lesevorgänge in Ordnung, Schreibvorgänge werden jedoch zwischengespeichert.- Wenn Sie mehrere global verteilte IMAP-Server haben, ist der Cache auf allen Servern deaktiviert, es sei denn, Sie haben einen einzelnen Writer und mehrere Listener (z. B. einen Pub/Sub-Ansatz).
- Das ist unglaublich komplex und das Hinzufügen zusätzlicher Komplexität wie dieser führt zu mehr Single Points of Failure.
- S3-kompatible Speicheranbieter unterstützen keine teilweisen Dateiänderungen – also jede Änderung der Datei
.sqlite
Die Datei führt zu einer vollständigen Änderung und einem erneuten Hochladen der Datenbank. - Andere Lösungen wie
rsync
existieren, aber sie konzentrieren sich nicht auf Write-Ahead-Log ("WAL")-Unterstützung – also haben wir uns letztendlich für Litestream entschieden. Glücklicherweise verschlüsselt unsere Verschlüsselungsnutzung bereits die WAL Dateien für uns, sodass wir uns hierfür nicht auf Litestream verlassen müssen. Wir waren jedoch noch nicht davon überzeugt, dass Litestream für den Produktionseinsatz geeignet ist, und haben unten ein paar Anmerkungen dazu. - Mit dieser Option von
--vfs-cache-mode writes
(Die nur Möglichkeit, SQLite zu verwendenrclone
für Schreibvorgänge) versucht, die gesamte Datenbank von Grund auf in den Arbeitsspeicher zu kopieren – die Handhabung eines 10-GB-Postfachs ist in Ordnung, die Handhabung mehrerer Postfächer mit übermäßig hohem Speicher führt jedoch dazu, dass die IMAP-Server an Speicherbeschränkungen stoßen undENOMEM
Fehler, Segmentierungsfehler und Datenbeschädigung.
- Wenn Sie versuchen, SQLite zu verwenden Virtuelle Tische (z.B. mit s3db), um Daten live auf einer S3-kompatiblen Speicherschicht zu haben, werden Sie auf mehrere weitere Probleme stoßen:
- Lese- und Schreibvorgänge werden extrem langsam sein, da S3-API-Endpunkte mit HTTP erreicht werden müssen
GET
,PUT
,HEAD
, undPOST
Methoden. - Entwicklungstests haben gezeigt, dass mehr als 500.000 bis 1 Mio. Datensätze im Glasfaser-Internet immer noch durch den Schreib- und Lesedurchsatz bei S3-kompatiblen Anbietern begrenzt sind. Zum Beispiel sind unsere Entwickler gelaufen
for
Schleifen, um sowohl sequentielles SQL auszuführenINSERT
Anweisungen und solche, die große Datenmengen in großen Mengen schreiben. In beiden Fällen war die Leistung erstaunlich langsam. - Virtuelle Tische kann keine Indizes haben,
ALTER TABLE
Aussagen und andere Einschränkungen – was je nach Datenmenge zu Verzögerungen von mehr als 1-2 Minuten oder mehr führt. - Objekte wurden unverschlüsselt gespeichert und es ist keine native Verschlüsselungsunterstützung verfügbar.
- Lese- und Schreibvorgänge werden extrem langsam sein, da S3-API-Endpunkte mit HTTP erreicht werden müssen
- Wir haben auch die Verwendung untersucht sqlite-s3vfs Dies ähnelt konzeptionell und technisch dem vorherigen Aufzählungspunkt (hat also die gleichen Probleme). Eine Möglichkeit wäre die Verwendung eines Customs
sqlite3
Build mit Verschlüsselung verpackt, z wxSQLite3 (die wir derzeit in unserer Lösung oben verwenden) durch Bearbeiten der Setup-Datei. - Ein weiterer möglicher Ansatz wäre die Verwendung von Multiplex-ErweiterungDies ist jedoch auf 32 GB begrenzt und würde komplexe Bau- und Entwicklungsprobleme erfordern.
ALTER TABLE
Anweisungen sind erforderlich (dies schließt die Verwendung virtueller Tabellen vollständig aus). Wir brauchenALTER TABLE
Anweisungen, damit unser Haken mitknex-schema-inspector
ordnungsgemäß funktionieren – wodurch sichergestellt wird, dass die Daten nicht beschädigt werden und die abgerufenen Zeilen in gültige Dokumente gemäß unseren Richtlinien umgewandelt werden könnenmongoose
Schemadefinitionen (einschließlich Einschränkungen, Variablentypen und willkürlicher Datenvalidierung).- Fast alle S3-kompatiblen Projekte im Zusammenhang mit SQLite in der Open-Source-Community sind in Python (und nicht in JavaScript, das wir für 100 % unseres Stacks verwenden).
- Komprimierungsbibliotheken wie z sqlite-zstd (sehen Kommentare) sehen vielversprechend aus, aber ist möglicherweise noch nicht für den Produktionseinsatz bereit. Stattdessen erfolgt eine anwendungsseitige Komprimierung von Datentypen wie z
String
,Object
,Map
,Array
,Set
, undBuffer
wird ein saubererer und einfacherer Ansatz sein (und ist auch einfacher zu migrieren, da wir eine speichern könntenBoolean
Flagge oder Säule – oder sogar nutzenPRAGMA
user_version=1
zur Komprimierung bzwuser_version=0
für keine Komprimierung als Datenbankmetadaten).- Glücklicherweise haben wir in unserem IMAP-Serverspeicher bereits die Deduplizierung von Anhängen implementiert – daher behält nicht jede Nachricht mit demselben Anhang eine Kopie des Anhangs – stattdessen wird ein einzelner Anhang für mehrere Nachrichten und Threads in einem Postfach (und einem fremden Postfach) gespeichert Referenz wird anschließend verwendet).
- Das Projekt Litestream, eine SQLite-Replikations- und Backup-Lösung, ist sehr vielversprechend und wir werden es höchstwahrscheinlich in Zukunft nutzen.
- Ich möchte die Autoren nicht diskreditieren – denn wir lieben ihre Arbeit und ihre Beiträge zu Open Source seit weit über einem Jahrzehnt –, aber aus der Praxis in der Praxis geht hervor, dass dies der Fall ist kann eine Menge Kopfschmerzen verursachen und Möglicher Datenverlust durch die Nutzung.
- Die Backup-Wiederherstellung muss reibungslos und einfach sein. Verwenden einer Lösung wie MongoDB mit
mongodump
undmongoexport
ist nicht nur mühsam, sondern auch zeitintensiv und weist eine komplexe Konfiguration auf.- SQLite-Datenbanken machen es einfach (es ist eine einzelne Datei).
- Wir wollten eine Lösung entwickeln, bei der Benutzer ihren Briefkasten jederzeit mitnehmen und verlassen können.
- Einfache Node.js-Befehle für
fs.unlink('mailbox.sqlite'))
und es wird dauerhaft aus dem Festplattenspeicher gelöscht. - Ebenso können wir eine S3-kompatible API mit HTTP verwenden
DELETE
um Snapshots und Backups für Benutzer einfach zu entfernen.
- Einfache Node.js-Befehle für
- SQLite war die einfachste, schnellste und kostengünstigste Lösung.
Mangel an Alternativen
Unseres Wissens nach sind keine anderen E-Mail-Dienste auf diese Weise konzipiert und auch nicht Open Source.
Wir Ich denke, das könnte daran liegen zu bestehenden E-Mail-Diensten mit veralteter Technologie in der Produktion Spaghetti-Code 🍝.
Die meisten, wenn nicht alle bestehenden E-Mail-Dienstanbieter sind entweder Closed-Source-Anbieter oder werben als Open-Source-Anbieter. aber in Wirklichkeit ist nur ihr Frontend Open Source.
Der sensibelste Teil einer E-Mail (die eigentliche Speicher/IMAP/SMTP-Interaktion) wird alles auf dem Back-End (Server) erledigt und nicht auf dem Frontend (Client).
Probieren Sie „E-Mail weiterleiten“ aus
Melden Sie sich noch heute an unter https://forwardemail.net! 🚀