Gecodeerde SQLite-mailboxen voor uw privacy
In tegenstelling tot andere e-maildiensten zorgen wij ervoor dat alleen u te allen tijde toegang heeft tot uw mailbox .
- Zoek pagina
- Inhoudsopgave
Voorwoord
tldr; Onze e-mailservice is 100% open source en privacygericht via veilige en gecodeerde SQLite-mailboxen.
Totdat we lanceerden IMAP-ondersteuning, gebruikten we MongoDB voor onze aanhoudende behoeften op het gebied van gegevensopslag.
Deze technologie is geweldig en we gebruiken deze nog steeds – maar om encryptie-at-rest te hebben met MongoDB moet je een provider gebruiken die MongoDB Enterprise aanbiedt, zoals Digital Ocean of Mongo Atlas – of betalen voor een bedrijfslicentie (en vervolgens moeten werken met latentie van het verkoopteam).
Ons team van E-mail doorsturen had behoefte aan een ontwikkelaarsvriendelijke, schaalbare, betrouwbare en gecodeerde opslagoplossing voor IMAP-mailboxen. Als open-sourceontwikkelaars was het gebruik van een technologie waarvoor je licentiekosten moet betalen om de functie voor versleuteling in rust te krijgen, tegen onze principes – en dus hebben we vanaf het begin geëxperimenteerd, onderzocht en een nieuwe oplossing ontwikkeld om aan deze behoeften te voldoen.
In plaats van een gedeelde database te gebruiken om uw mailboxen op te slaan, slaan wij uw mailboxen afzonderlijk op en coderen we deze met uw wachtwoord (dat alleen u heeft). 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 beginnen).
Blijf lezen terwijl we hieronder een diepe duik nemen met a vergelijking van e-mailserviceproviders, hoe onze dienstverlening werkt, onze technologiestapel, en meer.
Vergelijking van e-mailproviders
Wij zijn de enige 100% open source en op privacy gerichte e-mailserviceprovider die individueel gecodeerde SQLite-mailboxen opslaat, een onbeperkt aantal domeinen, aliassen en gebruikers biedt, en uitgaande SMTP-, IMAP- en POP3-ondersteuning biedt:
In tegenstelling tot andere e-mailproviders hoeft u bij Forward Email niet per domein of alias voor opslag te betalen. De opslag wordt gedeeld over uw hele account. Als u dus meerdere aangepaste domeinnamen en meerdere aliassen op elk account heeft, dan zijn wij de perfecte oplossing voor u. Houd er rekening mee dat u desgewenst nog steeds opslaglimieten kunt afdwingen per domein of alias.
Lees de vergelijking van e-mailservices
Hoe werkt het
-
Met uw e-mailclient zoals Apple Mail, Thunderbird, Gmail of Outlook maakt u verbinding met onze beveiligde IMAP servers die uw gebruikersnaam en wachtwoord gebruiken:
- 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 weergegeven als u klikt Genereer wachtwoord van Mijn Account Domeinen Aliassen.
- Uw gebruikersnaam is uw volledige alias met uw domein, zoals
-
Eenmaal verbonden, zal uw e-mailclient verzenden IMAP-protocolopdrachten naar onze IMAP-server om uw mailbox gesynchroniseerd te houden. Dit omvat het schrijven en opslaan van concept-e-mails en andere acties die u kunt ondernemen (bijvoorbeeld een e-mail labelen als belangrijk of een e-mail markeren als spam/ongewenste e-mail).
-
Mailuitwisselingsservers (algemeen bekend als "MX"-servers) ontvangen nieuwe inkomende e-mail en slaan deze op in uw mailbox. Wanneer dit gebeurt, ontvangt uw e-mailclient een melding en wordt uw mailbox gesynchroniseerd. Onze mailuitwisselingsservers kunnen uw e-mail doorsturen naar een of meer ontvangers (inclusief webhaken), bewaar uw e-mail voor u in uw gecodeerde IMAP-opslag bij ons, of allebei!
Wilt u meer weten? Lezen hoe u het doorsturen van e-mail instelt, hoe onze postuitwisselingsservice werkt, of bekijken onze gidsen.
-
Achter de schermen werkt ons veilige e-mailopslagontwerp op twee manieren om uw mailboxen gecodeerd te houden en alleen voor u toegankelijk:
-
Wanneer er nieuwe e-mail voor u wordt ontvangen van een afzender, schrijven onze mailuitwisselingsservers voor u naar een individuele, tijdelijke en gecodeerde mailbox.
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!
-
Wanneer u met uw e-mailclient verbinding maakt met onze IMAP-server, wordt uw wachtwoord gecodeerd in het geheugen en gebruikt om te lezen en te schrijven naar uw mailbox. Alleen met dit wachtwoord kan uw mailbox worden gelezen en geschreven. Houd er rekening mee dat, aangezien u de enige bent met dit wachtwoord, alleen jij kunt lezen en schrijven naar uw mailbox wanneer u deze opent. De volgende keer dat uw e-mailclient probeert te peilen naar e-mail of synchronisaties, worden uw nieuwe berichten overgebracht vanuit deze tijdelijke mailbox en opgeslagen in uw daadwerkelijke mailboxbestand met behulp van het door u opgegeven wachtwoord. Houd er rekening mee dat deze tijdelijke mailbox achteraf wordt opgeschoond en verwijderd, zodat alleen uw met een wachtwoord beveiligde mailbox de berichten bevat.
-
Als u verbonden bent met IMAP (bijvoorbeeld met behulp van een e-mailclient zoals Apple Mail of Thunderbird), hoeven we niet naar tijdelijke schijfopslag te schrijven. In plaats daarvan wordt uw in het geheugen gecodeerde IMAP-wachtwoord opgehaald en gebruikt. Wanneer een bericht bij u probeert te worden afgeleverd, sturen we in realtime een WebSocket-verzoek naar alle IMAP-servers met de vraag of ze een actieve sessie voor u hebben (dit is het ophaalgedeelte), en geven dat vervolgens door gecodeerd wachtwoord in het geheugen – we hoeven dus niet naar een tijdelijke mailbox te schrijven; we kunnen met uw gecodeerde wachtwoord naar uw daadwerkelijke gecodeerde mailbox schrijven.
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!
-
-
Back-ups van uw gecodeerde mailboxen worden dagelijks gemaakt. U kunt ook op elk moment een nieuwe back-up aanvragen of de nieuwste back-up downloaden van Mijn Account Domeinen Aliassen. Als u besluit over te stappen naar een andere e-mailservice, kunt u uw mailboxen en back-ups op elk gewenst moment eenvoudig migreren, downloaden, exporteren en opschonen.
Technologieën
Databases
We hebben andere mogelijke lagen voor databaseopslag onderzocht, maar geen enkele voldeed zo goed aan onze eisen als SQLite:
Database | Versleuteling in rust | In de zandbak Brievenbussen | Licentie | Overal gebruikt |
---|---|---|---|---|
SQLiet ⭐ | ✅Ja met SQLite3Meerdere cijfers | ✅ | ✅ Publiek domein | ✅ |
MongoDB | ❌ "Alleen beschikbaar in MongoDB Enterprise" | ❌ Relationele database | ❌AGPL en SSPL-1.0 | ❌ |
rqliet | ❌ Alleen netwerk | ❌ Relationele database | ✅ MIT | ❌ |
dqliet | ❌ Niet getest en nog niet ondersteund? | ❌ Niet getest en nog niet ondersteund? | ✅ LGPL-3.0-only | ❌ |
PostgreSQL | ✅ Ja | ❌ Relationele database | ✅ PostgreSQL (gelijkwaardig aan BSD of MIT ) | ❌ |
MariaDB | ✅ Alleen voor InnoDB | ❌ Relationele database | ✅ GPLv2 en BUSL-1.1 | ❌ |
KakkerlakDB | ❌ Functie alleen voor bedrijven | ❌ Relationele database | ❌ BUSL-1.1 en anderen | ❌ |
Hier is een blogpost waarin verschillende SQLite-databaseopslagopties worden vergeleken in de tabel hierboven.
Veiligheid
Wij gebruiken te allen tijde encryptie-in-rust (AES-256), encryptie-in-transit (TLS), DNS via HTTPS ("DoH") met 🍊 Mandarijn, en vierkant (ChaCha20-Poly1305) encryptie op mailboxen. Daarnaast maken we gebruik van op tokens gebaseerde twee-factor-authenticatie (in tegenstelling tot sms, wat verdacht is). man-in-the-middle-aanvallen), geroteerde SSH-sleutels met root-toegang uitgeschakeld, exclusieve toegang tot servers via beperkte IP-adressen, en meer.
In het geval van een boze meid aanval of een malafide werknemer van een externe leverancier, uw mailbox kan nog steeds alleen worden geopend met uw gegenereerde wachtwoord. Wees gerust, we vertrouwen niet op andere externe leveranciers dan onze SOC Type 2-klachtenserverproviders van Cloudflare, Digital Ocean en Vultr.
Ons doel is om er zo weinig mogelijk te hebben enig punt van mislukkingen als mogelijk.
Brievenbussen
tldr; Onze IMAP-servers gebruiken individueel gecodeerde SQLite-databases voor elk van uw mailboxen.
SQLite is extreem populair ingebouwde database – deze draait momenteel op uw telefoon en computer – en gebruikt door bijna alle belangrijke technologieën.
Op onze gecodeerde servers is er bijvoorbeeld een SQLite-databasemailbox voor linux@example.com
, info@example.com
, hello@example.com
enzovoort – één voor elk als a .sqlite
databasebestand. We geven de databasebestanden ook geen naam met het e-mailadres – in plaats daarvan gebruiken we BSON ObjectID en unieke gegenereerde UUID's die niet delen van wie de mailbox is of onder welk e-mailadres deze staat (bijv. 353a03f21e534321f5d6e267.sqlite
).
Elk van deze databases wordt zelf gecodeerd met uw wachtwoord (dat alleen u heeft). vierkant (ChaCha20-Poly1305). Dit betekent dat uw mailboxen individueel gecodeerd, op zichzelf staand, in de zandbaken draagbaar.
We hebben SQLite verfijnd met het volgende PRAGMA:
PRAGMA | Doel |
---|---|
cipher=chacha20 | ChaCha20-Poly1305 SQLite-database-encryptie. Referentie better-sqlite3-multiple-ciphers onder Projecten voor meer inzicht. |
key="****************" | Dit is uw gedecodeerde, alleen in het geheugen opgeslagen wachtwoord dat via de IMAP-verbinding van uw e-mailclient met onze server wordt doorgegeven. Voor elke lees- en schrijfsessie worden nieuwe database-instances gemaakt en gesloten (om sandboxing en isolatie te garanderen). |
journal_model=WAL | Vooruitschrijven-log ("WAL") wat de prestaties verbetert en gelijktijdige leestoegang mogelijk maakt. |
busy_timeout=5000 | Voorkomt schrijfvergrendelingsfouten terwijl er andere schrijfacties plaatsvinden. |
synchronous=NORMAL | Verhoogt de duurzaamheid van transacties zonder risico op gegevenscorruptie. |
foreign_keys=ON | Dwingt af dat verwijzingen naar externe sleutels (bijvoorbeeld een relatie van de ene tabel naar de andere) worden afgedwongen. Standaard is dit niet ingeschakeld in SQLite, maar voor validatie en gegevensintegriteit moet dit ingeschakeld zijn. |
encoding='UTF-8' | Standaardcodering te gebruiken om het gezond verstand van de ontwikkelaar te garanderen. |
Alle andere standaardinstellingen zijn afkomstig van SQLite zoals opgegeven in de officiële PRAGMA-documentatie.
Gelijktijdigheid
tldr; We gebruiken
WebSocket
voor gelijktijdige lees- en schrijfbewerkingen naar uw gecodeerde SQLite-mailboxen.
Leest
Mogelijk wordt het probleem opgelost door uw e-mailclient op uw telefoon imap.forwardemail.net
naar een van onze Digital Ocean IP-adressen – en uw desktopclient kan een afzonderlijk IP-adres van een ander IP-adres omzetten aanbieder allemaal samen.
Ongeacht met welke IMAP-server uw e-mailclient verbinding maakt, we willen dat de verbinding in realtime en met 100% nauwkeurigheid uit uw database leest. Dit gebeurt via WebSockets.
Schrijft
Schrijven naar uw database is een beetje anders – aangezien SQLite een ingebedde database is en uw mailbox standaard in één bestand staat.
We hadden opties onderzocht zoals litestream
, rqlite
, en dqlite
hieronder – maar geen van deze voldeed aan onze eisen.
Om schrijfbewerkingen uit te voeren met write-ahead-logging ("WAL") ingeschakeld – we moeten ervoor zorgen dat slechts één server ("Primair") hiervoor verantwoordelijk is. WAL versnelt de gelijktijdigheid drastisch en maakt één schrijver en meerdere lezers mogelijk.
De Primary draait op de dataservers met de gekoppelde volumes die de gecodeerde mailboxen bevatten. Vanuit distributieoogpunt zou je alle individuele IMAP-servers erachter kunnen overwegen imap.forwardemail.net
als secundaire servers ("Secundair").
Wij realiseren tweerichtingscommunicatie met WebSockets:
- Primaire servers gebruiken een exemplaar van ws'S
WebSocketServer
server. - Secundaire servers gebruiken een exemplaar van ws'S
WebSocket
cliënt waarmee is omwikkeld websocket-zoals beloofd en opnieuw verbinden-websocket. Deze twee wikkels zorgen ervoor dat deWebSocket
maakt opnieuw verbinding en kan gegevens verzenden en ontvangen voor specifieke databaseschrijfbewerkingen.
Back-ups
tldr; Er worden dagelijks back-ups gemaakt van uw gecodeerde mailboxen. U kunt ook direct een nieuwe back-up aanvragen of op elk gewenst moment de nieuwste back-up downloaden Mijn Account Domeinen Aliassen.
Voor back-ups gebruiken we eenvoudigweg SQLite VACUUM INTO
elke dag een opdracht uitvoeren tijdens de verwerking van IMAP-opdrachten, waarbij gebruik wordt gemaakt van uw gecodeerde wachtwoord via een IMAP-verbinding in het geheugen. Back-ups worden opgeslagen als er geen bestaande back-up wordt gedetecteerd of als de SHA-256 hash van het bestand is gewijzigd in vergelijking met de meest recente back-up.
Merk op dat we de gebruiken VACUUM INTO
commando in tegenstelling tot het ingebouwde backup
opdracht omdat als een pagina wordt gewijzigd tijdens een backup
commandobewerking, dan moet het opnieuw beginnen. De VACUUM INTO
commando maakt een momentopname. Zie deze opmerkingen op GitHub en Hackernieuws voor meer inzicht.
Daarnaast gebruiken wij VACUUM INTO
in tegenstelling tot backup
, omdat de backup
commando zou de database gedurende een korte periode onversleuteld laten rekey
wordt aangeroepen (zie dit GitHub opmerking voor inzicht).
De secundaire zal de primaire instrueren over de WebSocket
verbinding om de back-up uit te voeren – en de Primary ontvangt dan de opdracht om dit te doen en zal vervolgens:
- Maak verbinding met uw gecodeerde mailbox.
- Schaf een schrijfvergrendeling aan.
- Voer een WAL-controlepunt uit via
wal_checkpoint(PASSIVE)
. - Voer de ... uit
VACUUM INTO
SQLite-opdracht. - Zorg ervoor dat het gekopieerde bestand kan worden geopend met het gecodeerde wachtwoord (safeguard/dummyproofing).
- Upload het naar Cloudflare R2 voor opslag (of uw eigen provider indien gespecificeerd).
Houd er rekening mee dat uw mailboxen gecodeerd zijn – en hoewel we IP-beperkingen en andere authenticatiemaatregelen hebben getroffen voor WebSocket-communicatie – kunt u er in het geval van een slechte actor zeker van zijn dat, tenzij de WebSocket-payload uw IMAP-wachtwoord heeft, deze uw database niet kan openen .
Er wordt momenteel slechts één back-up per mailbox opgeslagen, maar in de toekomst kunnen we herstel op een bepaald tijdstip aanbieden ("PITR").
Zoekopdracht
Onze IMAP-servers ondersteunen de SEARCH
commando met complexe query's, reguliere expressies en meer.
Snelle zoekprestaties zijn te danken aan FTS5 en sqlite-regex.
Wij slaan op Date
waarden in de SQLite-mailboxen als ISO 8601 snaren via Date.prototype.toISOString (met UTC-tijdzone zodat gelijkheidsvergelijkingen correct functioneren).
Er worden ook indexen opgeslagen voor alle eigendommen die in zoekopdrachten voorkomen.
Projecten
Hier is een tabel met de projecten die we gebruiken in onze broncode en ons ontwikkelingsproces (alfabetisch gesorteerd):
Project | Doel |
---|---|
Ansibel | DevOps-automatiseringsplatform voor het eenvoudig onderhouden, schalen en beheren van onze volledige servervloot. |
Bree | Taakplanner voor Node.js en JavaScript met cron, dates, ms, later en mensvriendelijke ondersteuning. |
Cabine | Ontwikkelaarsvriendelijke JavaScript- en Node.js-logboekbibliotheek met veiligheid en privacy in gedachten. |
Laat | Node.js-framework dat ons volledige architectuur- en technisch ontwerp aanstuurt met MVC en meer. |
MongoDB | NoSQL-databaseoplossing die we gebruiken voor het opslaan van alle andere gegevens buiten mailboxen (bijvoorbeeld uw account, instellingen, domeinen en aliasconfiguraties). |
Mangoest | MongoDB objectdocument modellering ("ODM") die we in onze hele stapel gebruiken. We hebben speciale helpers geschreven waarmee we gewoon kunnen blijven gebruiken Mongoes met SQLite 🎉 |
Node.js | Node.js is de open-source, platformonafhankelijke JavaScript-runtime-omgeving die al onze serverprocessen uitvoert. |
Opmerking mailer | Node.js-pakket voor het verzenden van e-mails, het maken van verbindingen en meer. Wij zijn officieel sponsor van dit project. |
Opnieuw | In-memory database voor caching, publicatie-/abonneerkanalen en DNS via HTTPS-verzoeken. |
SQLite3Meerdere cijfers | Versleutelingsextensie voor SQLite waarmee volledige databasebestanden kunnen worden gecodeerd (inclusief het write-ahead-log ("WAL"), journaal, terugdraaien, ...). |
SQLiteStudio | Visuele SQLite-editor (die u ook kunt gebruiken) om ontwikkelingsmailboxen te testen, downloaden en bekijken. |
SQLiet | Ingebouwde databaselaag voor schaalbare, onafhankelijke, snelle en veerkrachtige IMAP-opslag. |
Spamscanner | Node.js antispam-, e-mailfilter- en phishing-preventietool (ons alternatief voor Spam-moordenaar en rspamd). |
Mandarijn | DNS via HTTPS-verzoeken met Node.js en caching met Redis – wat zorgt voor wereldwijde consistentie en nog veel meer. |
Dondervogel | Ons ontwikkelteam gebruikt dit (en beveelt dit ook aan) als de voorkeurs-e-mailclient die u wilt gebruiken met E-mail doorsturen. |
UTM | Ons ontwikkelingsteam gebruikt deze virtuele machines voor iOS en macOS 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. |
Wilde eend | IMAP-serverbibliotheek – zie de opmerkingen hierover deduplicatie van bijlagen en Ondersteuning voor IMAP-protocol. |
beter-sqlite3-meerdere-cijfers | Snelle en eenvoudige API-bibliotheek waarmee Node.js programmatisch met SQLite3 kan communiceren. |
e-mailsjablonen | Ontwikkelaarsvriendelijk e-mailframework voor het maken, bekijken en verzenden van aangepaste e-mails (bijvoorbeeld accountmeldingen en meer). |
json-sql | SQL-querybouwer met syntaxis in Mongo-stijl. Dit bespaart ons ontwikkelingsteam tijd, omdat we over de hele stapel in Mongo-stijl kunnen blijven schrijven met een database-agnostische aanpak. Het helpt ook om SQL-injectieaanvallen te voorkomen door queryparameters te gebruiken. |
knex-schema-inspecteur | SQL-hulpprogramma om informatie over het bestaande databaseschema te extraheren. Hierdoor kunnen we eenvoudig valideren dat alle indices, tabellen, kolommen, beperkingen en meer geldig zijn en 1:1 met hoe ze zouden moeten zijn. We hebben zelfs geautomatiseerde helpers geschreven om nieuwe kolommen en indexen toe te voegen als er wijzigingen worden aangebracht in databaseschema's (met ook uiterst gedetailleerde foutwaarschuwingen). |
knex | SQL-querybuilder die we alleen gebruiken voor databasemigraties en schemavalidatie knex-schema-inspector . |
mandarijn- | Automatisch ik18n zinsvertaling met ondersteuning voor het gebruik van Markdown Google Cloud-vertaal-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 (verfijnd voor prestaties). |
smtp-server | SMTP-serverbibliotheek – we gebruiken deze voor onze mailuitwisseling ("MX") en uitgaande SMTP-servers. |
ImapTest | Handig hulpmiddel voor het testen van IMAP-servers aan de hand van benchmarks en RFC-specificatie IMAP-protocolcompatibiliteit. Dit project is gemaakt door de Duiventil team (een actieve open-source IMAP- en POP3-server uit juli 2002). Met deze tool hebben we onze IMAP-server uitgebreid getest. |
U kunt andere projecten vinden waarin we gebruiken onze broncode op GitHub.
Aanbieders
Aanbieder | Doel |
---|---|
Wolkflare | DNS-provider, gezondheidscontroles, load balancers en back-upopslag gebruiken Wolkflare R2. |
Digitale Oceaan | Dedicated serverhosting, SSD-blokopslag en beheerde databases. |
vultr | Dedicated serverhosting en SSD-blokopslag. |
Gedachten
Principes
Forward Email is ontworpen volgens deze principes:
- Wees altijd ontwikkelaarsvriendelijk, gericht op beveiliging en privacy, en transparant.
- Houd u aan MVC, Unix, KISS, DRY, YAGNI, Twaalf Factor, Occam's scheermes, en hondenvoer
- Richt je op de scrappy, bootstrapped en ramen-winstgevend ontwikkelaar
Experimenten
tldr; Uiteindelijk is het gebruik van S3-compatibele objectopslag en/of virtuele tabellen technisch niet haalbaar vanwege prestatieredenen en gevoelig voor fouten vanwege geheugenbeperkingen.
We hebben een paar experimenten gedaan in de aanloop naar onze uiteindelijke SQLite-oplossing, zoals hierboven besproken.
Een daarvan was om te proberen het te gebruiken rcloon en SQLite samen met een S3-compatibele opslaglaag.
Dat experiment heeft ertoe geleid dat we randgevallen rondom rclone, SQLite en VFS gebruik:
- Als u inschakelt
--vfs-cache-mode writes
flag met rclone, dan zijn de leesbewerkingen in orde, maar worden de schrijfbewerkingen in de cache opgeslagen.- Als u meerdere wereldwijd verspreide IMAP-servers heeft, zal de cache op deze servers uitgeschakeld zijn, tenzij u een enkele schrijver en meerdere luisteraars heeft (bijvoorbeeld een pub/sub-benadering).
- Dit is ongelooflijk complex en het toevoegen van dergelijke extra complexiteit zal resulteren in meer single points of Failure.
- S3-compatibele opslagproviders ondersteunen geen gedeeltelijke bestandswijzigingen – dat wil zeggen elke wijziging van de
.sqlite
bestand zal resulteren in een volledige wijziging en opnieuw uploaden van de database. - Andere oplossingen zoals
rsync
bestaan, maar ze zijn niet gericht op write-ahead-log ("WAL") ondersteuning – dus hebben we Litestream beoordeeld. Gelukkig codeert ons versleutelingsgebruik de WAL bestanden voor ons, dus daarvoor zijn we niet afhankelijk van Litestream. We hadden echter nog geen vertrouwen in Litestream voor productiegebruik en hebben daarover hieronder een paar opmerkingen. - Met behulp van deze optie van
--vfs-cache-mode writes
(de alleen manier om SQLite te gebruikenrclone
voor schrijfbewerkingen) zal proberen de hele database helemaal opnieuw in het geheugen te kopiëren – het verwerken van één mailbox van 10 GB is prima, maar het verwerken van meerdere mailboxen met een buitengewoon hoge opslagcapaciteit zal ervoor zorgen dat de IMAP-servers tegen geheugenbeperkingen aanlopen enENOMEM
fouten, segmentatiefouten en datacorruptie.
- Als u SQLite probeert te gebruiken Virtuele tafels (bijv. gebruiken s3db) om gegevens live te hebben op een S3-compatibele opslaglaag, dan zul je nog een aantal problemen tegenkomen:
- Lezen en schrijven zal extreem traag zijn, omdat S3 API-eindpunten moeten worden geraakt met HTTP
GET
,PUT
,HEAD
, enPOST
methoden. - Uit ontwikkelingstests is gebleken dat het overschrijden van meer dan 500.000 tot 1 miljoen records op glasvezelinternet nog steeds wordt beperkt door de doorvoersnelheid van schrijven en lezen naar S3-compatibele providers. Onze ontwikkelaars hebben bijvoorbeeld gelopen
for
lussen om beide sequentiële SQL uit te voerenINSERT
verklaringen en verklaringen die grote hoeveelheden gegevens in bulk schreven. In beide gevallen was de uitvoering verbluffend traag. - Virtuele tafels kunnen geen indexen hebben,
ALTER TABLE
verklaringen, en ander beperkingen – wat leidt tot vertragingen van 1-2 minuten of meer, afhankelijk van de hoeveelheid gegevens. - Objecten werden onversleuteld opgeslagen en er is geen ondersteuning voor native versleuteling beschikbaar.
- Lezen en schrijven zal extreem traag zijn, omdat S3 API-eindpunten moeten worden geraakt met HTTP
- We hebben ook onderzoek gedaan naar het gebruik sqlite-s3vfs die conceptueel en technisch vergelijkbaar is met het vorige opsommingsteken (dus dezelfde problemen heeft). Een mogelijkheid zou zijn om gebruik te maken van een gewoonte
sqlite3
build verpakt met encryptie zoals wxSQLite3 (die we momenteel gebruiken in onze oplossing hierboven) door het installatiebestand bewerken. - Een andere mogelijke aanpak was het gebruik van de multiplex-extensie, maar dit heeft een beperking van 32 GB en zou complexe bouw- en ontwikkelingsproblemen vereisen.
ALTER TABLE
-instructies zijn vereist (dus dit sluit het gebruik van virtuele tabellen volledig uit). Wij hebben nodigALTER TABLE
uitspraken om onze haak te slaanknex-schema-inspector
om goed te werken – wat ervoor zorgt dat gegevens niet beschadigd raken en opgehaalde rijen kunnen worden geconverteerd naar geldige documenten volgens onzemongoose
schemadefinities (waaronder beperking, variabel type en willekeurige gegevensvalidatie).- Bijna alle S3-compatibele projecten gerelateerd aan SQLite in de open-sourcegemeenschap zijn in Python (en niet in JavaScript, dat we voor 100% van onze stapel gebruiken).
- Compressiebibliotheken zoals sqlite-zstd (zien opmerkingen) ziet er veelbelovend uit, maar is mogelijk nog niet klaar voor productiegebruik. In plaats daarvan wordt compressie aan de applicatiezijde toegepast op gegevenstypen zoals
String
,Object
,Map
,Array
,Set
, enBuffer
wordt een schonere en eenvoudigere aanpak (en is ook gemakkelijker te migreren, omdat we eenBoolean
vlag of kolom – of zelfs gebruikenPRAGMA
user_version=1
voor compressie ofuser_version=0
voor geen compressie als database-metagegevens).- Gelukkig hebben we deduplicatie van bijlagen al geïmplementeerd in onze IMAP-serveropslag – daarom zal elk bericht met dezelfde bijlage geen kopie van de bijlage bewaren – in plaats daarvan wordt één bijlage opgeslagen voor meerdere berichten en threads in een mailbox (en een buitenlandse referentie wordt vervolgens gebruikt).
- Het project Litestream, een SQLite-replicatie- en back-upoplossing, is veelbelovend en we zullen het waarschijnlijk in de toekomst gebruiken.
- Om de auteur(s) niet in diskrediet te brengen – omdat we al meer dan tien jaar dol zijn op hun werk en bijdragen aan open-source – maar uit praktijkgebruik blijkt dat er kan veel hoofdpijn zijn en potentieel gegevensverlies door gebruik.
- Back-upherstel moet wrijvingsloos en triviaal zijn. Met behulp van een oplossing zoals MongoDB met
mongodump
enmongoexport
is niet alleen vervelend, maar ook tijdrovend en heeft configuratiecomplexiteit.- SQLite-databases maken het eenvoudig (het is één bestand).
- We wilden een oplossing ontwerpen waarbij gebruikers hun mailbox konden pakken en op elk moment konden vertrekken.
- Eenvoudige Node.js-opdrachten om
fs.unlink('mailbox.sqlite'))
en het wordt permanent verwijderd uit de schijfopslag. - We kunnen op dezelfde manier een S3-compatibele API met HTTP gebruiken
DELETE
om eenvoudig snapshots en back-ups voor gebruikers te verwijderen.
- Eenvoudige Node.js-opdrachten om
- SQLite was de eenvoudigste, snelste en meest kosteneffectieve oplossing.
Gebrek aan alternatieven
Voor zover wij weten zijn geen andere e-maildiensten op deze manier ontworpen en zijn ze ook niet open source.
Wij denk dat dit misschien te wijten is naar bestaande e-maildiensten met verouderde technologie in productie spaghetti-code 🍝.
De meeste, zo niet alle, bestaande e-mailserviceproviders zijn gesloten bron of adverteren als open bron. maar in werkelijkheid is alleen hun front-end open source.
Het meest gevoelige deel van e-mail (de daadwerkelijke opslag/IMAP/SMTP-interactie) gebeurt allemaal op de back-end (server), en niet aan de front-end (klant).
Probeer E-mail doorsturen eens
Schrijf je vandaag nog in via https://forwardemail.net! 🚀