البريد الإلكتروني المقاوم للكم: كيف نستخدم صناديق بريد SQLite المشفرة للحفاظ على أمان بريدك الإلكتروني

مقدمة

[!هام] خدمة البريد الإلكتروني لدينا هي مفتوح المصدر بنسبة 100% والتركيز على الخصوصية من خلال صناديق بريد SQLite الآمنة والمشفرة.

حتى أطلقنا دعم IMAPلقد استخدمنا MongoDB لتلبية احتياجاتنا المتعلقة بتخزين البيانات المستمرة.

هذه التكنولوجيا مذهلة وما زلنا نستخدمها حتى يومنا هذا - ولكن من أجل الحصول على تشفير ثابت مع MongoDB، تحتاج إلى استخدام مزود يقدم MongoDB Enterprise، مثل Digital Ocean أو Mongo Atlas - أو دفع ثمن ترخيص مؤسسي (وبعد ذلك يتعين عليك العمل مع زمن انتقال فريق المبيعات).

فريقنا في إعادة توجيه البريد الإلكتروني كنتُ بحاجة إلى حل تخزين سهل الاستخدام، وقابل للتطوير، وموثوق، ومشفّر لصناديق بريد IMAP. بصفتي مطورًا مفتوح المصدر، كان استخدام تقنية تتطلب دفع رسوم ترخيص للحصول على ميزة التشفير عند السكون أمرًا مخالفًا. مبادئنا - ولذلك قمنا بالتجربة والبحث وتطوير حل جديد من الصفر لحل هذه الاحتياجات.

بدلاً من استخدام قاعدة بيانات مشتركة لتخزين صناديق البريد الخاصة بك، نقوم بتخزين صناديق البريد الخاصة بك وتشفيرها بشكل فردي باستخدام كلمة المرور الخاصة بك (والتي تمتلكها أنت فقط). خدمة البريد الإلكتروني لدينا آمنة للغاية بحيث إذا نسيت كلمة المرور الخاصة بك، فإنك تفقد صندوق البريد الخاص بك (وتحتاج إلى التعافي باستخدام النسخ الاحتياطية غير المتصلة بالإنترنت أو البدء من جديد).

استمر في القراءة بينما نلقي نظرة متعمقة أدناه مقارنة بين مزودي خدمات البريد الإلكتروني, كيف تعمل خدمتنا, مجموعة التكنولوجيا لدينا، وأكثر.

مقارنة مزودي خدمة البريد الإلكتروني

نحن مزود خدمة البريد الإلكتروني الوحيد مفتوح المصدر بنسبة 100% والذي يركز على الخصوصية والذي يخزن صناديق بريد SQLite المشفرة بشكل فردي، ويقدم نطاقات وأسماء مستعارة ومستخدمين غير محدودة، ويدعم SMTP وIMAP وPOP3 الصادر:

على عكس موفري البريد الإلكتروني الآخرين، لا تحتاج إلى دفع تكاليف التخزين على أساس كل نطاق أو اسم مستعار مع Forward Email. مساحة التخزين مشتركة على حسابك بالكامل، لذا إذا كان لديك عدة أسماء نطاقات مخصصة وأسماء مستعارة متعددة على كل منها، فنحن الحل الأمثل لك. يُرجى العلم أنه لا يزال بإمكانك فرض حدود تخزينية لكل نطاق أو اسم مستعار، إذا رغبت في ذلك.

قراءة مقارنة خدمات البريد الإلكتروني

كيف يعمل؟

  1. باستخدام عميل البريد الإلكتروني الخاص بك مثل Apple Mail أو Thunderbird أو Gmail أو Outlook - يمكنك الاتصال بشبكتنا الآمنة IMAP الخوادم باستخدام اسم المستخدم وكلمة المرور الخاصة بك:

    • اسم المستخدم الخاص بك هو الاسم المستعار الكامل الخاص بك مع نطاقك مثل [email protected].
    • يتم إنشاء كلمة المرور الخاصة بك بشكل عشوائي ويتم عرضها لك لمدة 30 ثانية فقط عند النقر فوقها إنشاء كلمة مرور من حسابي المجالات أسماء مستعارة.
  2. بمجرد الاتصال، سيرسل لك عميل البريد الإلكتروني الخاص بك أوامر بروتوكول IMAP إلى خادم IMAP الخاص بنا للحفاظ على مزامنة صندوق بريدك. يشمل ذلك كتابة مسودات رسائل البريد الإلكتروني وتخزينها، بالإضافة إلى إجراءات أخرى قد تقوم بها (مثل تصنيف رسالة بريد إلكتروني كمهمة أو وضع علامة على أنها بريد عشوائي/غير مرغوب فيه).

  3. تستقبل خوادم تبادل البريد (المعروفة باسم خوادم "MX") رسائل البريد الإلكتروني الواردة الجديدة وتخزنها في صندوق بريدك. عند حدوث ذلك، سيتلقى برنامج البريد الإلكتروني إشعارًا وسيزامن صندوق بريدك. يمكن لخوادم تبادل البريد لدينا إعادة توجيه بريدك الإلكتروني إلى مستلم واحد أو أكثر (بما في ذلك خطافات الويب)، قم بتخزين بريدك الإلكتروني في وحدة تخزين IMAP المشفرة لدينا، أو كلاهما!

    [!نصيحة] هل ترغب بمعرفة المزيد؟ اقرأ كيفية إعداد إعادة توجيه البريد الإلكتروني, كيف تعمل خدمة تبادل البريد لدينا، أو عرض مرشدينا.

  4. خلف الكواليس، يعمل تصميم تخزين البريد الإلكتروني الآمن لدينا بطريقتين للحفاظ على تشفير صناديق البريد الإلكتروني الخاصة بك وجعلها متاحة لك فقط:

    • عندما نتلقى بريدًا جديدًا لك من مرسل، تكتب خوادم تبادل البريد لدينا إلى صندوق بريد فردي ومؤقت ومشفر لك.

      sequenceDiagram
          autonumber
          actor Sender
          Sender->>MX: Inbound message received for your alias (e.g. [email protected]).
          MX->>SQLite: Message is stored in a temporary mailbox.
          Note over MX,SQLite: Forwards to other recipients and webhooks configured.
          MX->>Sender: Success!
      
    • عند اتصالك بخادم IMAP الخاص بنا باستخدام برنامج البريد الإلكتروني، تُشفَّر كلمة مرورك في الذاكرة وتُستخدم لقراءة رسائل البريد الإلكتروني وكتابتها في صندوق بريدك. لا يُمكن قراءة رسائل البريد الإلكتروني وكتابتها إلا باستخدام كلمة المرور هذه. تذكَّر أنه بما أنك الوحيد الذي يملك كلمة المرور هذه، أنت فقط يمكنه القراءة والكتابة إلى صندوق بريدك عند الوصول إليه. في المرة القادمة التي يحاول فيها برنامج البريد الإلكتروني الخاص بك البحث عن البريد أو مزامنته، سيتم نقل رسائلك الجديدة من صندوق البريد المؤقت هذا وتخزينها في ملف صندوق بريدك الفعلي باستخدام كلمة المرور التي أدخلتها. يُرجى العلم بأنه سيتم مسح صندوق البريد المؤقت هذا وحذفه لاحقًا، بحيث لا يحتفظ بالرسائل إلا صندوق بريدك المحمي بكلمة مرور.

    • إذا كنت متصلاً ببروتوكول IMAP (مثلاً، باستخدام برنامج بريد إلكتروني مثل Apple Mail أو Thunderbird)، فلن نحتاج إلى الكتابة إلى وحدة تخزين مؤقتة على القرص. بدلاً من ذلك، سيتم جلب كلمة مرور IMAP المشفرة المحفوظة في الذاكرة واستخدامها. في الوقت الفعلي، عند محاولة تسليم رسالة إليك، نرسل طلب WebSocket إلى جميع خوادم IMAP نسألهم عن وجود جلسة نشطة لك (هذه هي مرحلة الجلب)، ثم نمرر كلمة المرور المشفرة المحفوظة في الذاكرة لاحقًا - لذا لا نحتاج إلى الكتابة إلى صندوق بريد مؤقت، بل يمكننا الكتابة إلى صندوق بريدك المشفر الفعلي باستخدام كلمة مرورك المشفرة.

      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. نسخ احتياطية لصناديق البريد المشفرة الخاصة بك يتم إجراؤها يوميًا. يمكنك أيضًا طلب نسخة احتياطية جديدة في أي وقت أو تنزيل أحدث نسخة احتياطية من حسابي المجالات الأسماء المستعارة. إذا قررتَ الانتقال إلى خدمة بريد إلكتروني أخرى، يمكنك بسهولة نقل وتنزيل وتصدير وحذف صناديق بريدك والنسخ الاحتياطية في أي وقت.

التقنيات

قواعد البيانات

لقد استكشفنا طبقات تخزين قاعدة البيانات الأخرى المحتملة، ولكن لم تلبي أي منها متطلباتنا بقدر ما فعلت SQLite:

قاعدة البياناتالتشفير في حالة السكونصندوق رمل صناديق البريدرخصةمستخدم في كل مكان
SQLite✅ نعم مع SQLite3 تشفيرات متعددة✅ المجال العام
مونجو دي بي"متوفر في MongoDB Enterprise فقط"❌ قاعدة بيانات علائقية❌ AGPL و SSPL-1.0
rqliteالشبكة فقط❌ قاعدة بيانات علائقيةMIT
دك لايتلم يتم اختباره ولم يتم دعمه بعد؟لم يتم اختباره ولم يتم دعمه بعد؟LGPL-3.0-only
بوستجرس كيو النعم❌ قاعدة بيانات علائقيةPostgreSQL (مشابه ل BSD أو MIT)
ماريا دي بيمخصص لـ InnoDB فقط❌ قاعدة بيانات علائقيةGPLv2 و BUSL-1.1
قاعدة بيانات الصرصورميزة مخصصة للمؤسسات فقط❌ قاعدة بيانات علائقيةBUSL-1.1 و اخرين

وهنا هو تدوينة تقارن بين عدة خيارات لتخزين قاعدة بيانات SQLite في الجدول أعلاه.

حماية

نحن نستخدم في جميع الأوقات التشفير في حالة السكون (AES-256), التشفير أثناء النقل (TLS), DNS عبر HTTPS ("DoH") باستخدام 🍊 اليوسفي، و سكليت (تشاتشا20-بولي1305) تشفير صناديق البريد. بالإضافة إلى ذلك، نستخدم مصادقة ثنائية العوامل تعتمد على الرمز (على عكس الرسائل النصية القصيرة التي يُشتبه في أنها هجمات الرجل في المنتصف), مفاتيح SSH المُدارة مع تعطيل الوصول إلى الجذر، والوصول الحصري إلى الخوادم من خلال عناوين IP المقيدة، والمزيد.

في حالة حدوث هجوم الخادمة الشريرة أو موظف مارق من بائع تابع لجهة خارجية، لا يزال بإمكانك فتح صندوق البريد الخاص بك فقط باستخدام كلمة المرور التي تم إنشاؤهاكن مطمئنًا، فنحن لا نعتمد على أي بائعين خارجيين غير موفري خوادم SOC Type 2 لدينا وهم Cloudflare وDataPacket وDigital Ocean وVultr.

هدفنا هو أن يكون لدينا أقل عدد نقطة فشل واحدة قدر الإمكان.

صناديق البريد

ملخص؛ تستخدم خوادم IMAP الخاصة بنا قواعد بيانات SQLite مشفرة بشكل فردي لكل صندوق بريد لديك.

SQLite هو برنامج شائع للغاية قاعدة بيانات مضمنة - تعمل حاليًا على هاتفك وجهاز الكمبيوتر الخاص بك - وتستخدمها جميع التقنيات الرئيسية تقريبًا.

على سبيل المثال، يوجد على خوادمنا المشفرة صندوق بريد لقاعدة بيانات SQLite [email protected], [email protected], [email protected] وهكذا - واحد لكل واحد كـ .sqlite ملف قاعدة البيانات. لا نُسمّي ملفات قاعدة البيانات بعنوان البريد الإلكتروني أيضًا، بل نستخدم مُعرّف كائن BSON ومعرفات UUID فريدة مُولّدة، والتي لا تُشارك هوية صاحب صندوق البريد أو عنوان البريد الإلكتروني المُسجّل به (مثل: 353a03f21e534321f5d6e267.sqlite).

يتم تشفير كل من هذه القواعد البيانات باستخدام كلمة المرور الخاصة بك (والتي لديك فقط) باستخدام سكليت (تشاتشا20-بولي1305). وهذا يعني أن صناديق البريد الخاصة بك مشفرة بشكل فردي، ومكتفية ذاتيًا، صندوق رمل، و المحمولة.

لقد قمنا بضبط SQLite بما يلي PRAGMA:

PRAGMAغاية
cipher=chacha20تشفير قاعدة بيانات ChaCha20-Poly1305 SQLite. مرجع better-sqlite3-multiple-ciphers تحت المشاريع لمزيد من التبصر.
key="****************"هذه كلمة مرورك المُفككة والمُخزّنة في الذاكرة فقط، والتي تُمرّر عبر اتصال IMAP لعميل البريد الإلكتروني الخاص بك إلى خادمنا. يتم إنشاء نسخ جديدة من قاعدة البيانات وإغلاقها لكل جلسة قراءة وكتابة (لضمان الحماية والعزل).
journal_model=WALسجل الكتابة المسبقة ("WAL") مما يعزز الأداء ويسمح بالوصول المتزامن للقراءة.
busy_timeout=5000يمنع أخطاء قفل الكتابة بينما تجري كتابات أخرى.
synchronous=NORMALيزيد من متانة المعاملات بدون خطر تلف البيانات.
foreign_keys=ONيفرض فرض المراجع الرئيسية الخارجية (على سبيل المثال علاقة من جدول إلى آخر). بشكل افتراضي، لا يتم تشغيل هذا في SQLite، ولكن للتحقق من صحة البيانات وسلامتها يجب تمكينه.
encoding='UTF-8'الترميز الافتراضي للاستخدام لضمان سلامة المطور.

جميع الإعدادات الافتراضية الأخرى هي من SQLite كما هو محدد من وثائق PRAGMA الرسمية.

التزامن

ملخص؛ نحن نستخدم WebSocket للقراءة والكتابة المتزامنة إلى صناديق بريد SQLite المشفرة الخاصة بك.

يقرأ

قد يحل عميل البريد الإلكتروني على هاتفك المشكلة imap.forwardemail.net إلى أحد عناوين IP الخاصة بـ Digital Ocean الخاصة بنا - وقد يحل عميل سطح المكتب الخاص بك عنوان IP منفصلاً من عنوان IP مختلف مزود تماما.

بغض النظر عن خادم IMAP الذي يتصل به عميل البريد الإلكتروني الخاص بك، نريد أن يقرأ الاتصال من قاعدة بياناتك في الوقت الفعلي بدقة 100%. يتم ذلك من خلال WebSockets.

يكتب

تختلف عملية الكتابة إلى قاعدة البيانات الخاصة بك بعض الشيء - نظرًا لأن SQLite عبارة عن قاعدة بيانات مضمنة وصندوق البريد الخاص بك موجود في ملف واحد بشكل افتراضي.

لقد استكشفنا خيارات مثل litestream, rqlite، و dqlite أدناه - ولكن لم يلبِّ أي منها متطلباتنا.

لإنجاز عمليات الكتابة باستخدام تسجيل الكتابة المسبقة ("WAL") ممكّنًا - نحتاج إلى التأكد من أن خادمًا واحدًا فقط ("الأساسي") هو المسؤول عن القيام بذلك. WAL يعمل على تسريع التزامن بشكل كبير ويسمح بكاتب واحد وقراء متعددين.

يعمل النظام الأساسي على خوادم البيانات مع وحدات التخزين المُركّبة التي تحتوي على صناديق البريد المُشفّرة. من منظور التوزيع، يُمكنك اعتبار جميع خوادم IMAP المُستقلة خلفه. imap.forwardemail.net أن تكون خوادم ثانوية ("ثانوية").

نحن ننجز التواصل في الاتجاهين مع مآخذ الويب:

  • تستخدم الخوادم الأساسية مثيلًا من ويسWebSocketServer الخادم.
  • تستخدم الخوادم الثانوية مثيلًا من ويسWebSocket العميل الذي تم تغليفه بـ مقبس الويب كما وعد و إعادة توصيل مقبس الويب. تضمن هاتان الغلافتان أن WebSocket يعيد الاتصال ويمكنه إرسال واستقبال البيانات للكتابة في قاعدة بيانات محددة.

النسخ الاحتياطية

ملخص؛ يتم إجراء نسخ احتياطية لصناديق بريدك المشفرة يوميًا. يمكنك أيضًا طلب نسخة احتياطية جديدة فورًا أو تنزيل أحدث نسخة احتياطية في أي وقت من حسابي المجالات أسماء مستعارة.

بالنسبة للنسخ الاحتياطية، نقوم ببساطة بتشغيل SQLite VACUUM INTO أمر يوميًا أثناء معالجة أوامر IMAP، والتي تستفيد من كلمة مرورك المشفرة من اتصال IMAP في الذاكرة. تُخزَّن النسخ الاحتياطية في حال عدم اكتشاف أي نسخة احتياطية موجودة أو في حال SHA-256 لقد تغيرت التجزئة في الملف مقارنةً بالنسخة الاحتياطية الأحدث.

لاحظ أننا نستخدم VACUUM INTO الأمر على عكس الأمر المدمج backup الأمر لأنه إذا تم تعديل الصفحة أثناء backup عملية الأمر، ثم يجب أن تبدأ من جديد. VACUUM INTO سيأخذ الأمر لقطة. انظر هذه التعليقات على جيثب و أخبار القراصنة لمزيد من التبصر.

بالإضافة إلى ذلك نستخدم VACUUM INTO على عكس backup، لأن backup سيترك الأمر قاعدة البيانات غير مشفرة لفترة وجيزة حتى rekey يتم استدعاؤه (انظر هذا على GitHub تعليق (للحصول على فهم أفضل).

سيقوم الثانوي بإرشاد الابتدائي على WebSocket الاتصال لتنفيذ النسخ الاحتياطي - ثم سيستقبل الجهاز الأساسي الأمر للقيام بذلك وسيقوم بعد ذلك بما يلي:

  1. قم بالاتصال بصندوق البريد المشفر الخاص بك.
  2. احصل على قفل الكتابة.
  3. قم بتشغيل نقطة تفتيش WAL عبر wal_checkpoint(PASSIVE).
  4. تشغيل VACUUM INTO أمر SQLite.
  5. تأكد من إمكانية فتح الملف المنسوخ باستخدام كلمة المرور المشفرة (الحماية/الحماية من الاختراق).
  6. قم بتحميله إلى Cloudflare R2 للتخزين (أو إلى موفر خاص بك إذا تم تحديده).

تذكر أن صناديق البريد الخاصة بك مشفرة - وعلى الرغم من وجود قيود IP وتدابير مصادقة أخرى مطبقة لاتصالات WebSocket - في حالة وجود جهة سيئة، يمكنك التأكد من أنه ما لم يكن حمولة WebSocket تحتوي على كلمة مرور IMAP الخاصة بك، فلن تتمكن من فتح قاعدة البيانات الخاصة بك.

يتم تخزين نسخة احتياطية واحدة فقط لكل صندوق بريد في هذا الوقت، ولكن في المستقبل قد نقدم استردادًا في نقطة زمنية محددة ("PITR").

تدعم خوادم IMAP الخاصة بنا SEARCH الأمر مع الاستعلامات المعقدة، التعبيرات العادية، وأكثر من ذلك.

الأداء السريع للبحث هو بفضل FTS5 و sqlite-regex.

نحن نخزن Date القيم الموجودة في صناديق بريد SQLite مثل ISO 8601 سلاسل عبر Date.prototype.toISOString (مع المنطقة الزمنية UTC لمقارنات المساواة لتعمل بشكل صحيح).

يتم أيضًا تخزين الفهارس لجميع الخصائص الموجودة في استعلامات البحث.

المشاريع

فيما يلي جدول يوضح المشاريع التي نستخدمها في الكود المصدر وعملية التطوير (مرتبة أبجديًا):

مشروعغاية
أنسيبلمنصة أتمتة DevOps لصيانة وتوسيع وإدارة أسطولنا بالكامل من الخوادم بكل سهولة.
بريمجدول الوظائف لـ Node.js وJavaScript مع cron، والتواريخ، والملي ثانية، واللاحقة، والدعم السهل الاستخدام.
كابينةمكتبة تسجيل JavaScript وNode.js صديقة للمطورين مع وضع الأمان والخصوصية في الاعتبار.
فتىإطار عمل Node.js الذي يدعم بنيتنا الكاملة وتصميمنا الهندسي باستخدام MVC والمزيد.
مونجو دي بيحل قاعدة بيانات NoSQL الذي نستخدمه لتخزين جميع البيانات الأخرى خارج صناديق البريد (على سبيل المثال حسابك والإعدادات والمجالات وتكوينات الأسماء المستعارة).
النمسنمذجة مستندات كائنات MongoDB ("ODM") التي نستخدمها في جميع حزمنا. كتبنا أدوات مساعدة خاصة تُمكّننا من الاستمرار في استخدام Mongoose مع SQLite 🎉
Node.jsNode.js هي بيئة تشغيل JavaScript مفتوحة المصدر ومتعددة الأنظمة الأساسية والتي تقوم بتشغيل جميع عمليات الخادم لدينا.
نوداميلرحزمة Node.js لإرسال رسائل البريد الإلكتروني، وإنشاء الاتصالات، والمزيد. نحن الراعي الرسمي لهذا المشروع.
ريديسقاعدة بيانات في الذاكرة للتخزين المؤقت وقنوات النشر/الاشتراك وطلبات DNS عبر HTTPS.
SQLite3 تشفيرات متعددةامتداد التشفير لـ SQLite للسماح بتشفير ملفات قاعدة البيانات بأكملها (بما في ذلك سجل الكتابة المسبقة ("WAL")، المجلة، التراجع، ...).
إس كيو لايت ستوديومحرر Visual SQLite (الذي يمكنك استخدامه أيضًا) لاختبار صناديق البريد الخاصة بالتطوير وتنزيلها وعرضها.
SQLiteطبقة قاعدة بيانات مضمنة لتخزين IMAP قابل للتطوير ومستقل وسريع ومرن.
ماسح البريد العشوائيأداة Node.js لمكافحة البريد العشوائي وتصفية البريد الإلكتروني ومنع التصيد الاحتيالي (بديلنا لـ قاتل البريد العشوائي و rspamd).
اليوسفيطلبات DNS عبر HTTPS باستخدام Node.js والتخزين المؤقت باستخدام Redis - مما يضمن الاتساق العالمي وأكثر من ذلك بكثير.
طائر الرعديستخدم فريق التطوير الخاص بنا هذا (ويوصي به أيضًا) كـ عميل البريد الإلكتروني المفضل للاستخدام مع Forward Email.
UTMيستخدم فريق التطوير الخاص بنا هذه الآلات الافتراضية لإنشاء أنظمة التشغيل iOS وmacOS لاختبار عملاء البريد الإلكتروني المختلفين (بالتوازي) مع خوادم IMAP وSMTP الخاصة بنا.
أوبونتونظام تشغيل خادم حديث مفتوح المصدر يعتمد على Linux والذي يدعم كافة البنية التحتية لدينا.
وايلد داكمكتبة خادم IMAP – راجع ملاحظاتها على إزالة تكرار المرفقات و دعم بروتوكول IMAP.
تحسين تشفير sqlite3 المتعددمكتبة API سريعة وبسيطة لـ Node.js للتفاعل مع SQLite3 برمجيًا.
قوالب البريد الإلكترونيإطار عمل بريد إلكتروني صديق للمطورين لإنشاء رسائل بريد إلكتروني مخصصة ومعاينتها وإرسالها (على سبيل المثال إشعارات الحساب والمزيد).
json-sql-مُحسَّنمنشئ استعلامات SQL باستخدام صيغة Mongo. هذا يوفر وقت فريق التطوير لدينا، إذ يمكننا الاستمرار في الكتابة بصيغة Mongo عبر كامل المجموعة، مع نهج مستقل عن قواعد البيانات. ويساعد أيضًا على تجنب هجمات حقن SQL باستخدام معلمات الاستعلام.
مفتش مخططات knexأداة SQL لاستخراج معلومات حول مخطط قاعدة البيانات الحالي. هذا يسمح لنا بالتحقق بسهولة من صحة جميع المؤشرات والجداول والأعمدة والقيود وغيرها. 1:1 كما ينبغي أن تكون. حتى أننا كتبنا مساعدات آلية لإضافة أعمدة وفهرسات جديدة عند إجراء تغييرات على مخططات قاعدة البيانات (مع تنبيهات أخطاء مفصلة للغاية أيضًا).
كنيكسمنشئ استعلامات SQL الذي نستخدمه فقط لترحيل قواعد البيانات والتحقق من صحة المخطط من خلال knex-schema-inspector.
الماندرينأوتوماتيكي i18n ترجمة العبارات مع دعم Markdown باستخدام واجهة برمجة تطبيقات ترجمة Google Cloud.
الاتصال عبر mxحزمة Node.js لحل وإنشاء اتصالات مع خوادم MX ومعالجة الأخطاء.
بي ام 2مدير عملية إنتاج Node.js مع موازن التحميل المدمج (مُضبوطة بدقة (للأداء).
خادم smtpمكتبة خادم SMTP – نستخدمها لتبادل البريد الإلكتروني ("MX") وخوادم SMTP الصادرة.
ImapTestأداة مفيدة لاختبار خوادم IMAP وفقًا للمعايير وتوافق بروتوكول IMAP مع مواصفات RFC. تم إنشاء هذا المشروع بواسطة برج الحمام فريق (خادم IMAP وPOP3 مفتوح المصدر نشط منذ يوليو 2002). اختبرنا خادم IMAP الخاص بنا على نطاق واسع باستخدام هذه الأداة.

يمكنك العثور على مشاريع أخرى نستخدمها في كود المصدر الخاص بنا على GitHub.

مقدمي الخدمات

مزودغاية
كلاود فليرمزود DNS، وفحوصات الصحة، وموازنات التحميل، وتخزين النسخ الاحتياطية باستخدام كلاود فلير R2.
المحيط الرقمياستضافة خادم مخصص وقواعد بيانات مُدارة.
فولتراستضافة خادم مخصص.
حزمة البياناتاستضافة خادم مخصص.

أفكار

مبادئ

تم تصميم خدمة إعادة توجيه البريد الإلكتروني وفقًا للمبادئ التالية:

  1. يجب أن تكون دائمًا صديقة للمطورين، ومركزة على الأمان والخصوصية، وشفافة.
  2. الالتزام بـ MVC, يونكس, KISS, DRY, YAGNI, اثني عشر عاملًا, شفرة أوكام، و طعام الكلاب
  3. استهدف الأشخاص الذين يعملون بجد واجتهاد مربحة من الرامن مطور

التجارب

ملخص؛ في نهاية المطاف، فإن استخدام تخزين الكائنات المتوافق مع S3 و/أو الجداول الافتراضية ليس ممكنًا من الناحية الفنية لأسباب تتعلق بالأداء وهو عرضة للخطأ بسبب قيود الذاكرة.

لقد أجرينا بعض التجارب التي أدت إلى حل SQLite النهائي كما ناقشنا أعلاه.

كان أحد هذه الحلول هو محاولة استخدام rclone وSQLite مع طبقة تخزين متوافقة مع S3.

قادتنا هذه التجربة إلى فهم واكتشاف الحالات الحدية المحيطة بـ rclone وSQLite بشكل أكبر. VFS الاستخدام:

  • إذا قمت بتمكين --vfs-cache-mode writes العلم مع rclone، ثم ستكون عمليات القراءة على ما يرام، ولكن سيتم تخزين عمليات الكتابة مؤقتًا.
    • إذا كان لديك عدة خوادم IMAP موزعة عالميًا، فسيتم إيقاف تشغيل ذاكرة التخزين المؤقت عبرها ما لم يكن لديك كاتب واحد ومستمعون متعددون (على سبيل المثال، نهج النشر/الاشتراك).
    • هذا أمر معقد بشكل لا يصدق، وإضافة أي تعقيد إضافي مثل هذا سيؤدي إلى المزيد من نقاط الفشل الفردية.
    • لا يدعم موفرو التخزين المتوافقون مع S3 التغييرات الجزئية للملفات - مما يعني أن أي تغيير في .sqlite سيؤدي الملف إلى تغيير كامل وإعادة تحميل قاعدة البيانات.
    • حلول أخرى مثل rsync موجودة، لكنها لا تركز على سجل الكتابة المسبقة ("WAL") الدعم - لذلك انتهينا من مراجعة Litestream. لحسن الحظ، فإن استخدامنا للتشفير يشفر بالفعل WAL ملفاتنا، لذا لسنا بحاجة للاعتماد على Litestream في ذلك. مع ذلك، لم نكن واثقين بعد من استخدام Litestream في الإنتاج، ولدينا بعض الملاحظات أدناه حول ذلك.
    • باستخدام هذا الخيار --vfs-cache-mode writes (ال فقط طريقة استخدام SQLite rclone (للكتابة) ستحاول نسخ قاعدة البيانات بأكملها من البداية في الذاكرة - التعامل مع صندوق بريد واحد بحجم 10 جيجابايت أمر جيد، ومع ذلك فإن التعامل مع صناديق بريد متعددة ذات سعة تخزين عالية للغاية سيؤدي إلى تعرض خوادم IMAP لقيود الذاكرة و ENOMEM الأخطاء، وأخطاء التجزئة، وفساد البيانات.
  • إذا حاولت استخدام SQLite الطاولات الافتراضية (على سبيل المثال باستخدام s3db) لكي تتمكن من حفظ البيانات على طبقة تخزين متوافقة مع S3، فسوف تواجه العديد من المشكلات الأخرى:
    • ستكون عمليات القراءة والكتابة بطيئة للغاية حيث سيتعين الوصول إلى نقاط نهاية واجهة برمجة التطبيقات S3 باستخدام HTTP GET, PUT, HEAD، و POST طُرق.
    • أظهرت اختبارات التطوير أن تجاوز عدد السجلات من 500 ألف إلى مليون سجل على الإنترنت عبر الألياف الضوئية لا يزال محدودًا بمعدل الكتابة والقراءة لموفري الخدمة المتوافقين مع S3. على سبيل المثال، قام مطورونا بتشغيل for حلقات للقيام بكل من SQL المتتالية INSERT البيانات، وتلك التي كتبت كميات كبيرة من البيانات. في كلتا الحالتين، كان الأداء بطيئًا بشكل مذهل.
    • طاولات افتراضية لا يمكن أن يكون لها فهارس, ALTER TABLE البيانات، و آخر القيود - مما يؤدي إلى تأخيرات تصل إلى 1-2 دقيقة أو أكثر اعتمادًا على كمية البيانات.
    • تم تخزين الكائنات دون تشفير ولم يتوفر دعم التشفير الأصلي بسهولة.
  • لقد استكشفنا أيضًا استخدام sqlite-s3vfs وهو مشابه مفهوميًا وتقنيًا للنقطة السابقة (لذا فهو يعاني من نفس المشاكل). من الممكن استخدام نموذج مخصص sqlite3 بناء ملفوف بالتشفير مثل wxSQLite3 (التي نستخدمها حاليًا في حلنا أعلاه) من خلال تحرير ملف الإعداد.
  • وكان النهج المحتمل الآخر هو استخدام تمديد متعدد الإرسالومع ذلك، فإن هذا له حد أقصى قدره 32 جيجابايت وسيتطلب عمليات بناء وتطوير معقدة.
  • ALTER TABLE البيانات مطلوبة (لذا فإن هذا يستبعد تمامًا استخدام الجداول الافتراضية). نحتاج إلى ALTER TABLE عبارات من أجل ربطنا مع knex-schema-inspector للعمل بشكل صحيح - مما يضمن عدم تلف البيانات وإمكانية تحويل الصفوف المستردة إلى مستندات صالحة وفقًا لـ mongoose تعريفات المخطط (التي تتضمن القيد ونوع المتغير والتحقق من صحة البيانات التعسفية).
  • توجد جميع المشاريع المتوافقة مع S3 تقريبًا والمتعلقة بـ SQLite في مجتمع المصدر المفتوح في Python (وليس JavaScript الذي نستخدمه في 100% من مجموعتنا).
  • مكتبات الضغط مثل sqlite-zstd (يرى تعليقات) تبدو واعدة، ولكن قد لا يكون جاهزًا للاستخدام الإنتاجي بعد. بدلاً من ذلك، يتم الضغط على جانب التطبيق على أنواع البيانات مثل String, Object, Map, Array, Set، و Buffer سيكون النهج أنظف وأسهل (وأسهل في النقل أيضًا، حيث يمكننا تخزين Boolean العلم أو العمود - أو حتى الاستخدام PRAGMA user_version=1 للضغط أو user_version=0 لعدم وجود ضغط كبيانات تعريفية لقاعدة البيانات).
    • لحسن الحظ، قمنا بالفعل بتطبيق إزالة تكرار المرفقات في تخزين خادم IMAP الخاص بنا - وبالتالي فإن كل رسالة تحتوي على نفس المرفق لن تحتفظ بنسخة من المرفق - بدلاً من ذلك يتم تخزين مرفق واحد لرسائل وموضوعات متعددة في صندوق بريد (ويتم استخدام مرجع أجنبي لاحقًا).
  • يعد مشروع Litestream، وهو حل النسخ الاحتياطي والتكرار لـ SQLite، واعدًا جدًا ومن المرجح أن نستخدمه في المستقبل.
  • يجب أن تكون استعادة النسخ الاحتياطية سلسة وسهلة. باستخدام حل مثل MongoDB مع mongodump و mongoexport ليس الأمر مملًا فحسب، بل إنه يستغرق وقتًا طويلاً ويشتمل على تعقيد في التكوين.
    • قواعد بيانات SQLite تجعل الأمر بسيطًا (إنه ملف واحد).
    • أردنا تصميم حل حيث يمكن للمستخدمين أخذ صندوق البريد الخاص بهم والمغادرة في أي لحظة.
      • أوامر Node.js البسيطة لـ fs.unlink('mailbox.sqlite')) ويتم مسحه نهائيًا من وحدة تخزين القرص.
      • يمكننا أيضًا استخدام واجهة برمجة تطبيقات متوافقة مع S3 مع HTTP DELETE لإزالة اللقطات والنسخ الاحتياطية بسهولة للمستخدمين.
    • كان SQLite هو الحل الأسهل والأسرع والأكثر فعالية من حيث التكلفة.

عدم وجود بدائل

على حد علمنا، لا توجد خدمات بريد إلكتروني أخرى مصممة بهذه الطريقة ولا تعد مفتوحة المصدر.

نحن أعتقد أن هذا قد يكون بسبب إلى خدمات البريد الإلكتروني الحالية التي تحتوي على تقنية قديمة في الإنتاج مع كود السباغيتي 🍝.

معظم مزودي خدمات البريد الإلكتروني الحاليين، إن لم يكن جميعهم، إما مغلقي المصدر أو يعلنون عن كونهم مفتوحي المصدر، لكن في الواقع، فقط واجهتهم الأمامية مفتوحة المصدر.

الجزء الأكثر حساسية في البريد الإلكتروني (التفاعل الفعلي للتخزين/IMAP/SMTP) يتم كل ذلك على الواجهة الخلفية (الخادم)، و لا على الواجهة الأمامية (العميل).

جرب إعادة توجيه البريد الإلكتروني

سجل اليوم في https://forwardemail.net! 🚀