תיבות דואר מוצפנות של SQLite לפרטיות שלך
בניגוד לשירותי דוא"ל אחרים , אנו מבטיחים שרק לך תהיה גישה לתיבת הדואר שלך בכל עת.
- דף חיפוש
- תוכן העניינים
הַקדָמָה
tldr; שירות המייל שלנו הוא 100% קוד פתוח וממוקד פרטיות באמצעות תיבות דואר SQLite מאובטחות ומוצפנות.
עד שהשקנו תמיכה ב-IMAP, השתמשנו ב-MongoDB לצרכי אחסון הנתונים המתמידים שלנו.
הטכנולוגיה הזו מדהימה ואנחנו עדיין משתמשים בה היום - אבל כדי לקבל הצפנה במצב מנוחה עם MongoDB אתה צריך להשתמש בספק שמציע MongoDB Enterprise, כגון Digital Ocean או Mongo Atlas - או לשלם עבור רישיון ארגוני (ו לאחר מכן צריך לעבוד עם חביון צוות המכירות).
הצוות שלנו ב העברת דוא"ל היה זקוק לפתרון אחסון ידידותי למפתחים, ניתן להרחבה, אמין ומוצפן עבור תיבות דואר IMAP. כמפתחי קוד פתוח, באמצעות טכנולוגיה אתה צריך לשלם דמי רישיון כדי לקבל את תכונת ההצפנה במנוחה הייתה נגד העקרונות שלנו – וכך התנסנו, חקרנו ופיתחנו פתרון חדש מאפס כדי לפתור את הצרכים הללו.
במקום להשתמש במסד נתונים משותף לאחסון תיבות הדואר שלך, אנו מאחסנים ומצפינים בנפרד את תיבות הדואר שלך עם הסיסמה שלך (שרק לך יש). שירות הדואר האלקטרוני שלנו כל כך מאובטח שאם תשכח את הסיסמה שלך, תאבד את תיבת הדואר שלך (וצריך להתאושש עם גיבויים לא מקוונים או להתחיל מחדש).
המשך לקרוא כשאנחנו צוללים לעומק למטה עם א השוואה בין ספקי שירותי דואר אלקטרוני, איך השירות שלנו עובד, מחסנית הטכנולוגיה שלנו, ועוד.
השוואה בין ספקי שירותי דואר אלקטרוני
אנחנו ספק שירותי הדואר האלקטרוני היחיד בקוד פתוח וממוקד פרטיות המאחסן תיבות דואר מוצפנות של SQLite בנפרד, מציע דומיינים, כינויים ומשתמשים ללא הגבלה, ויש לו תמיכה יוצאת ב-SMTP, IMAP ו-POP3:
בניגוד לספקי דוא"ל אחרים, אינך צריך לשלם עבור אחסון על בסיס דומיין או כינוי עם העבר דוא"ל. האחסון משותף על פני כל החשבון שלך - כך שאם יש לך מספר שמות דומיין מותאמים אישית וכינויים מרובים בכל אחד מהם, אז אנחנו הפתרון המושלם עבורך. שים לב שאתה עדיין יכול לאכוף מגבלות אחסון אם תרצה על בסיס לכל דומיין או כינוי.
קרא השוואת שירותי דואר אלקטרוני
איך זה עובד
-
באמצעות לקוח הדוא"ל שלך כגון Apple Mail, Thunderbird, Gmail או Outlook - אתה מתחבר למאובטח שלנו IMAP שרתים המשתמשים בשם המשתמש והסיסמה שלך:
- שם המשתמש שלך הוא הכינוי המלא שלך עם הדומיין שלך כגון
hello@example.com
. - הסיסמה שלך נוצרת באופן אקראי ומוצגת לך רק למשך 30 שניות כאשר אתה לוחץ צור סיסמה מ החשבון שלי דומיינים כינויים.
- שם המשתמש שלך הוא הכינוי המלא שלך עם הדומיין שלך כגון
-
לאחר החיבור, לקוח הדוא"ל שלך ישלח פקודות פרוטוקול IMAP לשרת ה-IMAP שלנו כדי לשמור על סנכרון תיבת הדואר שלך. זה כולל כתיבה ואחסון של טיוטות דוא"ל ופעולות אחרות שאתה עשוי לעשות (למשל, תווית דוא"ל כחשובה או סימון דוא"ל כדואר זבל/דואר זבל).
-
שרתי חילופי דואר (הידועים בכינויים שרתי "MX") מקבלים דוא"ל נכנס חדש ומאחסנים אותו בתיבת הדואר שלך. כשזה יקרה לקוח הדואר האלקטרוני שלך יקבל הודעה ויסנכרן את תיבת הדואר שלך. שרתי חילופי הדואר שלנו יכולים להעביר את הדוא"ל שלך לנמען אחד או יותר (כולל webhooks), אחסן את הדוא"ל שלך עבורך באחסון ה-IMAP המוצפן שלך אצלנו, או שניהם!
מעוניינים ללמוד עוד? לקרוא כיצד להגדיר העברת דוא"ל, כיצד פועל שירות החלפת הדואר שלנו, או הצג המדריכים שלנו.
-
מאחורי הקלעים, עיצוב אחסון הדוא"ל המאובטח שלנו פועל בשתי דרכים כדי לשמור על תיבות הדואר שלך מוצפנות ונגישות רק לך:
-
כאשר דואר חדש מתקבל עבורך משולח, שרתי חילופי הדואר שלנו כותבים לתיבת דואר בודדת, זמנית ומוצפנת עבורך.
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!
-
כאשר אתה מתחבר לשרת ה-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!
-
-
גיבויים של תיבות הדואר המוצפנות שלך נעשים מדי יום. אתה יכול גם לבקש גיבוי חדש בכל עת או להוריד את הגיבוי האחרון מ החשבון שלי דומיינים כינויים. אם תחליט לעבור לשירות דוא"ל אחר, תוכל להעביר בקלות, להוריד, לייצא ולנקות את תיבות הדואר והגיבויים שלך בכל עת.
טכנולוגיות
מאגרי מידע
בדקנו שכבות אחסון אפשריות אחרות של מסדי נתונים, אולם אף אחת לא סיפקה את הדרישות שלנו כמו SQLite:
מאגר מידע | הצפנה במנוחה | ארגז חול תיבות דואר | רישיון | בשימוש בכל מקום |
---|---|---|---|---|
SQLite ⭐ | ✅ כן עם SQLite3MultipleCiphers | ✅ | ✅ תחום ציבורי | ✅ |
MongoDB | ❌ "זמין ב-MongoDB Enterprise בלבד" | ❌ מסד נתונים יחסי | ❌ AGPL ו SSPL-1.0 | ❌ |
rqlite | ❌ רשת בלבד | ❌ מסד נתונים יחסי | ✅ MIT | ❌ |
dqlite | ❌ לא נבדק ועדיין לא נתמך? | ❌ לא נבדק ועדיין לא נתמך? | ✅ LGPL-3.0-only | ❌ |
PostgreSQL | ✅ כן | ❌ מסד נתונים יחסי | ✅ PostgreSQL (דומה ל BSD אוֹ MIT ) | ❌ |
MariaDB | ✅ עבור InnoDB בלבד | ❌ מסד נתונים יחסי | ✅ GPLv2 ו BUSL-1.1 | ❌ |
ג'וקDB | ❌ תכונה ארגונית בלבד | ❌ מסד נתונים יחסי | ❌ BUSL-1.1 ואחרים | ❌ |
הנה א פוסט בלוג המשווה מספר אפשרויות אחסון של מסדי נתונים של SQLite בטבלה למעלה.
בִּטָחוֹן
בכל עת אנו משתמשים הצפנה במנוחה (AES-256), הצפנה במעבר (TLS), DNS דרך HTTPS ("DoH") באמצעות 🍊 מַנדָרִינָה, ו sqleet (ChaCha20-Poly1305) הצפנה בתיבות דואר. בנוסף אנו משתמשים באימות דו-גורמי מבוסס אסימון (בניגוד ל-SMS שחשוד איש-באמצע-התקפות), מפתחות SSH מסובבים עם גישת שורש מושבתת, גישה בלעדית לשרתים דרך כתובות IP מוגבלות ועוד.
במקרה של א התקפת עוזרת רעה או עובד נוכל מספק צד שלישי, עדיין ניתן לפתוח את תיבת הדואר שלך רק עם הסיסמה שנוצרת. היה סמוך ובטוח, אנחנו לא מסתמכים על ספקי צד שלישי אחרים מלבד ספקי שרתי התלונות SOC Type 2 שלנו של Cloudflare, Digital Ocean ו-Vultr.
המטרה שלנו היא שיהיו כמה שפחות נקודת כשל אחת ככל האפשר.
תיבות דואר
tldr; שרתי ה-IMAP שלנו משתמשים במסדי נתונים מוצפנים של SQLite עבור כל אחת מתיבות הדואר שלך.
SQLite הוא פופולרי מאוד מסד נתונים משובץ - הוא פועל כעת בטלפון ובמחשב שלך - ומשמש כמעט את כל הטכנולוגיות העיקריות.
לדוגמה, בשרתים המוצפנים שלנו יש תיבת דואר של מסד נתונים של SQLite עבור linux@example.com
, info@example.com
, hello@example.com
וכן הלאה – אחד לכל כא .sqlite
קובץ מסד הנתונים. אנחנו גם לא קוראים לקבצי מסד הנתונים עם כתובת הדואר האלקטרוני - במקום זאת אנו משתמשים ב-BSON ObjectID וב-UUIDs ייחודיים שנוצרו שאינם חולקים למי שייכת תיבת הדואר או באיזו כתובת דוא"ל היא נמצאת (למשל. 353a03f21e534321f5d6e267.sqlite
).
כל אחד מבסיסי הנתונים הללו מוצפן בעצמו באמצעות הסיסמה שלך (שרק לך יש). sqleet (ChaCha20-Poly1305). משמעות הדבר היא שתיבות הדואר שלך מוצפנות בנפרד, עצמאיות, ארגז חול, ונייד.
כוונון עדין של SQLite עם הדברים הבאים PRAGMA:
PRAGMA | מַטָרָה |
---|---|
cipher=chacha20 | הצפנת מסד נתונים של ChaCha20-Poly1305 SQLite. התייחסות better-sqlite3-multiple-ciphers תַחַת פרויקטים לתובנה נוספת. |
key="****************" | זוהי הסיסמה המפוענחת בלבד בזיכרון המועברת דרך חיבור ה-IMAP של לקוח הדוא"ל שלך לשרת שלנו. מופעי מסד נתונים חדשים נוצרים ונסגרים עבור כל סשן קריאה וכתיבה (על מנת להבטיח ארגז חול ובידוד). |
journal_model=WAL | Write-ahead-log ("WAL") מה שמגביר את הביצועים ומאפשר גישה לקריאה במקביל. |
busy_timeout=5000 | מונע שגיאות נעילת כתיבה בעוד כתיבה אחרת מתרחשת. |
synchronous=NORMAL | מגביר את עמידות העסקאות ללא סיכון שחיתות נתונים. |
foreign_keys=ON | אוכפת שהפניות למפתח זר (למשל קשר מטבלה אחת לאחרת) נאכפות. כברירת מחדל זה לא מופעל ב-SQLite, אך לצורך אימות ושלמות הנתונים יש להפעיל אותו. |
encoding='UTF-8' | קידוד ברירת מחדל להשתמש כדי להבטיח שפיות מפתח. |
כל ברירות המחדל האחרות הן מ-SQLite כפי שצוין מה- תיעוד רשמי של PRAGMA.
במקביל
tldr; אנו משתמשים
WebSocket
לקריאה וכתיבה במקביל לתיבות הדואר המוצפנות של SQLite.
קורא
לקוח הדוא"ל שלך בטלפון שלך עשוי לפתור imap.forwardemail.net
לאחת מכתובות ה-IP Digital Ocean שלנו - ולקוח שולחן העבודה שלך עשוי לפתור כתובת IP נפרדת משל אחרת ספק לְגַמרֵי.
לא משנה לאיזה שרת IMAP מתחבר לקוח הדוא"ל שלך, אנו רוצים שהחיבור יקרא ממסד הנתונים שלך בזמן אמת עם 100% דיוק. זה נעשה באמצעות WebSockets.
כותב
הכתיבה למסד הנתונים שלך היא קצת שונה - מכיוון ש- SQLite הוא מסד נתונים משובץ ותיבת הדואר שלך חיה בקובץ בודד כברירת מחדל.
בדקנו אפשרויות כגון litestream
, rqlite
, ו dqlite
להלן - אולם אף אחד מאלה לא עמד בדרישות שלנו.
כדי לבצע כתיבה עם רישום-לפני כן ("WAL") מופעל - עלינו לוודא שרק שרת אחד ("ראשי") אחראי לעשות זאת. WAL מאיץ בצורה דרסטית את המקבילות ומאפשר כותב אחד ומספר קוראים.
ה-Primary פועל על שרתי הנתונים עם אמצעי האחסון המורכבים המכילים את תיבות הדואר המוצפנות. מנקודת מבט של הפצה, אתה יכול לשקול את כל שרתי ה-IMAP הבודדים שמאחוריהם imap.forwardemail.net
להיות שרתים משניים ("משניים").
אנו משיגים תקשורת דו כיוונית עם WebSockets:
- שרתים ראשיים משתמשים במופע של wsשל
WebSocketServer
שרת. - שרתים משניים משתמשים במופע של wsשל
WebSocket
לקוח שעטוף בו websocket-כמו-מובטח ו reconnecting-websocket. שתי העטיפות הללו מבטיחות שהWebSocket
מתחבר מחדש ויכול לשלוח ולקבל נתונים עבור כתיבת מסד נתונים ספציפיים.
גיבויים
tldr; גיבויים של תיבות הדואר המוצפנות שלך נעשים מדי יום. אתה יכול גם לבקש גיבוי חדש באופן מיידי או להוריד את הגיבוי האחרון בכל עת מ החשבון שלי דומיינים כינויים.
עבור גיבויים, אנו פשוט מפעילים את SQLite VACUUM INTO
פקודה כל יום במהלך עיבוד פקודות IMAP, הממנף את הסיסמה המוצפנת שלך מחיבור IMAP בזיכרון. גיבויים מאוחסנים אם לא מזוהה גיבוי קיים או אם SHA-256 hash השתנה בקובץ בהשוואה לגיבוי האחרון.
שימו לב שאנו משתמשים ב- VACUUM INTO
פקודה בניגוד למובנה backup
פקודה כי אם דף שונה במהלך א backup
פעולת הפקודה, אז היא צריכה להתחיל מחדש. ה VACUUM INTO
הפקודה תצלם תמונת מצב. ראה הערות אלה על GitHub ו חדשות האקר לתובנה נוספת.
בנוסף אנו משתמשים VACUUM INTO
בניגוד ל backup
, בגלל ה backup
הפקודה תשאיר את מסד הנתונים לא מוצפן למשך תקופה קצרה עד rekey
מופעל (ראה GitHub זה תגובה לתובנה).
המשני ינחה את היסוד על WebSocket
חיבור לביצוע הגיבוי - והראשי יקבל את הפקודה לעשות זאת ולאחר מכן:
- התחבר לתיבת הדואר המוצפנת שלך.
- רכשו מנעול כתיבה.
- הפעל מחסום WAL באמצעות
wal_checkpoint(PASSIVE)
. - הפעל את
VACUUM INTO
פקודת SQLite. - ודא שניתן לפתוח את הקובץ המועתק באמצעות הסיסמה המוצפנת (הגנה/הגנת דמה).
- העלה אותו ל-Cloudflare R2 לאחסון (או לספק משלך אם צוין).
זכור שתיבות הדואר שלך מוצפנות - ולמרות שיש לנו הגבלות IP ואמצעי אימות אחרים עבור תקשורת WebSocket - במקרה של שחקן גרוע, אתה יכול להיות סמוך ובטוח שאם לא למטען WebSocket יש את סיסמת ה-IMAP שלך, הוא לא יכול לפתוח את מסד הנתונים שלך .
רק גיבוי אחד מאוחסן לתיבת דואר בשלב זה, אך בעתיד אנו עשויים להציע שחזור נקודת זמן ("PITR").
לחפש
שרתי ה-IMAP שלנו תומכים ב SEARCH
פקודה עם שאילתות מורכבות, ביטויים רגולריים ועוד.
ביצועי חיפוש מהירים הם בזכות FTS5 ו sqlite-regex.
אנחנו מאחסנים Date
ערכים בתיבות הדואר של SQLite as ISO 8601 מחרוזות דרך Date.prototype.toISOString (עם אזור זמן UTC להשוואות שוויון לתפקד כראוי).
מדדים מאוחסנים גם עבור כל הנכסים שנמצאים בשאילתות חיפוש.
פרויקטים
להלן טבלה המתארת פרויקטים שבהם אנו משתמשים בתהליך המקור ובתהליך הפיתוח שלנו (ממוינים בסדר אלפביתי):
פּרוֹיֶקט | מַטָרָה |
---|---|
אנסיבל | פלטפורמת אוטומציה DevOps לתחזוקה, קנה מידה וניהול של כל צי השרתים שלנו בקלות. |
ברי | מתזמן עבודה עבור Node.js ו-JavaScript עם cron, תאריכים, ms, מאוחר יותר ותמיכה ידידותית לאדם. |
תָא | ספריית רישום JavaScript ו-Node.js ידידותית למפתחים תוך מחשבה על אבטחה ופרטיות. |
בָּחוּר | מסגרת Node.js אשר מפעילה את כל הארכיטקטורה והתכנון ההנדסי שלנו עם MVC ועוד. |
MongoDB | פתרון מסד הנתונים של NoSQL שבו אנו משתמשים לאחסון כל שאר הנתונים מחוץ לתיבות הדואר (למשל החשבון שלך, הגדרות, דומיינים ותצורות כינוי). |
נְמִיָה | מודל מסמכי אובייקט MongoDB ("ODM") בו אנו משתמשים בכל הערימה שלנו. כתבנו עוזרים מיוחדים שמאפשרים לנו פשוט להמשיך להשתמש נמיה עם SQLite 🎉 |
Node.js | Node.js היא סביבת זמן ריצה של JavaScript חוצה פלטפורמות בקוד פתוח, המריץ את כל תהליכי השרת שלנו. |
דואר הערות | חבילת Node.js לשליחת מיילים, יצירת קשרים ועוד. אנחנו נותנים חסות רשמית לפרויקט הזה. |
Redis | מסד נתונים בזיכרון לאחסון במטמון, פרסום/הרשמה לערוצים ו-DNS על פני בקשות HTTPS. |
SQLite3MultipleCiphers | תוסף הצפנה עבור SQLite כדי לאפשר הצפנת קבצי מסד נתונים שלמים (כולל ה-write-ahead-log ("WAL"), יומן, חזרה לאחור, ...). |
SQLiteStudio | עורך SQLite חזותי (שאפשר גם להשתמש בו) כדי לבדוק, להוריד ולהציג תיבות דואר פיתוח. |
SQLite | שכבת מסד נתונים משובצת לאחסון IMAP ניתן להרחבה, עצמאי, מהיר ועמיד. |
סורק דואר זבל | Node.js אנטי ספאם, סינון דואר אלקטרוני וכלי למניעת דיוג (החלופה שלנו ל מתנקש ספאם ו rspamd). |
מַנדָרִינָה | DNS על פני בקשות HTTPS עם Node.js ושמירת מטמון באמצעות Redis - מה שמבטיח עקביות גלובלית ועוד. |
Thunderbird | צוות הפיתוח שלנו משתמש בזה (וממליץ גם על זה) בתור לקוח הדוא"ל המועדף לשימוש עם העבר דוא"ל. |
UTM | צוות הפיתוח שלנו משתמש במכונות וירטואליות ליצירת iOS ו-macOS כדי לבדוק לקוחות דוא"ל שונים (במקביל) עם שרתי ה-IMAP וה-SMTP שלנו. |
אובונטו | מערכת הפעלה מודרנית מבוססת לינוקס מבוססת לינוקס המניעה את כל התשתית שלנו. |
ברווז בר | ספריית שרת IMAP - ראה את ההערות שלה בנושא ביטול כפילות של קבצים מצורפים ו תמיכה בפרוטוקול IMAP. |
better-sqlite3-מרובים-צפנים | ספריית API מהירה ופשוטה עבור Node.js לאינטראקציה עם SQLite3 באופן פרוגרמטי. |
תבניות אימייל | מסגרת דוא"ל ידידותית למפתחים ליצירה, תצוגה מקדימה ושליחת אימיילים מותאמים אישית (למשל התראות חשבון ועוד). |
json-sql | בונה שאילתות SQL באמצעות תחביר בסגנון מונגו. זה חוסך זמן לצוות הפיתוח שלנו מכיוון שאנו יכולים להמשיך לכתוב בסגנון מונגו על פני כל הערימה בגישה אגנוסטית של מסד נתונים. זה גם עוזר להימנע מהתקפות הזרקת SQL על ידי שימוש בפרמטרים של שאילתה. |
knex-schema-inspector | כלי SQL לחילוץ מידע על סכימת מסד נתונים קיימת. זה מאפשר לנו לאמת בקלות שכל המדדים, הטבלאות, העמודות, האילוצים ועוד תקפים והם 1:1 עם איך שהם צריכים להיות. אפילו כתבנו עוזרים אוטומטיים כדי להוסיף עמודות ואינדקסים חדשים אם נעשו שינויים בסכימות של מסד נתונים (גם עם התראת שגיאה מפורטת ביותר). |
knex | בונה שאילתות SQL שבו אנו משתמשים רק עבור העברות מסדי נתונים ואימות סכימה באמצעות knex-schema-inspector . |
מַנדָרִין | אוֹטוֹמָטִי i18n תרגום ביטויים עם תמיכה בשימוש ב-Markdown Google Cloud Translation API. |
mx-connect | חבילת Node.js לפתרון ויצירת קשרים עם שרתי MX וטיפול בשגיאות. |
אחר הצהריים 2 | מנהל תהליך הייצור של Node.js עם מאזן עומסים מובנה (מכוון עדין לביצועים). |
שרת smtp | ספריית שרתי SMTP - אנו משתמשים בזה עבור חילופי הדואר שלנו ("MX") ושרתי SMTP יוצאים. |
ImapTest | כלי שימושי לבדיקת שרתי IMAP מול מדדים ותאימות פרוטוקול IMAP של מפרט RFC. פרויקט זה נוצר על ידי ה קו יונים צוות (שרת IMAP ו-POP3 פעיל בקוד פתוח מיולי 2002). בדקנו בהרחבה את שרת ה-IMAP שלנו עם הכלי הזה. |
אתה יכול למצוא פרויקטים אחרים שבהם אנו משתמשים קוד המקור שלנו ב-GitHub.
ספקים
ספק | מַטָרָה |
---|---|
Cloudflare | ספק DNS, בדיקות תקינות, מאזני עומסים ואחסון גיבוי באמצעות Cloudflare R2. |
אוקיינוס דיגיטלי | אירוח שרתים ייעודי, אחסון חסימת SSD ומסדי נתונים מנוהלים. |
Vultr | אירוח שרת ייעודי ואחסון חסימת SSD. |
מחשבות
עקרונות
העבר דוא"ל עוצב על פי העקרונות הבאים:
- היה תמיד ידידותי למפתחים, ממוקד אבטחה ופרטיות ושקוף.
- לדבוק MVC, יוניקס, KISS, DRY, YAGNI, 12 פקטור, סכין הגילוח של אוקאם, ו הפצה לפני הפצה
- כוון את השחורים, עם המגפיים, ו ראמן-רווחי מפתח
ניסויים
tldr; בסופו של דבר שימוש באחסון אובייקטים תואם S3 ו/או בטבלאות וירטואליות אינם אפשריים מבחינה טכנית מסיבות ביצועים ונוטים לשגיאות עקב מגבלות זיכרון.
עשינו כמה ניסויים שהובילו לפתרון SQLite הסופי שלנו כפי שנדון לעיל.
אחד מהם היה לנסות להשתמש rclone ו- SQLite יחד עם שכבת אחסון תואמת S3.
הניסוי הזה הוביל אותנו להבין ולגלות מקרי קצה סביב rclone, SQLite ו VFS נוֹהָג:
- אם תפעיל
--vfs-cache-mode writes
דגל עם rclone, אז הקריאה תהיה בסדר, אולם הכתיבה תישמר במטמון.- אם יש לך שרתי IMAP מרובים המופצים ברחבי העולם, המטמון יהיה כבוי ביניהם אלא אם יש לך כותב יחיד ומאזינים מרובים (למשל גישת פאב/משנה).
- זה מורכב להפליא והוספת כל מורכבות נוספת כזו תגרום ליותר נקודות כשל בודדות.
- ספקי אחסון תואמי S3 אינם תומכים בשינויים חלקיים של קבצים - כלומר כל שינוי של
.sqlite
הקובץ יביא לשינוי מוחלט ולהעלאה מחדש של מסד הנתונים. - פתרונות אחרים כמו
rsync
קיימים, אבל הם לא מתמקדים ב-write-ahead-log ("WAL") תמיכה - אז בסופו של דבר בדקנו את Litestream. למרבה המזל, השימוש בהצפנה שלנו כבר מצפין את WAL קבצים עבורנו, אז אנחנו לא צריכים להסתמך על Litestream בשביל זה. עם זאת, עדיין לא היינו בטוחים ב-Litestream לשימוש בייצור ויש לנו כמה הערות בהמשך. - שימוש באפשרות זו של
--vfs-cache-mode writes
(ה רק דרך להשתמש ב- SQLite overrclone
לכתיבה) ינסה להעתיק את כל מסד הנתונים מאפס בזיכרון - טיפול בתיבת דואר אחת של 10 ג'יגה-בתים זה בסדר, אולם טיפול במספר תיבות דואר עם אחסון גבוה במיוחד יגרום לשרתי IMAP להיתקל במגבלות זיכרון.ENOMEM
שגיאות, תקלות פילוח ושחיתות נתונים.
- אם אתה מנסה להשתמש ב-SQLite טבלאות וירטואליות (למשל באמצעות s3db) כדי שהנתונים יהיו חיים בשכבת אחסון תואמת S3, תיתקלו בכמה בעיות נוספות:
- הקריאה והכתיבה יהיו איטיים במיוחד מכיוון שנקודות קצה S3 API יצטרכו להיפגע עם HTTP
GET
,PUT
,HEAD
, וPOST
שיטות. - מבחני פיתוח הראו שחרוג מ-500K-1M+ רשומות באינטרנט סיבים עדיין מוגבל על ידי תפוקת הכתיבה והקריאה לספקים תואמים S3. לדוגמה, המפתחים שלנו רצו
for
לולאות לעשות את שניהם SQL רציףINSERT
הצהרות וכאלה שכתבו כמויות גדולות של נתונים. בשני המקרים הביצועים היו איטיים להפליא. - שולחנות וירטואליים לא יכול להיות אינדקסים,
ALTER TABLE
הצהרות, ו אַחֵר מגבלות - מה שמוביל לעיכובים של למעלה מ-1-2 דקות או יותר בהתאם לכמות הנתונים. - אובייקטים אוחסנו ללא מוצפן ואין תמיכה בהצפנה מקורית זמינה.
- הקריאה והכתיבה יהיו איטיים במיוחד מכיוון שנקודות קצה S3 API יצטרכו להיפגע עם HTTP
- חקרנו גם שימוש sqlite-s3vfs שדומה מבחינה רעיונית וטכנית לנקודת התבליט הקודמת (ולכן יש לה את אותן בעיות). אפשרות תהיה להשתמש במנהג
sqlite3
לבנות עטוף בהצפנה כגון wxSQLite3 (בה אנו משתמשים כעת בפתרון שלנו למעלה) דרך עריכת קובץ ההגדרות. - גישה פוטנציאלית נוספת הייתה להשתמש ב- הרחבה מרובהעם זאת, יש לכך מגבלה של 32 GB ויצריך כאבי ראש מורכבים של בנייה ופיתוח.
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'))
והוא נמחק לצמיתות מאחסון הדיסק. - אנו יכולים להשתמש באופן דומה ב-API תואם S3 עם HTTP
DELETE
כדי להסיר בקלות תמונות וגיבויים עבור משתמשים.
- פקודות Node.js פשוטות ל
- SQLite היה הפתרון הפשוט, המהיר והמשתלם ביותר.
חוסר אלטרנטיבות
למיטב ידיעתנו, אף שירותי דוא"ל אחרים לא מתוכננים כך וגם אינם בקוד פתוח.
אָנוּ חושב שאולי זה נובע לשירותי דואר אלקטרוני קיימים עם טכנולוגיה מדור קודם בייצור עם קוד ספגטי 🍝.
רוב אם לא כל ספקי שירותי הדוא"ל הקיימים הם בקוד סגור או מפרסמים כקוד פתוח, אבל במציאות רק הקצה הקדמי שלהם הוא קוד פתוח.
החלק הרגיש ביותר באימייל (אינטראקציית האחסון/IMAP/SMTP בפועל) הכל נעשה בקצה האחורי (שרת), ו לֹא בחזית (לקוח).
נסה את העבר אימייל
הירשם היום ב- https://forwardemail.net! 🚀