Ayrıntılı inceleme: Gizlilik odaklı ve güvenli e-posta hizmetimiz için kuantum güvenli şifrelenmiş SQLite posta kutularını nasıl kullanıyoruz?

Diğer e-posta hizmetlerinin aksine , posta kutunuza her zaman yalnızca sizin erişebilmenizi sağlıyoruz.

Önsöz

tldr; E-posta hizmetimiz %100 açık kaynak ve güvenli ve şifreli SQLite posta kutuları aracılığıyla gizlilik odaklı.

Biz lansmana kadar IMAP desteğiKalıcı veri depolama ihtiyaçlarımız için MongoDB'yi kullandık.

Bu teknoloji harika ve bugün hala kullanıyoruz - ancak MongoDB ile kullanımda olmayan şifrelemeye sahip olmak için Digital Ocean veya Mongo Atlas gibi MongoDB Enterprise sunan bir sağlayıcı kullanmanız veya bir kurumsal lisans için ödeme yapmanız gerekir (ve daha sonra satış ekibi gecikmesiyle çalışmak zorunda kalacaksınız).

Ekibimiz E-posta Yönlendir IMAP posta kutuları için geliştirici dostu, ölçeklenebilir, güvenilir ve şifrelenmiş bir depolama çözümüne ihtiyaç duyuyordu. Açık kaynak geliştiricileri olarak, kullanımda olmayan şifreleme özelliğini elde etmek için lisans ücreti ödemeniz gereken bir teknolojiyi kullanmak, karşıydı ilkelerimiz – ve böylece bu ihtiyaçları çözmek için sıfırdan yeni bir çözüm denedik, araştırdık ve geliştirdik.

Posta kutularınızı depolamak için paylaşılan bir veritabanı kullanmak yerine, posta kutularınızı (yalnızca sizin sahip olduğunuz) şifrenizle ayrı ayrı saklıyor ve şifreliyoruz. E-posta hizmetimiz o kadar güvenlidir ki, şifrenizi unutursanız posta kutunuzu kaybedersiniz. (ve çevrimdışı yedeklemelerle kurtarmanız veya baştan başlamanız gerekir).

Aşağıda derin bir dalış yaparken okumaya devam edin. e-posta servis sağlayıcılarının karşılaştırılması, Hizmetimiz nasıl çalışıyor?, teknoloji yığınımız, ve dahası.

E-posta servis sağlayıcı karşılaştırması

Ayrı ayrı şifrelenmiş SQLite posta kutularını saklayan, sınırsız alan adı, takma ad ve kullanıcı sunan ve giden SMTP, IMAP ve POP3 desteğine sahip tek %100 açık kaynaklı ve gizlilik odaklı e-posta hizmet sağlayıcısıyız:

Diğer e-posta sağlayıcılarının aksine, Forward Email ile depolama için alan adı veya takma ad bazında ödeme yapmanız gerekmez. Depolama, hesabınızın tamamında paylaşılır; dolayısıyla, birden fazla özel alan adınız ve her birinde birden fazla takma adınız varsa, o zaman sizin için mükemmel çözümüz. İsterseniz alan adı veya takma ad bazında depolama sınırları uygulayabileceğinizi unutmayın.

E-posta Hizmeti Karşılaştırmasını Okuyun

O nasıl çalışır

  1. Apple Mail, Thunderbird, Gmail veya Outlook gibi e-posta istemcinizi kullanarak güvenli bağlantımıza bağlanırsınız IMAP kullanıcı adınızı ve şifrenizi kullanan sunucular:

    • Kullanıcı adınız, alan adınızdaki tam takma adınızdır, örneğin hello@example.com.
    • Şifreniz rastgele oluşturulur ve tıkladığınızda yalnızca 30 saniye boyunca size gösterilir. Şifre oluştur itibaren Hesabım Alanlar Takma adlar.
  2. Bağlandıktan sonra e-posta istemciniz şunları gönderecektir: IMAP protokolü komutları posta kutunuzu senkronize tutmak için IMAP sunucumuza. Bu, taslak e-postaların yazılmasını ve saklanmasını ve yapabileceğiniz diğer eylemleri (örneğin, bir e-postayı Önemli olarak etiketlemek veya bir e-postayı Spam/Önemsiz Posta olarak işaretlemek) içerir.

  3. Posta alışverişi sunucuları (genellikle "MX" sunucuları olarak bilinir) yeni gelen e-postaları alır ve posta kutunuza kaydeder. Bu gerçekleştiğinde e-posta istemciniz bilgilendirilecek ve posta kutunuzu senkronize edecektir. Posta değişim sunucularımız, e-postanızı bir veya daha fazla alıcıya (dahil) iletebilir. web kancaları), e-postanızı bizim için şifrelenmiş IMAP depolama alanınızda saklayın, ya da her ikisi de!

    Daha fazlasını öğrenmek ister misiniz? Okumak e-posta yönlendirme nasıl kurulur, posta alışverişi hizmetimiz nasıl çalışır?veya görüntüle rehberlerimiz.

  4. Perde arkasında, güvenli e-posta depolama tasarımımız, posta kutularınızı şifrelenmiş ve yalnızca sizin tarafınızdan erişilebilir durumda tutmak için iki şekilde çalışır:

    • Bir göndericiden sizin için yeni posta alındığında, posta değişim sunucularımız sizin için bireysel, geçici ve şifreli bir posta kutusuna yazar.

      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!
      
    • E-posta istemcinizle IMAP sunucumuza bağlandığınızda, şifreniz daha sonra bellekte şifrelenir ve posta kutunuzu okumak ve yazmak için kullanılır. Posta kutunuz yalnızca bu şifreyle okunabilir ve yazılabilir. Bu şifreye sahip olan tek kişi olduğunuz için şunu unutmayın: sadece sen eriştiğinizde posta kutunuza okuyabilir ve yazabilirsiniz. E-posta istemcinizin bir daha posta veya senkronizasyon için yoklama girişiminde bulunması durumunda, yeni mesajlarınız bu geçici posta kutusundan aktarılacak ve sağladığınız şifre kullanılarak gerçek posta kutusu dosyanızda saklanacaktır. Bu geçici posta kutusunun daha sonra temizleneceğini ve silineceğini, böylece mesajların yalnızca şifre korumalı posta kutunuzda bulunacağını unutmayın.

    • IMAP'ye bağlıysanız (örneğin, Apple Mail veya Thunderbird gibi bir e-posta istemcisi kullanarak), geçici disk depolama alanına yazmamız gerekmez. Bunun yerine bellek içi şifrelenmiş IMAP şifreniz alınır ve kullanılır. Gerçek zamanlı olarak, size bir mesaj teslim edilmeye çalışıldığında, tüm IMAP sunucularına, sizin için aktif bir oturumları olup olmadığını soran bir WebSocket isteği göndeririz (bu, getirme kısmıdır) ve daha sonra bu mesajı iletiriz. şifrelenmiş bellek içi şifre - böylece geçici bir posta kutusuna yazmamıza gerek kalmaz, şifrelenmiş şifrenizi kullanarak gerçek şifrelenmiş posta kutunuza yazabiliriz.

      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. Şifrelenmiş posta kutularınızın yedekleri günlük olarak yapılmaktadır. Ayrıca istediğiniz zaman yeni bir yedekleme talep edebilir veya en son yedeği şuradan indirebilirsiniz: Hesabım Alanlar Takma adlar. Başka bir e-posta hizmetine geçmeye karar verirseniz posta kutularınızı ve yedeklerinizi istediğiniz zaman kolayca taşıyabilir, indirebilir, dışa aktarabilir ve temizleyebilirsiniz.

Teknolojiler

Veritabanları

Diğer olası veritabanı depolama katmanlarını araştırdık ancak hiçbiri gereksinimlerimizi SQLite kadar karşılamadı:

Veri tabanıKullanılmayan şifrelemeKorumalı alana alınmış Posta kutularıLisansHer Yerde Kullanılır
SQLite✅ Evet ile SQLite3Çoklu Şifreler✅ Kamu Alanı
MongoDB"Yalnızca MongoDB Enterprise'da mevcuttur"❌ İlişkisel veritabanı❌AGPL ve SSPL-1.0
rqliteYalnızca ağ❌ İlişkisel veritabanıMIT
dqliteTest edilmemiş ve henüz desteklenmiyor mu?Test edilmemiş ve henüz desteklenmiyor mu?LGPL-3.0-only
PostgreSQLEvet❌ İlişkisel veritabanıPostgreSQL (benzer BSD veya MIT)
MariaDBYalnızca InnoDB için❌ İlişkisel veritabanıGPLv2 ve BUSL-1.1
HamamböceğiDBYalnızca kurumsal özellik❌ İlişkisel veritabanıBUSL-1.1 ve diğerleri

Burada bir Çeşitli SQLite veritabanı depolama seçeneklerini karşılaştıran blog yazısı yukarıdaki tabloda.

Güvenlik

Her zaman kullanıyoruz atıl durumdaki şifreleme (AES-256), geçiş halindeki şifreleme (TLS), HTTPS üzerinden DNS ("DoH") 🍊 kullanarak mandalina, ve dağınık (ChaCha20-Poly1305) posta kutularında şifreleme. Ayrıca belirteç tabanlı iki faktörlü kimlik doğrulama kullanıyoruz (SMS'in ortadaki adam saldırıları), kök erişimi devre dışı bırakılmış döndürülmüş SSH anahtarları, kısıtlanmış IP adresleri aracılığıyla sunuculara özel erişim ve daha fazlası.

Bir durumda kötü hizmetçi saldırısı veya üçüncü taraf bir satıcının hileli çalışanı, posta kutunuz hâlâ yalnızca oluşturduğunuz şifreyle açılabilir. İçiniz rahat olsun; Cloudflare, Digital Ocean ve Vultr SOC Type 2 şikayet sunucusu sağlayıcılarımız dışında herhangi bir üçüncü taraf satıcıya güvenmiyoruz.

Amacımız mümkün olduğu kadar az sayıda tek başarısızlık noktası olabildiğince.

Posta kutuları

tldr; IMAP sunucularımız, posta kutularınızın her biri için ayrı ayrı şifrelenmiş SQLite veritabanlarını kullanır.

SQLite son derece popüler bir gömülü veritabanı – şu anda telefonunuzda ve bilgisayarınızda çalışıyor – ve neredeyse tüm önemli teknolojiler tarafından kullanılıyor.

Örneğin, şifrelenmiş sunucularımızda SQLite veritabanı posta kutusu bulunmaktadır. linux@example.com, info@example.com, hello@example.com vb. – her biri için bir tane .sqlite veritabanı dosyası. Veritabanı dosyalarını e-posta adresiyle de adlandırmıyoruz; bunun yerine posta kutusunun kime ait olduğunu veya hangi e-posta adresinin altında olduğunu paylaşmayan BSON ObjectID'yi ve oluşturulan benzersiz UUID'leri kullanıyoruz (ör. 353a03f21e534321f5d6e267.sqlite).

Bu veritabanlarının her biri, (yalnızca sizin sahip olduğunuz) şifreniz kullanılarak şifrelenir. dağınık (ChaCha20-Poly1305). Bu, posta kutularınızın ayrı ayrı şifrelendiği, bağımsız olduğu ve korumalı alana alınmışve taşınabilir.

SQLite'ta aşağıdakilerle ince ayar yaptık PRAGMA:

PRAGMAAmaç
cipher=chacha20ChaCha20-Poly1305 SQLite veritabanı şifrelemesi. Referans better-sqlite3-multiple-ciphers altında Projeler daha fazla bilgi için.
key="****************"Bu, e-posta istemcinizin IMAP bağlantısı üzerinden sunucumuza aktarılan, şifresi çözülmüş, yalnızca bellek içi şifrenizdir. Her okuma ve yazma oturumu için yeni veritabanı örnekleri oluşturulur ve kapatılır (korumalı alan oluşturma ve izolasyonu sağlamak için).
journal_model=WALÖnceden yazma günlüğü ("WAL") performansı artırır ve eşzamanlı okuma erişimine izin verir.
busy_timeout=5000Yazma kilidi hatalarını önler diğer yazmalar gerçekleşirken.
synchronous=NORMALİşlemlerin dayanıklılığını artırır veri bozulması riski olmadan.
foreign_keys=ONYabancı anahtar referanslarının (örneğin, bir tablodan diğerine ilişki) uygulanmasını zorunlu kılar. Varsayılan olarak bu SQLite'da açık değildirancak doğrulama ve veri bütünlüğü için etkinleştirilmesi gerekir.
encoding='UTF-8'Varsayılan kodlama geliştiricinin akıl sağlığını sağlamak için kullanmak.

Diğer tüm varsayılanlar SQLite'tandır. resmi PRAGMA belgeleri.

Eşzamanlılık

tldr; Kullanırız rclone ve WebSocket şifrelenmiş SQLite posta kutularınıza eşzamanlı okuma ve yazma işlemleri için.

Okur

Telefonunuzdaki e-posta istemciniz sorunu çözebilir imap.forwardemail.net Digital Ocean IP adreslerimizden birine; masaüstü istemciniz farklı bir IP'den ayrı bir IP'yi çözümleyebilir Sağlayıcı tamamen.

E-posta istemcinizin hangi IMAP sunucusuna bağlandığına bakılmaksızın, bağlantının veritabanınızdan gerçek zamanlı olarak %100 doğrulukla okunmasını istiyoruz:

  • Bu kullanılarak gerçekleştirilir rclone ile birlikte --vfs-cache-mode off (varsayılan).

  • Yerel disk önbelleğini kullanmak yerine, önbellek doğrudan uzak bağlantı noktasından (veritabanınız) gerçek zamanlı olarak okunur.

  • Yerel dosyanın bulunamaması durumunda bu şunu gösterir: rclone yüklenemedi veya bir sorun var. Bu durumda bir kullanırız WebSocket okumalar için geri dönüş (bu, performansı biraz azaltır ancak yine de hizmetin bütünlüğünü korur).

  • Sunucularımızın her biri tutarlı bir şekilde bağlanacak şekilde yapılandırılmıştır ve herhangi bir hata durumunda bizi gerçek zamanlı olarak uyarır.

yazar

Veritabanınıza yazmak biraz farklıdır; çünkü SQLite gömülü bir veritabanıdır ve posta kutunuz varsayılan olarak tek bir dosyada bulunur.

gibi seçenekleri araştırdık. litestream, rqlite, ve dqlite aşağıda – ancak bunların hiçbiri gereksinimlerimizi karşılamadı.

Yazma öncesi günlük kaydıyla yazma işlemlerini gerçekleştirmek için ("WAL") etkin - bunu yapmaktan yalnızca bir sunucunun ("Birincil") sorumlu olduğundan emin olmamız gerekir. WAL Eşzamanlılığı büyük ölçüde hızlandırır ve bir yazara ve birden fazla okuyucuya izin verir.

Birincil, şifrelenmiş posta kutularını içeren bağlı birimlerin bulunduğu veri sunucularında çalışıyor. Dağıtım açısından bakıldığında, arkadaki tüm bireysel IMAP sunucularını düşünebilirsiniz. imap.forwardemail.net ikincil sunucular ("İkincil") olmak.

ile iki yönlü iletişim sağlıyoruz WebSoketleri:

  • Birincil sunucular şunun bir örneğini kullanır: ws'S WebSocketServer sunucu.
  • İkincil sunucular aşağıdakilerin bir örneğini kullanır: ws'S WebSocket ile sarılmış müşteri söz verildiği gibi websocket ve yeniden bağlanma-websocket. Bu iki sarmalayıcı, WebSocket yeniden bağlanır ve belirli veritabanı yazma işlemleri için veri gönderip alabilir.

Yedeklemeler

tldr; Şifrelenmiş mail kutularınızın yedekleri günlük olarak yapılmaktadır. Ayrıca anında yeni bir yedekleme talebinde bulunabilir veya istediğiniz zaman en son yedeği indirebilirsiniz. Hesabım Alanlar Takma adlar.

Yedeklemeler için SQLite'ı çalıştırmamız yeterlidir. VACUUM INTO Bellek içi bir IMAP bağlantısından şifrelenmiş parolanızdan yararlanan IMAP komut işleme sırasında her gün komut verin. Yedeklemeler, mevcut bir yedekleme algılanmazsa veya SHA-256 En son yedeklemeyle karşılaştırıldığında dosyadaki karma değişti.

kullandığımızı unutmayın. VACUUM INTO yerleşik komutun aksine komut backup komutu çünkü bir sayfa bir işlem sırasında değiştirilirse backup komut işlemi, o zaman baştan başlaması gerekir. VACUUM INTO komut anlık görüntü alacaktır. Şu yorumlara bakın GitHub ve Hacker Haberleri daha fazla bilgi için.

Ek olarak kullanıyoruz VACUUM INTO aksine backup, Çünkü backup komutu veritabanını kısa bir süreliğine şifrelenmemiş olarak bırakacaktır. rekey çağrılır (bu GitHub'a bakın Yorum içgörü için).

İkincil, Birincil'e talimat verecektir. WebSocket yedeklemeyi yürütmek için bağlantı - ve Birincil daha sonra bunu yapmak için komutu alacak ve ardından:

  1. Şifrelenmiş posta kutunuza bağlanın.
  2. Bir yazma kilidi edinin.
  3. Bir WAL kontrol noktası çalıştırın wal_checkpoint(PASSIVE).
  4. Çalıştır VACUUM INTO SQLite komutu.
  5. Kopyalanan dosyanın şifrelenmiş parolayla (koruma/göstergelik önleme) açılabildiğinden emin olun.
  6. Depolama için Cloudflare R2'ye (veya belirtilmişse kendi sağlayıcınıza) yükleyin.
  7. Ortaya çıkan yedekleme dosyasını şununla sıkıştırın: gzip.
  8. Depolama için Cloudflare R2'ye (veya belirtilmişse kendi sağlayıcınıza) yükleyin.

Posta kutularınızın şifrelendiğini unutmayın; WebSocket iletişimi için IP kısıtlamalarımız ve diğer kimlik doğrulama önlemlerimiz olsa da, kötü bir aktör olması durumunda, WebSocket yükünün IMAP şifreniz olmadığı sürece veritabanınızı açamayacağından emin olabilirsiniz. .

Şu anda posta kutusu başına yalnızca bir yedek depolanıyor, ancak gelecekte belirli bir noktaya kurtarma sunabiliriz ("PITR").

IMAP sunucularımız şunları destekler: SEARCH karmaşık sorgular, normal ifadeler ve daha fazlasını içeren komut.

Hızlı arama performansı sayesinde FTS5 ve sqlite-regex.

saklıyoruz Date SQLite posta kutularındaki değerler şu şekildedir: ISO 8601 aracılığıyla dizeler Date.prototype.toISOString (Eşitlik karşılaştırmalarının düzgün çalışması için UTC saat dilimiyle).

Dizinler ayrıca arama sorgularındaki tüm özellikler için de saklanır.

Projeler

Kaynak kodumuz ve geliştirme sürecimizde kullandığımız projeleri özetleyen bir tablo (alfabetik olarak sıralanmıştır):

ProjeAmaç
YanıtlayıcıSunucu filomuzun tamamının kolaylıkla bakımını yapmak, ölçeklendirmek ve yönetmek için DevOps otomasyon platformu.
BreeNode.js ve JavaScript için cron, tarihler, ms, daha sonra ve insan dostu destek içeren iş zamanlayıcı.
KabinGüvenlik ve gizlilik göz önünde bulundurularak geliştirici dostu JavaScript ve Node.js günlük kaydı kitaplığı.
İzin VermekTüm mimarimize ve mühendislik tasarımımıza MVC ve daha fazlasıyla güç veren Node.js çerçevesi.
MongoDBPosta kutularının dışındaki tüm verileri (ör. hesabınız, ayarlarınız, alan adlarınız ve takma ad yapılandırmalarınız) depolamak için kullandığımız NoSQL veritabanı çözümü.
Firavun faresiTüm yığınımızda kullandığımız MongoDB nesne belge modellemesi ("ODM"). Kullanmaya devam etmemizi sağlayan özel yardımcılar yazdık SQLite ile Firavun Faresi 🎉
node.jsNode.js, tüm sunucu işlemlerimizi çalıştıran açık kaynaklı, platformlar arası JavaScript çalışma zamanı ortamıdır.
Not postacısıE-posta göndermek, bağlantı oluşturmak ve daha fazlası için Node.js paketi. Biz bu projenin resmi sponsoruyuz.
RedisÖnbelleğe alma, kanalları yayınlama/abone olma ve HTTPS istekleri üzerinden DNS için bellek içi veritabanı.
SQLite3Çoklu ŞifrelerTüm veritabanı dosyalarının şifrelenmesine izin veren SQLite şifreleme uzantısı (önceden yazma günlüğü ("WAL"), günlük, geri alma,…).
SQLiteStudioGeliştirme posta kutularını test etmek, indirmek ve görüntülemek için görsel SQLite düzenleyicisi (bunu da kullanabilirsiniz).
SQLiteÖlçeklenebilir, bağımsız, hızlı ve dayanıklı IMAP depolaması için yerleşik veritabanı katmanı.
Spam TarayıcıNode.js anti-spam, e-posta filtreleme ve kimlik avı önleme aracı (alternatifimiz) Spam Suikastçısı ve RS-spamd).
mandalinaNode.js ile HTTPS üzerinden DNS istekleri ve Redis kullanılarak önbelleğe alma; bu da küresel tutarlılık ve çok daha fazlasını sağlar.
yıldırım kuşuGeliştirme ekibimiz bunu şu şekilde kullanıyor (ve bunu da tavsiye ediyor) E-postayı İlet ile kullanmak için tercih edilen e-posta istemcisi.
UTMGeliştirme ekibimiz, IMAP ve SMTP sunucularımızla farklı e-posta istemcilerini (paralel olarak) test etmek için iOS ve macOS için bu sanal makineleri kullanır.
ubuntuTüm altyapımıza güç veren, modern açık kaynaklı Linux tabanlı sunucu işletim sistemi.
Vahşi ördekIMAP sunucusu kitaplığı – notlarına bakın eki tekilleştirme ve IMAP protokolü desteği.
daha iyi-sqlite3-çoklu-şifrelerNode.js'nin SQLite3 ile programlı olarak etkileşime geçmesi için hızlı ve basit API kitaplığı.
E-posta ŞablonlarıÖzel e-postalar (ör. hesap bildirimleri ve daha fazlası) oluşturmak, önizlemek ve göndermek için geliştirici dostu e-posta çerçevesi.
json-sqlMongo tarzı sözdizimini kullanan SQL sorgu oluşturucusu. Veritabanından bağımsız bir yaklaşımla tüm yığında Mongo tarzında yazmaya devam edebildiğimiz için bu, geliştirme ekibimize zaman kazandırıyor. Ayrıca sorgu parametrelerini kullanarak SQL enjeksiyon saldırılarından kaçınmaya da yardımcı olur.
diz-şema-denetçisiMevcut veritabanı şeması hakkında bilgi çıkarmak için SQL yardımcı programı. Bu, tüm endekslerin, tabloların, sütunların, kısıtlamaların ve daha fazlasının geçerli ve geçerli olduğunu kolayca doğrulamamıza olanak tanır. 1:1 nasıl olmaları gerektiği ile. Veritabanı şemalarında değişiklik yapılması durumunda yeni sütunlar ve dizinler eklemek için otomatik yardımcılar bile yazdık (son derece ayrıntılı hata uyarılarıyla birlikte).
diz çökmekYalnızca veritabanı geçişleri ve şema doğrulaması için kullandığımız SQL sorgu oluşturucusu knex-schema-inspector.
mandalinaOtomatik i18n Markdown desteğiyle cümle çevirisi Google Bulut Çeviri API'si.
mx bağlantısıNode.js paketi, MX sunucularıyla bağlantı kurmak ve hataları çözmek için kullanılır.
pm2Yerleşik yük dengeleyiciye sahip Node.js üretim süreci yöneticisi (ince ayarlı performans için).
SMTP sunucusuSMTP sunucu kitaplığı – bunu posta alışverişimiz ("MX") ve giden SMTP sunucularımız için kullanırız.
ImapTestIMAP sunucularını karşılaştırmalı değerlendirmelere ve RFC belirtimi IMAP protokolü uyumluluğuna göre test etmek için kullanışlı bir araç. Bu proje tarafından oluşturuldu. Güvercinlik ekibi (Temmuz 2002'den itibaren aktif bir açık kaynaklı IMAP ve POP3 sunucusu). Bu araçla IMAP sunucumuzu kapsamlı bir şekilde test ettik.

Kullandığımız diğer projeleri burada bulabilirsiniz. GitHub'daki kaynak kodumuz.

Sağlayıcılar

SağlayıcıAmaç
bulut parlamasıDNS sağlayıcısı, durum denetimleri, yük dengeleyiciler ve yedekleme depolama alanı Cloudflare R2.
Dijital OkyanusÖzel sunucu barındırma, SSD blok depolama ve yönetilen veritabanları.
VultrÖzel sunucu barındırma ve SSD blok depolama.

Düşünceler

Prensipler

Yönlendirme E-postası şu ilkelere göre tasarlanmıştır:

  1. Her zaman geliştirici dostu, güvenlik ve gizlilik odaklı ve şeffaf olun.
  2. Bağlı olmak MVC, Unix, KISS, DRY, YAGNI, Oniki Faktör, Occam'ın usturası, ve test sürümü
  3. Dağınık, önyüklemeli ve ramen-karlı geliştirici

Deneyler

tldr; Sonuçta S3 uyumlu nesne depolama ve/veya Sanal Tabloların kullanılması, performans nedenleriyle teknik olarak mümkün değildir ve bellek sınırlamaları nedeniyle hataya açıktır.

Yukarıda tartışıldığı gibi nihai SQLite çözümümüze giden birkaç deney yaptık.

Bunlardan biri kullanmayı denemekti rclone ve S3 uyumlu bir depolama katmanıyla birlikte SQLite.

Bu deney bizi rclone, SQLite ve VFS kullanım:

  • Etkinleştirirseniz --vfs-cache-mode writes rclone ile işaretlerseniz okumalar tamam olur, ancak yazmalar önbelleğe alınır.
    • Küresel olarak dağıtılmış birden fazla IMAP sunucunuz varsa, tek bir yazıcınız ve birden fazla dinleyiciniz olmadığı sürece (örneğin, pub/sub yaklaşımı) önbellek bunların genelinde kapalı olacaktır.
    • Bu inanılmaz derecede karmaşıktır ve buna benzer herhangi bir ek karmaşıklığın eklenmesi, daha fazla tekil hata noktasına yol açacaktır.
    • S3 uyumlu depolama sağlayıcıları kısmi dosya değişikliklerini desteklemez; bu, dosyada herhangi bir değişiklik yapılması anlamına gelir. .sqlite dosyanın tamamen değiştirilmesine ve veritabanının yeniden yüklenmesine neden olacaktır.
    • Gibi diğer çözümler rsync var, ancak ön-günlüğe yazmaya odaklanmıyorlar ("WAL") desteği – bu yüzden Litestream'i inceledik. Neyse ki şifreleme kullanımımız zaten WAL bizim için dosyalar olduğundan, bunun için Litestream'e güvenmemize gerek yok. Ancak üretimde kullanım açısından Litestream'e henüz güvenmiyorduk ve bu konuda aşağıda birkaç not vereceğiz.
    • Bu seçeneğin kullanılması --vfs-cache-mode writes ( sadece SQLite'ı kullanmanın yolu rclone yazmalar için) tüm veri tabanını bellekte sıfırdan kopyalamaya çalışacaktır; 10 GB'lık bir posta kutusunun işlenmesinde sorun yoktur, ancak aşırı yüksek depolama alanına sahip birden fazla posta kutusunun işlenmesi, IMAP sunucularının bellek sınırlamaları yaşamasına ve ENOMEM hatalar, bölümleme hataları ve veri bozulması.
  • SQLite kullanmaya çalışırsanız Sanal Tablolar (örn. kullanarak s3db) verileri S3 uyumlu bir depolama katmanında canlı tutmak için birkaç sorunla daha karşılaşacaksınız:
    • S3 API uç noktalarına HTTP ile ulaşılması gerekeceğinden okuma ve yazma işlemleri son derece yavaş olacaktır. GET, PUT, HEAD, ve POST yöntemler.
    • Geliştirme testleri, fiber internette 500.000-1 milyonun üzerinde kaydın aşılmasının, S3 uyumlu sağlayıcılara yönelik yazma ve okuma verimiyle hâlâ sınırlı olduğunu gösterdi. Örneğin, geliştiricilerimiz çalıştırdı for her iki sıralı SQL'i yapmak için döngüler INSERT ifadeler ve toplu olarak büyük miktarda veri yazan ifadeler. Her iki durumda da performans şaşırtıcı derecede yavaştı.
    • Sanal tablolar indekslere sahip olamaz, ALTER TABLE açıklamalar ve diğer sınırlamalar – bu da veri miktarına bağlı olarak 1-2 dakika veya daha fazla gecikmeye neden olur.
    • Nesneler şifrelenmeden saklandı ve herhangi bir yerel şifreleme desteği mevcut değil.
  • kullanarak da araştırdık. sqlite-s3vfs kavramsal ve teknik olarak önceki madde işaretine benzer (bu nedenle aynı sorunlara sahiptir). Bir olasılık özel bir kullanım olabilir sqlite3 gibi şifrelemeyle sarılmış yapı wxSQLite3 (şu anda yukarıdaki çözümümüzde kullanıyoruz) aracılığıyla kurulum dosyasını düzenleme.
  • Başka bir potansiyel yaklaşım, multipleks uzatmaancak bunun 32 GB'lik bir sınırlaması vardır ve karmaşık oluşturma ve geliştirme sorunları gerektirir.
  • ALTER TABLE ifadeler gereklidir (bu nedenle bu, Sanal Tabloların kullanımını tamamen ortadan kaldırır). İhtiyacımız var ALTER TABLE kancamız için ifadeler knex-schema-inspector düzgün çalışmasını sağlar – bu, verilerin bozulmamasını ve alınan satırların bizim kurallarımıza göre geçerli belgelere dönüştürülebilmesini sağlar. mongoose şema tanımları (kısıtlama, değişken türü ve isteğe bağlı veri doğrulamayı içerir).
  • Açık kaynak topluluğunda SQLite ile ilgili S3 uyumlu projelerin neredeyse tamamı Python'dadır (ve yığınımızın %100'ü için kullandığımız JavaScript değil).
  • Sıkıştırma kütüphaneleri gibi sqlite-zstd (Görmek yorumlar) umut verici görünüyor, ancak henüz üretimde kullanıma hazır olmayabilir. Bunun yerine veri türlerinde uygulama tarafında sıkıştırma String, Object, Map, Array, Set, ve Buffer daha temiz ve daha kolay bir yaklaşım olacak (ve bir dosyayı saklayabileceğimiz için taşınması da daha kolay) Boolean bayrak veya sütun – hatta kullanın PRAGMA user_version=1 sıkıştırma için veya user_version=0 veritabanı meta verileri olarak sıkıştırma yapılmaması için).
    • Neyse ki, IMAP sunucu depolama alanımızda ek tekilleştirme işlemi zaten uygulandı; bu nedenle aynı eke sahip her mesaj, ekin bir kopyasını saklamaz; bunun yerine, birden fazla mesaj ve iş parçacığı için tek bir ek, bir posta kutusunda (ve yabancı bir dosyada) depolanır. referans daha sonra kullanılır).
  • SQLite replikasyon ve yedekleme çözümü olan Litestream projesi oldukça umut verici ve büyük olasılıkla gelecekte kullanacağız.
  • Yedekleme geri yüklemesinin sürtünmesiz ve önemsiz olması gerekir. MongoDB gibi bir çözümün kullanılması mongodump ve mongoexport sadece sıkıcı değil, aynı zamanda zaman alıcıdır ve konfigürasyon karmaşıklığına sahiptir.
    • SQLite veritabanları bunu kolaylaştırır (tek bir dosyadır).
    • Kullanıcıların posta kutularını alıp istedikleri an ayrılabilecekleri bir çözüm tasarlamak istedik.
      • Basit Node.js komutları fs.unlink('mailbox.sqlite')) ve disk depolama alanından kalıcı olarak silinir.
      • Benzer şekilde HTTP ile S3 uyumlu bir API kullanabiliriz DELETE kullanıcılar için anlık görüntüleri ve yedeklemeleri kolayca kaldırmak için.
    • SQLite en basit, en hızlı ve en uygun maliyetli çözümdü.

Alternatif eksikliği

Bildiğimiz kadarıyla başka hiçbir e-posta hizmeti bu şekilde tasarlanmamıştır ve açık kaynak değildir.

Biz bunun nedeni olabileceğini düşünüyorum üretimde eski teknolojiye sahip mevcut e-posta hizmetlerine spagetti kodu 🍝.

Mevcut e-posta servis sağlayıcılarının tümü olmasa da çoğu ya kapalı kaynaktır ya da açık kaynak olarak reklam yapar. ancak gerçekte yalnızca ön uçları açık kaynaklıdır.

E-postanın en hassas kısmı (gerçek depolama/IMAP/SMTP etkileşimi) hepsi arka uçta (sunucuda) yapılır ve Olumsuz ön uçta (istemci).

E-postayı İlet'i deneyin

Bugün şu saatte kaydolun: https://forwardemail.net! 🚀