Djupdykning: Hur vi använder kvantsäkra krypterade SQLite-postlådor för vår integritetsfokuserade och säkra e-posttjänst

Till skillnad från andra e-posttjänster ser vi till att endast du har tillgång till din brevlåda hela tiden.

Förord

tldr; 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 ihållande datalagringsbehov.

Den här tekniken är fantastisk och vi använder den fortfarande idag – men för att ha encryption-at-rest med MongoDB måste du använda en leverantör som erbjuder MongoDB Enterprise, som Digital Ocean eller Mongo Atlas – eller betala för en företagslicens (och måste därefter arbeta med säljteamets latens).

Vårt team kl Vidarebefordra e-post behövde en utvecklarvänlig, skalbar, pålitlig och krypterad lagringslösning för IMAP-postlådor. Som utvecklare med öppen källkod måste du genom att använda en teknik betala en licensavgift för att få funktionen kryptering i vila var emot våra principer – och så vi experimenterade, undersökte 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 brevlådor lagrar vi individuellt och krypterar dina brevlådor 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 så tappar du din brevlåda (och behöver återställa med offline-säkerhetskopior eller börja om).

Fortsätt läsa när vi tar en djupdykning nedan med en jämförelse av e-postleverantörer, hur vår tjänst fungerar, vår teknikstack, och mer.

Jämförelse av e-postleverantörer

Vi är den enda leverantören av 100 % öppen källkod och integritetsfokuserad e-posttjänst som lagrar individuellt krypterade SQLite-postlådor, erbjuder obegränsade domäner, alias och användare och 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. Lagring delas över hela ditt konto – så om du har flera anpassade domännamn och flera alias på varje, så är vi den perfekta lösningen för dig. Observera att du fortfarande kan upprätthålla lagringsgränser om så önskas per domän eller alias.

Läs Jämförelse av e-posttjänster

Hur fungerar det

  1. Genom att använda din e-postklient som Apple Mail, Thunderbird, Gmail eller Outlook – ansluter du till vårt säkra IMAP servrar som använder ditt användarnamn och lösenord:

    • Ditt användarnamn är ditt fullständiga alias med din domän som t.ex hello@example.com.
    • Ditt lösenord genereras slumpmässigt och visas bara för dig i 30 sekunder när du klickar Generera lösenord från Mitt konto domäner Alias.
  2. 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-postmeddelanden 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/skräppost).

  3. E-postutbytesservrar (allmänt kända som "MX"-servrar) tar emot ny inkommande e-post och lagrar den i din brevlåda. När detta händer kommer din e-postklient att få ett meddelande och synkronisera 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!

    Intresserad av att lära dig mer? Läsa hur man ställer in vidarebefordran av e-post, hur vår postväxlingstjänst fungerar, eller visa våra guider.

  4. 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-postväxlingsservrar till en individuell, tillfällig och krypterad postlåda åt dig.

      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!
      
    • När du ansluter till vår IMAP-server med din e-postklient krypteras ditt lösenord sedan 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, bara du kan läsa och skriva till din brevlåda när du kommer åt den. Nästa gång din e-postklient försöker polla efter e-post eller synkronisera, kommer dina nya meddelanden att överföras från denna tillfälliga brevlåda och lagras i din faktiska brevlådefil med ditt angivna lösenord. Observera att denna tillfälliga brevlåda rensas och raderas efteråt så att endast din lösenordsskyddade brevlåda har meddelandena.

    • Om du är ansluten till IMAP (t.ex. genom att använda 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 dem om de har en aktiv session för dig (detta är hämtningsdelen), och skickar sedan vidare den krypterat lösenord i minnet – så vi behöver inte skriva till en tillfällig brevlåda, vi kan skriva till din faktiska krypterade brevlåda med ditt krypterade lösenord.

      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!
      
  5. Säkerhetskopiering av dina krypterade postlådor görs dagligen. Du kan också begära en ny säkerhetskopia när som helst eller ladda ner den senaste säkerhetskopian från Mitt konto domäner Alias. 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 databaslagringslager, men ingen uppfyllde våra krav så mycket som SQLite gjorde:

DatabasKryptering i vilaSandlåda BrevlådorLicensAnvänds överallt
SQLite✅ Ja med SQLite3 MultipleCiphers✅ Allmän egendom
MongoDB"Endast tillgängligt i MongoDB Enterprise"❌ Relationsdatabas❌ AGPL och SSPL-1.0
rqliteEndast nätverk❌ RelationsdatabasMIT
dqliteOtestad och ännu inte stödd?Otestad och ännu inte stödd?LGPL-3.0-only
PostgreSQLJa❌ RelationsdatabasPostgreSQL (Liknande BSD eller MIT)
MariaDBEndast för InnoDB❌ RelationsdatabasGPLv2 och BUSL-1.1
KackerlackaDBEnbart företagsfunktion❌ RelationsdatabasBUSL-1.1 och andra

Här är en blogginlägg som jämför flera SQLite-databaslagringsalternativ i tabellen ovan.

säkerhet

Alltid vi använder kryptering i vila (AES-256), kryptering under transport (TLS), DNS över HTTPS ("DoH") med 🍊 Mandarin, och sqleet (ChaCha20-Poly1305) kryptering på brevlådor. Dessutom använder vi token-baserad tvåfaktorsautentisering (till skillnad från SMS som är misstänkt för man-i-mitten-attacker), roterade SSH-nycklar med rotåtkomst inaktiverad, exklusiv åtkomst till servrar via begränsade IP-adresser och mer.

I händelse av en ond piga attack eller oseriös anställd från en tredjepartsleverantör, din brevlåda kan fortfarande bara öppnas med ditt skapade lösenord. Du kan vara säker på att vi inte litar på några tredjepartsleverantörer förutom våra SOC Type 2-klagomålsserverleverantörer av Cloudflare, Digital Ocean och Vultr.

Vårt mål är att ha så få enda punkt av misslyckanden 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 större tekniker.

Till exempel, på våra krypterade servrar finns det en SQLite-databaspostlå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:s som genereras som inte delar vem brevlådan tillhör eller vilken e-postadress den ligger under (t.ex. 353a03f21e534321f5d6e267.sqlite).

Var och en av dessa databaser krypteras själva med ditt lösenord (som bara du har) med sqleet (ChaCha20-Poly1305). Detta innebär att dina brevlådor är individuellt krypterade, fristående, sandlåda, och bärbar.

Vi har finjusterat SQLite med följande PRAGMA:

PRAGMASyfte
cipher=chacha20ChaCha20-Poly1305 SQLite databaskryptering. Referens better-sqlite3-multiple-ciphers under Projekt för mer insikt.
key="****************"Detta är ditt dekrypterade lösenord endast i minnet 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 sandboxning och isolering).
journal_model=WALWrite-ahead-log ("WAL") som ökar prestandan och tillåter samtidig läsåtkomst.
busy_timeout=5000Förhindrar skrivlåsfel medan andra skrivningar äger rum.
synchronous=NORMALÖkar varaktigheten av transaktioner utan risk för datakorruption.
foreign_keys=ONFramtvingar att främmande nyckelreferenser (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 aktiverat.
encoding='UTF-8'Standardkodning att använda för att säkerställa utvecklarens förnuft.

Alla andra standardinställningar är från SQLite som specificerats från officiella PRAGMA-dokumentation.

Samtidighet

tldr; Vi använder rclone och WebSocket för samtidiga läsningar och skrivningar till dina krypterade SQLite-postlådor.

Läser

Din e-postklient på din telefon kan lösa sig imap.forwardemail.net till en av våra Digital Ocean IP-adresser – och din stationära klient kan lösa en separat IP från en annan leverantör sammanlagt.

Oavsett vilken IMAP-server din e-postklient ansluter till vill vi att anslutningen ska läsas från din databas i realtid med 100 % noggrannhet:

  • Detta uppnås genom att använda rclone med --vfs-cache-mode off (standarden).

  • Istället för att använda lokal diskcache läses cachen direkt från fjärrmonteringen (din databas) i realtid.

  • I händelse av att den lokala filen inte kan hittas indikerar detta det rclone kunde inte monteras eller har ett problem. I det här fallet använder vi en WebSocket reserv för läsningar (vilket minskar prestandan något, men ändå bibehåller tjänstens integritet).

  • Var och en av våra servrar är konfigurerade för att montera med konsekvens och varnar oss i realtid om eventuella fel.

Skriver

Att skriva till din databas är lite annorlunda – eftersom SQLite är en inbäddad databas och din brevlåda som standard finns i en enda fil.

Vi hade utforskat alternativ som t.ex litestream, rqlite, och dqlite nedan – men ingen av dessa uppfyllde våra krav.

För att utföra skrivningar med write-ahead-logging ("WAL") aktiverat – vi måste se till att endast en server ("Primär") är ansvarig för att göra det. WAL påskyndar drastiskt samtidighet och tillåter en skribent och flera läsare.

Primären körs på dataservrarna med de monterade volymerna som innehåller de krypterade postlådorna. Ur distributionssynpunkt kan du överväga alla individuella IMAP-servrar bakom imap.forwardemail.net vara sekundära servrar ("Sekundär").

Vi åstadkommer tvåvägskommunikation med WebSockets:

  • Primära servrar använder en instans av wss WebSocketServer server.
  • Sekundära servrar använder en instans av wss WebSocket klient som är lindad med websocket-som-promised och återansluta-websocket. Dessa två omslag säkerställer att WebSocket återansluter och kan skicka och ta emot data för specifika databasskrivningar.

Säkerhetskopieringar

tldr; Säkerhetskopieringar av dina krypterade brevlå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 Alias.

För säkerhetskopiering kör vi helt enkelt SQLite VACUUM INTO kommando varje dag under IMAP-kommandobehandling, som utnyttjar ditt krypterade lösenord från en IMAP-anslutning i minnet. Säkerhetskopieringar lagras om ingen befintlig säkerhetskopia upptäcks eller om SHA-256 hash har ändrats på filen jämfört med den senaste säkerhetskopian.

Observera att vi använder VACUUM INTO kommandot i motsats till det inbyggda backup kommandot eftersom om en sida ändras under en backup kommandooperation, sedan måste den börja om. De VACUUM INTO kommandot tar en ögonblicksbild. Se dessa kommentarer på GitHub och Hacker Nyheter för mer insikt.

Dessutom använder vi VACUUM INTO i motsats till backup, eftersom den backup kommandot skulle lämna databasen okrypterad under en kort period tills rekey anropas (se denna GitHub kommentar för insikt).

Sekundären kommer att instruera Primären om WebSocket anslutning för att utföra säkerhetskopieringen – och den primära kommer sedan att få kommandot att göra det och kommer därefter:

  1. Anslut till din krypterade brevlåda.
  2. Skaffa ett skrivlås.
  3. Kör en WAL-kontrollpunkt via wal_checkpoint(PASSIVE).
  4. Springa det VACUUM INTO SQLite kommando.
  5. Se till att den kopierade filen kan öppnas med det krypterade lösenordet (safeguard/dummyproofing).
  6. Ladda upp den till Cloudflare R2 för lagring (eller din egen leverantör om det anges).
  7. Komprimera den resulterande säkerhetskopian med gzip.
  8. Ladda upp den till Cloudflare R2 för lagring (eller din egen leverantör om det anges).

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 – i händelse av en dålig aktör kan du vara säker på att om inte WebSockets nyttolast har ditt IMAP-lösenord, kan den inte öppna din databas .

Endast en säkerhetskopia lagras per brevlåda för närvarande, men i framtiden kan vi erbjuda punkt-i-tid-återställning ("PITR").

Våra IMAP-servrar stöder SEARCH kommando med komplexa frågor, reguljära uttryck och mer.

Snabb sökprestanda är tack vare FTS5 och sqlite-regex.

Vi lagrar Date värden i SQLite-postlådorna som ISO 8601 strängar via Date.prototype.toISOString (med UTC-tidszon för att jämställdhetsjämförelser ska fungera korrekt).

Index lagras också för alla egenskaper som finns i sökfrågor.

Projekt

Här är en tabell som beskriver projekt vi använder i vår källkod och utvecklingsprocess (sorterade i alfabetisk ordning):

ProjektSyfte
AnsibleDevOps automationsplattform för att underhålla, skala och hantera hela vår flotta av servrar med lätthet.
BreeJobbschemaläggare för Node.js och JavaScript med cron, datum, ms, senare och människovänlig support.
StugaUtvecklarvänligt JavaScript- och Node.js-loggningsbibliotek med säkerhet och integritet i åtanke.
LåtaNode.js ramverk som driver hela vår arkitektur och ingenjörsdesign med MVC och mer.
MongoDBNoSQL-databaslösning som vi använder för att lagra all annan data utanför postlådor (t.ex. ditt konto, inställningar, domäner och aliaskonfigurationer).
MungoMongoDB objektdokumentmodellering ("ODM") som vi använder över hela vår stack. Vi skrev specialhjälpare som gör att vi helt enkelt kan fortsätta använda Mongoose med SQLite 🎉
Node.jsNode.js är den plattformsoberoende JavaScript-runtimemiljön med öppen källkod som kör alla våra serverprocesser.
Notera mailerNode.js-paket för att skicka e-post, skapa anslutningar och mer. Vi är en officiell sponsor för detta projekt.
RedisIn-memory databas för cachelagring, publicera/prenumerera kanaler och DNS över HTTPS-förfrågningar.
SQLite3 MultipleCiphersKrypteringstillägg för SQLite för att tillåta att hela databasfiler krypteras (inklusive write-ahead-loggen ("WAL"), journal, återställning, ...).
SQLiteStudioVisual SQLite-redigerare (som du också kan använda) för att testa, ladda ner och visa utvecklingsbrevlådor.
SQLiteInbäddat databaslager för skalbar, fristående, snabb och motståndskraftig IMAP-lagring.
SkräppostläsareNode.js anti-spam, e-postfiltrering och nätfiskeförebyggande verktyg (vårt alternativ till Spammördare och rspamd).
MandarinDNS över HTTPS-förfrågningar med Node.js och cachning med Redis – vilket säkerställer global konsistens och mycket mer.
ThunderbirdVårt utvecklingsteam använder detta (och rekommenderar detta också) som den föredragna e-postklienten att använda med Vidarebefordra e-post.
UTMVå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.
UbuntuModernt Linux-baserat serveroperativsystem med öppen källkod som driver all vår infrastruktur.
Vild ankaIMAP-serverbibliotek – se dess anteckningar om deduplicering av bilagor och Stöd för IMAP-protokoll.
better-sqlite3-multiple-ciphersSnabbt och enkelt API-bibliotek för Node.js att interagera med SQLite3 programmatiskt.
e-postmallarUtvecklarvänligt e-postramverk för att skapa, förhandsgranska och skicka anpassade e-postmeddelanden (t.ex. kontoaviseringar och mer).
json-sqlSQL-frågebyggare med syntax i Mongo-stil. Detta sparar tid för vårt utvecklingsteam eftersom vi kan fortsätta att 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-inspektörSQL-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 extremt detaljerad felvarning också).
knexSQL frågebyggare som vi endast använder för databasmigreringar och schemavalidering genom knex-schema-inspector.
mandarinAutomatisk i18n frasöversättning med stöd för Markdown att använda Google Cloud Translation API.
mx-anslutNode.js-paket för att lösa och upprätta anslutningar med MX-servrar och hantera fel.
kl 2Node.js produktionsprocessledare med inbyggd lastbalanserare (finstämd för prestanda).
smtp-serverSMTP-serverbibliotek – vi använder detta för vår e-postutbyte ("MX") och utgående SMTP-servrar.
ImapTestAnvändbart verktyg för att testa IMAP-servrar mot riktmärken och RFC-specifikation IMAP-protokollkompatibilitet. Detta projekt skapades av Duvhacka team (en aktiv IMAP- och POP3-server med öppen källkod från juli 2002). Vi testade vår IMAP-server omfattande med det här verktyget.

Du kan hitta andra projekt vi använder i vår källkod på GitHub.

Leverantörer

LeverantörSyfte
CloudFlareDNS-leverantör, hälsokontroller, lastbalanserare och säkerhetskopieringslagring med hjälp av Cloudflare R2.
Digital OceanDedikerad serverhosting, SSD-blocklagring och hanterade databaser.
VultrDedikerad serverhosting och SSD-blocklagring.

Tankar

Principer

Vidarebefordra e-post är utformad enligt dessa principer:

  1. Var alltid utvecklarvänlig, säkerhets- och integritetsfokuserad och transparent.
  2. Hålla fast vid MVC, Unix, KISS, DRY, YAGNI, Tolvfaktor, Occams rakkniv, och dogfooding
  3. Inrikta dig på de skrapiga, stövlade och ramen-lönsamt utvecklare

Experiment

tldr; I slutändan är det inte tekniskt möjligt att använda S3-kompatibel objektlagring och/eller virtuella tabeller av prestandaskäl och risk för fel på grund av minnesbegränsningar.

Vi har gjort några experiment som ledde fram till vår slutliga SQLite-lösning som diskuterats ovan.

En av dessa var att prova att använda rclone och SQLite tillsammans med ett S3-kompatibelt lagringslager.

Det experimentet ledde oss att ytterligare förstå och upptäcka edge-fall kring rclone, SQLite och VFS användande:

  • Om du aktiverar --vfs-cache-mode writes flagga med rclone, då kommer läsningar att vara OK, men skrivningar kommer att cachelagras.
    • Om du har flera IMAP-servrar distribuerade globalt, kommer cacheminnet att vara avstängt över dem om du inte har en enda skribent och flera lyssnare (t.ex. en pub/sub-inställning).
    • Detta är otroligt komplicerat och att lägga till ytterligare komplexitet som denna kommer att resultera i fler enstaka felpunkter.
    • S3-kompatibla lagringsleverantörer stöder inte partiella filändringar – vilket innebär någon ändring av .sqlite filen kommer att resultera i en fullständig ändring och återuppladdning av databasen.
    • Andra lösningar som rsync existerar, men de är inte fokuserade på write-ahead-log ("WAL") support – så det slutade med att vi granskade Litestream. Lyckligtvis krypterar vår krypteringsanvändning redan WAL filer för oss, så vi behöver inte förlita oss på Litestream för det. Men vi var ännu inte säkra på Litestream för produktionsanvändning och har några anteckningar nedan om det.
    • Genom att använda det här alternativet --vfs-cache-mode writes (de endast sätt att använda SQLite över rclone för skrivningar) kommer att försöka kopiera hela databasen från början i minnet – att hantera en 10 GB-postlåda är OK, men hantering av flera brevlådor med mycket hög lagringskapacitet kommer att göra att IMAP-servrarna stöter på minnesbegränsningar och ENOMEM fel, segmenteringsfel och datakorruption.
  • Om du försöker använda SQLite Virtuella tabeller (t.ex. att använda s3db) för att ha data live på ett S3-kompatibelt lagringslager kommer du att stöta på flera fler problem:
    • Läsning och skrivning kommer att vara extremt långsam eftersom S3 API-slutpunkter kommer att behöva träffas med HTTP GET, PUT, HEAD, och POST metoder.
    • Utvecklingstester visade att överskridande av 500K-1M+ rekord på fiberinternet fortfarande begränsas av genomströmningen av skrivning och läsning till S3-kompatibla leverantörer. Våra utvecklare körde till exempel for loopar för att göra både sekventiell SQL INSERT uttalanden och sådana som bulk skrev stora mängder data. I båda fallen var prestandan förbluffande långsam.
    • Virtuella bord kan inte ha index, ALTER TABLE uttalanden och Övrig begränsningar – vilket leder till förseningar på uppåt 1-2 minuter eller mer beroende på mängden data.
    • Objekt lagrades okrypterade och inget inbyggt krypteringsstöd är lätt tillgängligt.
  • Vi utforskade också att använda sqlite-s3vfs som liknar den föregående punkten begreppsmässigt och tekniskt (så det har samma problem). En möjlighet skulle vara att använda en anpassad sqlite3 bygg insvept med kryptering som t.ex wxSQLite3 (som vi för närvarande använder i vår lösning ovan) genom redigera installationsfilen.
  • Ett annat potentiellt tillvägagångssätt var att använda multiplex förlängning, men detta har en begränsning på 32 GB och skulle kräva komplex byggnads- och utvecklingshuvudvärk.
  • ALTER TABLE uttalanden krävs (så detta utesluter helt att du använder virtuella tabeller). Vi behöver ALTER TABLE uttalanden för att vår krok med knex-schema-inspector att fungera korrekt – vilket säkerställer att data inte skadas och rader som hämtas kan konverteras till giltiga dokument enligt vår mongoose schemadefinitioner (som inkluderar begränsning, variabeltyp och godtycklig datavalidering).
  • Nästan alla S3-kompatibla projekt relaterade till SQLite i open source-communityt är i Python (och inte JavaScript som vi använder för 100 % av vår stack).
  • Kompressionsbibliotek som t.ex sqlite-zstd (ser kommentarer) ser lovande ut, men kanske ännu inte är redo för produktionsanvändning. Istället applikationssidans komprimering på datatyper som t.ex String, Object, Map, Array, Set, och Buffer kommer att bli ett renare och enklare tillvägagångssätt (och är också lättare att migrera, eftersom vi skulle kunna lagra en Boolean flagga eller kolumn – eller till och med använda PRAGMA user_version=1 för kompression eller user_version=0 för ingen komprimering som databasmetadata).
    • Lyckligtvis har vi redan de-duplicering av bilagor implementerad 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 utländsk referens används senare).
  • Projektet Litestream, som är en SQLite-replikerings- och backuplösning är mycket lovande och vi kommer med största sannolikhet att använda det i framtiden.
  • Säkerhetskopiering måste vara friktionsfri och trivial. Att använda en lösning som MongoDB med mongodump och mongoexport är inte bara tråkig, utan tidsintensiv och har konfigurationskomplexitet.
    • SQLite-databaser gör det enkelt (det är en enda fil).
    • Vi ville designa en lösning där användare kunde ta sin brevlåda och lämna när som helst.
      • Enkla Node.js-kommandon till fs.unlink('mailbox.sqlite')) och den raderas permanent från disklagring.
      • Vi kan på liknande sätt använda ett S3-kompatibelt API med HTTP DELETE för att enkelt ta bort ögonblicksbilder och säkerhetskopior för användare.
    • SQLite var den enklaste, snabbaste och mest kostnadseffektiva lösningen.

Brist på alternativ

Såvitt vi vet är inga andra e-posttjänster utformade på detta sätt och de är inte heller öppen källkod.

Vi tror att detta kan bero till befintliga e-posttjänster som har äldre teknologi i produktion med spagettikod 🍝.

De flesta om inte alla befintliga e-postleverantörer är antingen stängd källkod eller annonserar som öppen källkod, men i verkligheten är bara deras front-end öppen källkod.

Den mest känsliga delen av e-post (den faktiska lagringen/IMAP/SMTP-interaktionen) allt görs på back-end (server), och inte på front-end (klient).

Testa vidarebefordra e-post

Anmäl dig idag kl https://forwardemail.net! 🚀