KvantsÀkert e-post: Hur vi anvÀnder krypterade SQLite-postlÄdor för att hÄlla din e-post sÀker
Förord
Important
VÄr e-posttjÀnst Àr 100% öppen kÀllkod och integritetsfokuserad genom sÀkra och krypterade SQLite-postlÄdor.
Tills vi lanserade IMAP-stöd anvÀnde vi MongoDB för vÄra behov av persistent datalagring.
Denna teknik Ă€r fantastisk och vi anvĂ€nder den fortfarande idag â men för att ha kryptering vid vila med MongoDB mĂ„ste du anvĂ€nda en leverantör som erbjuder MongoDB Enterprise, sĂ„som Digital Ocean eller Mongo Atlas â eller betala för en företagslicens (och dĂ€refter hantera försĂ€ljningsteamets svarstider).
VĂ„rt team pĂ„ Forward Email behövde en utvecklarvĂ€nlig, skalbar, pĂ„litlig och krypterad lagringslösning för IMAP-postlĂ„dor. Som öppen kĂ€llkodsutvecklare gick det emot vĂ„ra principer att anvĂ€nda en teknik dĂ€r du mĂ„ste betala en licensavgift för att fĂ„ kryptering vid vila â sĂ„ vi experimenterade, forskade och utvecklade en ny lösning frĂ„n grunden för att lösa dessa behov.
IstÀllet för att anvÀnda en delad databas för att lagra dina postlÄdor lagrar och krypterar vi varje postlÄda individuellt med ditt lösenord (som bara du har). VÄr e-posttjÀnst Àr sÄ sÀker att om du glömmer ditt lösenord förlorar du din postlÄda (och mÄste ÄterstÀlla med offline-sÀkerhetskopior eller börja om frÄn början).
FortsÀtt lÀsa nÀr vi gÄr pÄ djupet nedan med en jÀmförelse av e-postleverantörer, hur vÄr tjÀnst fungerar, vÄr teknologistack och mer.
JÀmförelse av e-postleverantörer
Vi Àr den enda 100% öppna kÀllkods- och integritetsfokuserade e-postleverantören som lagrar individuellt krypterade SQLite-postlÄdor, erbjuder obegrÀnsade domÀner, alias och anvÀndare, samt har stöd för utgÄende SMTP, IMAP och POP3:
Till skillnad frĂ„n andra e-postleverantörer behöver du inte betala för lagring per domĂ€n eller alias med Forward Email. Lagringen delas över hela ditt konto â sĂ„ om du har flera egna domĂ€nnamn och flera alias pĂ„ varje Ă€r vi den perfekta lösningen för dig. Observera att du fortfarande kan införa lagringsgrĂ€nser om sĂ„ önskas per domĂ€n eller alias.
LÀs JÀmförelse av E-posttjÀnster
Hur fungerar det
-
Med din e-postklient som Apple Mail, Thunderbird, Gmail eller Outlook â ansluter du till vĂ„ra sĂ€kra IMAP-servrar med ditt anvĂ€ndarnamn och lösenord:
- Ditt anvÀndarnamn Àr ditt fullstÀndiga alias med din domÀn, till exempel
hello@example.com. - Ditt lösenord genereras slumpmÀssigt och visas endast för dig i 30 sekunder nÀr du klickar pÄ Generera Lösenord frÄn Mitt Konto DomÀner Alias.
- Ditt anvÀndarnamn Àr ditt fullstÀndiga alias med din domÀn, till exempel
-
NÀr du Àr ansluten kommer din e-postklient att skicka IMAP-protokollkommandon till vÄr IMAP-server för att hÄlla din brevlÄda synkroniserad. Detta inkluderar att skriva och lagra utkast till e-post och andra ÄtgÀrder du kan göra (t.ex. mÀrka ett e-postmeddelande som Viktigt eller flagga ett e-postmeddelande som SkrÀppost/Spam).
-
E-postutbytesservrar (vanligtvis kallade "MX"-servrar) tar emot ny inkommande e-post och lagrar den i din brevlÄda. NÀr detta hÀnder fÄr din e-postklient en avisering och synkroniserar din brevlÄda. VÄra e-postutbytesservrar kan vidarebefordra din e-post till en eller flera mottagare (inklusive webhooks), lagra din e-post Ät dig i din krypterade IMAP-lagring hos oss, eller bÄda!
Tip
Intresserad av att lÀra dig mer? LÀs hur du stÀller in e-postvidarebefordran, hur vÄr e-postutbyteservice fungerar, eller se vÄra guider.
-
Bakom kulisserna fungerar vÄr sÀkra e-postlagringsdesign pÄ tvÄ sÀtt för att hÄlla dina brevlÄdor krypterade och endast tillgÀngliga för dig:
-
NÀr ny e-post tas emot för dig frÄn en avsÀndare skriver vÄra e-postutbytesservrar till en individuell, temporÀr och krypterad brevlÄda för dig.
-
NÀr du ansluter till vÄr IMAP-server med din e-postklient krypteras ditt lösenord i minnet och anvÀnds för att lÀsa och skriva till din brevlÄda. Din brevlÄda kan endast lÀsas frÄn och skrivas till med detta lösenord. TÀnk pÄ att eftersom du Àr den enda med detta lösenord, kan endast du lÀsa och skriva till din brevlÄda nÀr du anvÀnder den. NÀsta gÄng din e-postklient försöker hÀmta e-post eller synkroniserar, kommer dina nya meddelanden att överföras frÄn denna temporÀra brevlÄda och lagras i din faktiska brevlÄdefil med hjÀlp av ditt angivna lösenord. Observera att denna temporÀra brevlÄda rensas och tas bort efterÄt sÄ att endast din lösenordsskyddade brevlÄda har meddelandena.
-
Om du Ă€r ansluten till IMAP (t.ex. med en e-postklient som Apple Mail eller Thunderbird) behöver vi inte skriva till temporĂ€r disklagring. Ditt krypterade IMAP-lösenord i minnet hĂ€mtas och anvĂ€nds istĂ€llet. I realtid, nĂ€r ett meddelande försöker levereras till dig, skickar vi en WebSocket-förfrĂ„gan till alla IMAP-servrar och frĂ„gar om de har en aktiv session för dig (detta Ă€r hĂ€mtningen), och vidarebefordrar sedan det krypterade lösenordet i minnet â sĂ„ vi behöver inte skriva till en temporĂ€r brevlĂ„da, vi kan skriva till din faktiska krypterade brevlĂ„da med ditt krypterade lösenord.
-
-
SÀkerhetskopior av dina krypterade brevlÄdor görs dagligen. Du kan ocksÄ nÀr som helst begÀra en ny sÀkerhetskopia eller ladda ner den senaste sÀkerhetskopian frÄn Mitt konto DomÀner Aliaser. Om du bestÀmmer dig för att byta till en annan e-posttjÀnst kan du enkelt migrera, ladda ner, exportera och rensa dina brevlÄdor och sÀkerhetskopior nÀr som helst.
Teknologier
Databaser
Vi undersökte andra möjliga databasskikt, men ingen uppfyllde vÄra krav lika bra som SQLite gjorde:
| Database | Encryption-at-rest | Sandboxed Mailboxes | License | Used Everywhere |
|---|---|---|---|---|
| SQLite â | â Ja med SQLite3MultipleCiphers | â | â Public Domain | â |
| MongoDB | â "Endast tillgĂ€ngligt i MongoDB Enterprise" | â Relationsdatabas | â AGPL och SSPL-1.0 |
â |
| rqlite | â Endast nĂ€tverk | â Relationsdatabas | â
MIT |
â |
| dqlite | â Otestad och Ă€nnu inte stödd? | â Otestad och Ă€nnu inte stödd? | â
LGPL-3.0-only |
â |
| PostgreSQL | â Ja | â Relationsdatabas | â
PostgreSQL (liknande BSD eller MIT) |
â |
| MariaDB | â Endast för InnoDB | â Relationsdatabas | â
GPLv2 och BUSL-1.1 |
â |
| CockroachDB | â Endast Enterprise-funktion | â Relationsdatabas | â BUSL-1.1 och andra |
â |
HÀr Àr ett blogginlÀgg som jÀmför flera SQLite-databaslagringsalternativ i tabellen ovan.
Security
Vi anvĂ€nder alltid encryption-at-rest (AES-256), encryption-in-transit (TLS), DNS over HTTPS ("DoH") med đ Tangerine, och sqleet (ChaCha20-Poly1305) kryptering pĂ„ brevlĂ„dor. Dessutom anvĂ€nder vi token-baserad tvĂ„faktorsautentisering (till skillnad frĂ„n SMS som Ă€r sĂ„rbart för man-in-the-middle-attacker), roterade SSH-nycklar med rootĂ„tkomst avstĂ€ngd, exklusiv Ă„tkomst till servrar via begrĂ€nsade IP-adresser, och mer. Vid en evil maid-attack eller illasinnad anstĂ€lld frĂ„n en tredjepartsleverantör kan din brevlĂ„da fortfarande endast öppnas med ditt genererade lösenord. Var sĂ€ker pĂ„ att vi inte förlitar oss pĂ„ nĂ„gra tredjepartsleverantörer förutom vĂ„ra SOC Type 2-kompatibla serverleverantörer Cloudflare, DataPacket, Digital Ocean, GitHub och Vultr.
VÄrt mÄl Àr att ha sÄ fÄ single point of failures som möjligt.
BrevlÄdor
tldr; VÄra IMAP-servrar anvÀnder individuellt krypterade SQLite-databaser för var och en av dina brevlÄdor.
SQLite Ă€r en extremt populĂ€r inbĂ€ddad databas â den körs för nĂ€rvarande pĂ„ din telefon och dator â och anvĂ€nds av nĂ€stan alla stora teknologier.
Till exempel finns det pĂ„ vĂ„ra krypterade servrar en SQLite-databasbrevlĂ„da för linux@example.com, info@example.com, hello@example.com och sĂ„ vidare â en för varje som en .sqlite databasfil. Vi namnger inte heller databasfilerna med e-postadressen â istĂ€llet anvĂ€nder vi BSON ObjectID och unika UUID:er som genereras och som inte avslöjar vem brevlĂ„dan tillhör eller vilken e-postadress den Ă€r kopplad till (t.ex. 353a03f21e534321f5d6e267.sqlite).
Var och en av dessa databaser Àr sjÀlva krypterade med ditt lösenord (som bara du har) med hjÀlp av sqleet (ChaCha20-Poly1305). Detta innebÀr att dina brevlÄdor Àr individuellt krypterade, sjÀlvstÀndiga, sandboxade och portabla.
Vi har finjusterat SQLite med följande PRAGMA:
PRAGMA |
Syfte |
|---|---|
cipher=chacha20 |
ChaCha20-Poly1305 SQLite databas-kryptering. Se better-sqlite3-multiple-ciphers under Projects för mer insikt. |
key="****************" |
Detta Àr ditt dekrypterade lösenord som endast finns i minnet och som skickas via din e-postklients IMAP-anslutning till vÄr server. Nya databasinstanser skapas och stÀngs för varje lÀs- och skrivsession (för att sÀkerstÀlla sandboxing och isolering). |
journal_mode=WAL |
Write-ahead-log ("WAL") som förbÀttrar prestanda och tillÄter samtidig lÀsning. |
busy_timeout=5000 |
Förhindrar skrivlÄs-fel medan andra skrivningar pÄgÄr. |
synchronous=NORMAL |
Ăkar hĂ„llbarheten för transaktioner utan risk för datakorruption. |
foreign_keys=ON |
SÀkerstÀller att referenser till frÀmmande nycklar (t.ex. en relation frÄn en tabell till en annan) upprÀtthÄlls. Som standard Àr detta inte aktiverat i SQLite, men för validering och dataintegritet bör det vara pÄslaget. |
encoding='UTF-8' |
Standardkodning som anvÀnds för att sÀkerstÀlla utvecklarens sinnesro. |
Alla andra standardinstÀllningar kommer frÄn SQLite enligt officiell PRAGMA-dokumentation.
Samtidighet
tldr; Vi anvÀnder
WebSocketför samtidiga lÀsningar och skrivningar till dina krypterade SQLite-postlÄdor.
LĂ€sningar
Din e-postklient pĂ„ din telefon kan lösa imap.forwardemail.net till en av vĂ„ra Digital Ocean IP-adresser â och din skrivbordsklient kan lösa en separat IP frĂ„n en annan leverantör helt och hĂ„llet.
Oavsett vilken IMAP-server din e-postklient ansluter till vill vi att anslutningen ska lÀsa frÄn din databas i realtid med 100 % noggrannhet. Detta görs via WebSockets.
Skrivningar
Att skriva till din databas Ă€r lite annorlunda â eftersom SQLite Ă€r en inbĂ€ddad databas och din postlĂ„da som standard finns i en enda fil.
Vi hade utforskat alternativ som litestream, rqlite och dqlite nedan â men inget av dessa uppfyllde vĂ„ra krav.
För att utföra skrivningar med write-ahead-logging ("WAL") aktiverat â mĂ„ste vi sĂ€kerstĂ€lla att endast en server ("PrimĂ€r") Ă€r ansvarig för detta. WAL pĂ„skyndar samtidighet avsevĂ€rt och tillĂ„ter en skrivare och flera lĂ€sare.
Den PrimÀra körs pÄ dataservrarna med monterade volymer som innehÄller de krypterade postlÄdorna. Ur ett distributionsperspektiv kan du betrakta alla individuella IMAP-servrar bakom imap.forwardemail.net som sekundÀra servrar ("SekundÀr").
Vi uppnÄr tvÄvÀgskommunikation med WebSockets:
- PrimÀra servrar anvÀnder en instans av ws's
WebSocketServerserver. - SekundÀra servrar anvÀnder en instans av ws's
WebSocketklient som Àr inlindad med websocket-as-promised och reconnecting-websocket. Dessa tvÄ wrappers sÀkerstÀller attWebSocketÄteransluter och kan skicka och ta emot data för specifika databas-skrivningar.
SĂ€kerhetskopior
tldr; SÀkerhetskopior av dina krypterade postlÄdor görs dagligen. Du kan ocksÄ omedelbart begÀra en ny sÀkerhetskopia eller ladda ner den senaste sÀkerhetskopian nÀr som helst frÄn Mitt konto DomÀner Aliaser.
För sÀkerhetskopior kör vi helt enkelt SQLite-kommandot VACUUM INTO varje dag under IMAP-kommandobehandling, vilket utnyttjar ditt krypterade lösenord frÄn en IMAP-anslutning i minnet. SÀkerhetskopior sparas om ingen befintlig sÀkerhetskopia upptÀcks eller om SHA-256 hashen har Àndrats pÄ filen jÀmfört med den senaste sÀkerhetskopian.
Observera att vi anvÀnder kommandot VACUUM INTO istÀllet för det inbyggda backup-kommandot eftersom om en sida Àndras under en backup-kommandooperation mÄste den börja om. Kommandot VACUUM INTO tar en ögonblicksbild. Se dessa kommentarer pÄ GitHub och Hacker News för mer insikt.
Dessutom anvÀnder vi VACUUM INTO istÀllet för backup, eftersom backup-kommandot skulle lÀmna databasen okrypterad under en kort period tills rekey anropas (se denna GitHub kommentar för insikt).
Den SekundĂ€ra kommer att instruera den PrimĂ€ra över WebSocket-anslutningen att utföra sĂ€kerhetskopian â och den PrimĂ€ra kommer sedan att ta emot kommandot att göra detta och dĂ€refter:
- Ansluta till din krypterade postlÄda.
- Skaffa en skrivlÄs.
- Köra en WAL-checkpoint via
wal_checkpoint(PASSIVE). - Köra SQLite-kommandot
VACUUM INTO. - SÀkerstÀlla att den kopierade filen kan öppnas med det krypterade lösenordet (sÀkerhetsÄtgÀrd/felsÀkerhet).
- Ladda upp den till Cloudflare R2 för lagring (eller din egen leverantör om specificerad).
Kom ihĂ„g att dina brevlĂ„dor Ă€r krypterade â och Ă€ven om vi har IP-begrĂ€nsningar och andra autentiseringsĂ„tgĂ€rder pĂ„ plats för WebSocket-kommunikation â kan du vara sĂ€ker pĂ„ att om en illasinnad aktör skulle agera, sĂ„ kan den inte öppna din databas om inte WebSocket-payloaden innehĂ„ller ditt IMAP-lösenord.
Endast en sÀkerhetskopia lagras per brevlÄda för tillfÀllet, men i framtiden kan vi erbjuda punkt-i-tid-ÄterstÀllning ("PITR").
Sök
VÄra IMAP-servrar stödjer SEARCH-kommandot med komplexa sökfrÄgor, reguljÀra uttryck och mer.
Snabb sökprestanda tack vare FTS5 och sqlite-regex.
Vi lagrar Date-vÀrden i SQLite-brevlÄdorna som ISO 8601-strÀngar via Date.prototype.toISOString (med UTC-tidszon för att likhetsjÀmförelser ska fungera korrekt).
Index lagras ocksÄ för alla egenskaper som ingÄr i sökfrÄgor.
Projekt
HÀr Àr en tabell som beskriver projekt vi anvÀnder i vÄr kÀllkod och utvecklingsprocess (sorterade alfabetiskt):
| Projekt | Syfte |
|---|---|
| Ansible | DevOps-automationsplattform för att underhÄlla, skala och hantera hela vÄr serverflotta med lÀtthet. |
| Bree | JobbschemalÀggare för Node.js och JavaScript med stöd för cron, datum, ms, later och anvÀndarvÀnligt stöd. |
| Cabin | UtvecklarvÀnligt JavaScript- och Node.js-loggningsbibliotek med sÀkerhet och integritet i Ätanke. |
| Lad | Node.js-ramverk som driver hela vÄr arkitektur och ingenjörsdesign med MVC och mer. |
| MongoDB | NoSQL-databaslösning som vi anvÀnder för att lagra all annan data utanför brevlÄdor (t.ex. ditt konto, instÀllningar, domÀner och alias-konfigurationer). |
| Mongoose | MongoDB-objektdokumentmodellering ("ODM") som vi anvĂ€nder i hela vĂ„r stack. Vi skrev speciella hjĂ€lpare som gör att vi enkelt kan fortsĂ€tta anvĂ€nda Mongoose med SQLite đ |
| Node.js | Node.js Àr den öppen kÀllkods-, plattformsoberoende JavaScript-körtidsmiljön som kör alla vÄra serverprocesser. |
| Nodemailer | Node.js-paket för att skicka e-post, skapa anslutningar och mer. Vi Àr en officiell sponsor av detta projekt. |
| Redis | Minnesdatabas för caching, publicera/prenumerera-kanaler och DNS över HTTPS-förfrÄgningar. |
| SQLite3MultipleCiphers | KrypteringstillĂ€gg för SQLite som tillĂ„ter hela databaser att krypteras (inklusive write-ahead-log ("WAL"), journal, rollback, âŠ). |
| SQLiteStudio | Visuell SQLite-editor (som du ocksÄ kan anvÀnda) för att testa, ladda ner och visa utvecklingsbrevlÄdor. |
| SQLite | InbÀddat databasskikt för skalbar, sjÀlvstÀndig, snabb och robust IMAP-lagring. |
| Spam Scanner | Node.js-verktyg för anti-spam, e-postfiltrering och phishing-förebyggande (vÄrt alternativ till Spam Assassin och rspamd). |
| Tangerine | DNS över HTTPS-förfrĂ„gningar med Node.js och caching med Redis â vilket sĂ€kerstĂ€ller global konsistens och mycket mer. |
| Thunderbird | VÄrt utvecklingsteam anvÀnder detta (och rekommenderar det ocksÄ) som den föredragna e-postklienten att anvÀnda med Forward Email. |
| UTM | VÄrt utvecklingsteam anvÀnder detta för att skapa virtuella maskiner för iOS och macOS för att testa olika e-postklienter (parallellt) med vÄra IMAP- och SMTP-servrar. |
| Ubuntu | Modernt öppen kÀllkods Linux-baserat serveroperativsystem som driver hela vÄr infrastruktur. |
| WildDuck | IMAP-serverbibliotek â se dess anteckningar om bifogade filer de-duplicering och IMAP-protokollstöd. |
| better-sqlite3-multiple-ciphers | Snabbt och enkelt API-bibliotek för Node.js för att programmÀssigt interagera med SQLite3. |
| email-templates | UtvecklarvÀnligt e-postramverk för att skapa, förhandsgranska och skicka anpassade e-postmeddelanden (t.ex. kontonotifikationer och mer). |
| json-sql-enhanced | SQL-frÄgebyggare med Mongo-stil syntax. Detta sparar vÄrt utvecklingsteam tid eftersom vi kan fortsÀtta skriva i Mongo-stil över hela stacken med en databasagnostisk metod. Det hjÀlper ocksÄ till att undvika SQL-injektionsattacker genom att anvÀnda frÄgeparametrar. |
| knex-schema-inspector | SQL-verktyg för att extrahera information om befintligt databasschema. Detta gör att vi enkelt kan validera att alla index, tabeller, kolumner, begrÀnsningar och mer Àr giltiga och Àr 1:1 med hur de ska vara. Vi skrev till och med automatiserade hjÀlpare för att lÀgga till nya kolumner och index om Àndringar görs i databasscheman (med mycket detaljerade felmeddelanden ocksÄ). |
| knex | SQL-frÄgebyggare som vi endast anvÀnder för databas-migrationer och schema-validering via knex-schema-inspector. |
| mandarin | Automatisk i18n-frasöversÀttning med stöd för Markdown med hjÀlp av Google Cloud Translation API. |
| mx-connect | Node.js-paket för att lösa och etablera anslutningar med MX-servrar och hantera fel. |
| pm2 | Node.js produktionsprocesshanterare med inbyggd lastbalanserare (finjusterad för prestanda). |
| smtp-server | SMTP-serverbibliotek â vi anvĂ€nder detta för vĂ„ra mail exchange ("MX") och utgĂ„ende SMTP-servrar. |
| ImapTest | AnvÀndbart verktyg för att testa IMAP-servrar mot benchmarks och RFC-specifikationens IMAP-protokollkompatibilitet. Detta projekt skapades av Dovecot-teamet (en aktiv öppen kÀllkods IMAP- och POP3-server frÄn juli 2002). Vi testade vÄr IMAP-server omfattande med detta verktyg. |
Du kan hitta andra projekt vi anvÀnder i vÄr kÀllkod pÄ GitHub.
Leverantörer
| Leverantör | Syfte |
|---|---|
| Cloudflare | DNS-leverantör, hÀlsokontroller, lastbalanserare och backup-lagring med hjÀlp av Cloudflare R2. |
| GitHub | VÀrd för kÀllkod, CI/CD och projektledning. |
| Digital Ocean | Dedikerad serverhosting och hanterade databaser. |
| Vultr | Dedikerad serverhosting. |
| DataPacket | Dedikerad serverhosting. |
Tankar
Principer
Forward Email Àr designat enligt dessa principer:
- Vara alltid utvecklarvÀnligt, sÀkerhets- och integritetsfokuserat samt transparent.
- Följa MVC, Unix, KISS, DRY, YAGNI, Twelve Factor, Occam's razor och dogfooding
- Rikta sig till den driftiga, egenfinansierade och ramen-lönsamma utvecklaren
Experiment
tldr; I slutÀndan Àr det inte tekniskt genomförbart att anvÀnda S3-kompatibel objektlagring och/eller Virtual Tables pÄ grund av prestandaskÀl och Àr benÀget för fel pÄ grund av minnesbegrÀnsningar.
Vi har gjort nÄgra experiment som ledde fram till vÄr slutgiltiga SQLite-lösning som diskuterats ovan.
Ett av dessa var att försöka anvÀnda rclone och SQLite tillsammans med ett S3-kompatibelt lagringslager.
Det experimentet ledde till att vi bÀttre förstod och upptÀckte kantfall kring rclone, SQLite och anvÀndning av VFS:
- Om du aktiverar flaggan
--vfs-cache-mode writesmed rclone, sÄ fungerar lÀsningar bra, men skrivningar kommer att cachas.- Om du har flera IMAP-servrar distribuerade globalt, kommer cachen att vara inkonsekvent mellan dem om du inte har en enda skrivare och flera lyssnare (t.ex. en pub/sub-lösning).
- Detta Àr otroligt komplext och att lÀgga till ytterligare komplexitet som detta kommer att resultera i fler enskilda felpunkter.
- S3-kompatibla lagringsleverantörer stödjer inte partiella filĂ€ndringar â vilket innebĂ€r att varje Ă€ndring av
.sqlite-filen resulterar i en komplett Àndring och uppladdning av databasen. - Andra lösningar som
rsyncfinns, men de Ă€r inte fokuserade pĂ„ write-ahead-log ("WAL")-stöd â sĂ„ vi slutade med att granska Litestream. Lyckligtvis krypterar vĂ„r anvĂ€ndning redan WAL-filerna Ă„t oss, sĂ„ vi behöver inte förlita oss pĂ„ Litestream för det. Dock var vi Ă€nnu inte sĂ€kra pĂ„ Litestream för produktionsanvĂ€ndning och har nĂ„gra anteckningar nedan om det. - Att anvĂ€nda detta alternativ
--vfs-cache-mode writes(det enda sĂ€ttet att anvĂ€nda SQLite överrcloneför skrivningar) kommer att försöka kopiera hela databasen frĂ„n början i minnet â att hantera en 10 GB stor brevlĂ„da Ă€r okej, men att hantera flera brevlĂ„dor med extremt hög lagring kommer att orsaka att IMAP-servrarna stöter pĂ„ minnesbegrĂ€nsningar ochENOMEM-fel, segmenteringsfel och datakorruption.
- Om du försöker anvÀnda SQLite Virtual Tables (t.ex. med s3db) för att ha data lagrade pÄ ett S3-kompatibelt lagringslager, kommer du att stöta pÄ flera fler problem:
- LÀsningar och skrivningar blir extremt lÄngsamma eftersom S3 API-endpoints mÄste nÄs med HTTP-metoderna
GET,PUT,HEADochPOST. - Utvecklingstester visade att över 500K-1M+ poster pÄ fiberinternet fortfarande begrÀnsas av genomströmningen vid skrivning och lÀsning till S3-kompatibla leverantörer. Till exempel körde vÄra utvecklare
for-loopar för bÄde sekventiella SQLINSERT-satser och sÄdana som bulk-skriver stora mÀngder data. I bÄda fallen var prestandan hÀpnadsvÀckande lÄngsam. - Virtuella tabeller kan inte ha index,
ALTER TABLE-satser och andra begrĂ€nsningar â vilket leder till fördröjningar pĂ„ upp till 1-2 minuter eller mer beroende pĂ„ datamĂ€ngd. - Objekt lagrades okrypterade och inget inbyggt krypteringsstöd finns tillgĂ€ngligt.
- LÀsningar och skrivningar blir extremt lÄngsamma eftersom S3 API-endpoints mÄste nÄs med HTTP-metoderna
- Vi undersökte ocksÄ att anvÀnda sqlite-s3vfs som Àr konceptuellt och tekniskt liknande föregÄende punkt (sÄ det har samma problem). En möjlighet skulle vara att anvÀnda en anpassad
sqlite3-build inlindad med kryptering som wxSQLite3 (som vi för nÀrvarande anvÀnder i vÄr lösning ovan) genom att redigera setup-filen. - En annan potentiell metod var att anvÀnda multiplex-tillÀgget, men detta har en begrÀnsning pÄ 32 GB och skulle krÀva komplex byggnation och utvecklingsproblem.
ALTER TABLE-satser krĂ€vs (sĂ„ detta utesluter helt anvĂ€ndning av Virtual Tables). Vi behöverALTER TABLE-satser för att vĂ„r hook medknex-schema-inspectorska fungera korrekt â vilket sĂ€kerstĂ€ller att data inte korruptas och att hĂ€mtade rader kan konverteras till giltiga dokument enligt vĂ„ramongoose-schemadefinitioner (vilket inkluderar begrĂ€nsningar, variabeltyp och godtycklig datavalidering).- NĂ€stan alla S3-kompatibla projekt relaterade till SQLite i open-source-communityn Ă€r i Python (och inte JavaScript som vi anvĂ€nder för 100% av vĂ„r stack).
- Komprimeringsbibliotek som sqlite-zstd (se kommentarer) ser lovande ut, men Àr kanske inte redo för produktionsanvÀndning Àn. IstÀllet kommer applikationssideskomprimering pÄ datatyper som
String,Object,Map,Array,SetochBufferatt vara en renare och enklare metod (och Ă€r ocksĂ„ lĂ€ttare att migrera eftersom vi kan lagra enBoolean-flagga eller kolumn â eller till och med anvĂ€ndaPRAGMAuser_version=1för komprimering elleruser_version=0för ingen komprimering som databasmetadata).- Lyckligtvis har vi redan implementerat bilagede-duplicering i vĂ„r IMAP-serverlagring â dĂ€rför kommer varje meddelande med samma bilaga inte att behĂ„lla en kopia av bilagan â istĂ€llet lagras en enda bilaga för flera meddelanden och trĂ„dar i en brevlĂ„da (och en frĂ€mmande referens anvĂ€nds dĂ€refter).
- Projektet Litestream, som Àr en SQLite-replikations- och backup-lösning, Àr mycket lovande och vi kommer troligen att anvÀnda det i framtiden.
- Inte för att förminska författaren/författarna â eftersom vi Ă€lskar deras arbete och bidrag till open-source i över ett decennium nu â men frĂ„n verklig anvĂ€ndning verkar det som att det kan finnas mĂ„nga problem och potentiell dataförlust vid anvĂ€ndning.
- Backup-ÄterstÀllning mÄste vara friktionsfri och trivial. Att anvÀnda en lösning som MongoDB med
mongodumpochmongoexportÀr inte bara tidskrÀvande utan ocksÄ konfigurationskomplicerat.- SQLite-databaser gör det enkelt (det Àr en enda fil).
- Vi ville designa en lösning dÀr anvÀndare kan ta sin brevlÄda och lÀmna nÀr som helst.
- Enkla Node.js-kommandon som
fs.unlink('mailbox.sqlite'))och den Àr permanent raderad frÄn disklagring. - Vi kan pÄ liknande sÀtt anvÀnda ett S3-kompatibelt API med HTTP
DELETEför att enkelt ta bort snapshots och backuper för anvÀndare.
- Enkla Node.js-kommandon som
- SQLite var den enklaste, snabbaste och mest kostnadseffektiva lösningen.
Brist pÄ alternativ
SÄvitt vi vet Àr inga andra e-posttjÀnster designade pÄ detta sÀtt och de Àr inte heller open-source.
Vi tror att detta kan bero pĂ„ att befintliga e-posttjĂ€nster har gammal teknik i produktion med spaghettikod đ.
De flesta, om inte alla, befintliga e-postleverantörer Àr antingen closed-source eller marknadsför sig som open-source, men i verkligheten Àr det bara deras front-end som Àr open-source.
Den mest kÀnsliga delen av e-post (den faktiska lagringen/IMAP/SMTP-interaktionen) hanteras helt pÄ back-end (servern), och inte pÄ front-end (klienten).
Prova Forward Email
Registrera dig idag pĂ„ https://forwardemail.net! đ