Глибоке занурення: як ми використовуємо квантово безпечні зашифровані поштові скриньки SQLite для нашої безпечної служби електронної пошти, орієнтованої на конфіденційність

На відміну від інших служб електронної пошти , ми гарантуємо, що лише ви маєте постійний доступ до своєї поштової скриньки .

Передмова

tldr; Наша служба електронної пошти 100% відкритий код і зосереджено на конфіденційності через безпечні та зашифровані поштові скриньки SQLite.

Поки ми не запустили Підтримка IMAP, ми використовували MongoDB для постійного зберігання даних.

Ця технологія дивовижна, і ми все ще використовуємо її сьогодні, але для того, щоб мати шифрування у спокої з MongoDB, вам потрібно використовувати постачальника, який пропонує MongoDB Enterprise, наприклад Digital Ocean або Mongo Atlas, або заплатити за корпоративну ліцензію (і згодом доведеться працювати із затримкою команди продажів).

Наша команда в Переслати електронну пошту потрібне зручне для розробників, масштабоване, надійне та зашифроване рішення для зберігання поштових скриньок IMAP. Як розробники з відкритим вихідним кодом використання технології, яка потребує сплати ліцензійної плати, щоб отримати функцію шифрування у спокої, було проти наші принципи – тому ми експериментували, досліджували та з нуля розробили нове рішення для вирішення цих потреб.

Замість того, щоб використовувати спільну базу даних для зберігання ваших поштових скриньок, ми окремо зберігаємо та шифруємо ваші поштові скриньки за допомогою вашого пароля (який є лише у вас). Наша служба електронної пошти настільки безпечна, що якщо ви забудете свій пароль, ви втратите свою поштову скриньку (і потрібно відновити за допомогою офлайн-резервних копій або почати спочатку).

Продовжуйте читати, оскільки ми глибоко зануримося нижче з a порівняння постачальників послуг електронної пошти, як працює наш сервіс, наш стек технологій, і більше.

Порівняння постачальників послуг електронної пошти

Ми єдиний постачальник послуг електронної пошти з 100% відкритим вихідним кодом, орієнтований на конфіденційність, який зберігає індивідуально зашифровані поштові скриньки SQLite, пропонує необмежену кількість доменів, псевдонімів і користувачів і підтримує вихідні SMTP, IMAP і POP3:

На відміну від інших постачальників електронної пошти, вам не потрібно платити за зберігання для кожного домену чи псевдоніма за допомогою Forward Email. Обсяг пам’яті використовується для всього облікового запису, тож якщо у вас є кілька користувацьких доменних імен і кілька псевдонімів для кожного, ми станемо ідеальним рішенням для вас. Зауважте, що за бажанням ви все ще можете застосувати обмеження на пам’ять для кожного домену чи псевдоніма.

Прочитайте порівняння послуг електронної пошти

Як це працює

  1. Використовуючи свій поштовий клієнт, наприклад Apple Mail, Thunderbird, Gmail або Outlook, ви підключаєтесь до нашого безпечного доступу IMAP сервери за допомогою вашого імені користувача та пароля:

    • Ваше ім’я користувача – це ваш повний псевдонім із вашим доменом, наприклад hello@example.com.
    • Ваш пароль генерується випадковим чином і відображається лише протягом 30 секунд після натискання Згенерувати пароль від Мій рахунок Домени Псевдоніми.
  2. Після підключення ваш поштовий клієнт надішле Команди протоколу IMAP на наш сервер IMAP, щоб синхронізувати вашу поштову скриньку. Це включає написання та зберігання чернеток електронних листів та інші дії, які ви можете виконувати (наприклад, позначити електронний лист як важливий або позначити його як спам/небажану пошту).

  3. Сервери обміну поштою (широко відомі як сервери «MX») отримують нову вхідну електронну пошту та зберігають її у вашій поштовій скриньці. Коли це станеться, ваш поштовий клієнт отримає сповіщення та синхронізує вашу поштову скриньку. Наші сервери обміну поштою можуть пересилати вашу електронну пошту одному або кільком одержувачам (включаючи веб-хуки), зберігати вашу електронну пошту у вашому зашифрованому сховищі IMAP у нас, або обидва!

    Хочете дізнатися більше? Прочитайте як налаштувати пересилання електронної пошти, як працює наша служба обміну поштою, або переглянути наші гіди.

  4. За лаштунками наш безпечний дизайн зберігання електронної пошти працює двома способами, щоб зберегти ваші поштові скриньки зашифрованими та доступними лише вам:

    • Коли ви отримуєте нову пошту від відправника, наші сервери обміну поштою надсилають для вас окрему, тимчасову та зашифровану поштову скриньку.

      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!
      
  5. Резервні копії ваших зашифрованих поштових скриньок виготовляються щодня. Ви також можете будь-коли подати запит на створення нової резервної копії або завантажити останню резервну копію з Мій рахунок Домени Псевдоніми. Якщо ви вирішите перейти на іншу службу електронної пошти, ви можете будь-коли легко перенести, завантажити, експортувати та очистити свої поштові скриньки та резервні копії.

Технології

Бази даних

Ми досліджували інші можливі рівні зберігання бази даних, однак жоден із них не задовольняв наші вимоги настільки, як 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
CockroachDBФункція лише для підприємств❌ Реляційна база данихBUSL-1.1 та інші

Ось а публікація в блозі, яка порівнює кілька варіантів зберігання бази даних SQLite у таблиці вище.

Безпека

Завжди використовуємо шифрування в спокої (AES-256), шифрування в дорозі (TLS), DNS через HTTPS ("DoH") за допомогою 🍊 Мандарин, і sqleet (ChaCha20-Poly1305) шифрування на поштових скриньках. Крім того, ми використовуємо двофакторну автентифікацію на основі токенів (на відміну від SMS, які можуть людина посередині атакує), змінені ключі SSH із вимкненим кореневим доступом, ексклюзивний доступ до серверів через обмежені IP-адреси тощо.

У разі ан напад злої служниці або шахрайський працівник від стороннього постачальника, вашу поштову скриньку все ще можна відкрити лише за допомогою створеного вами пароля. Будьте впевнені, ми не покладаємося на жодних сторонніх постачальників, окрім наших постачальників серверів скарг SOC типу 2 Cloudflare, Digital Ocean і Vultr.

Наша мета — мати якомога менше єдина точка відмов як можна.

Поштові скриньки

tldr; Наші сервери IMAP використовують окремо зашифровані бази даних SQLite для кожної вашої поштової скриньки.

SQLite надзвичайно популярний вбудована база даних – зараз вона працює на вашому телефоні та комп’ютері – і використовується майже всіма основними технологіями.

Наприклад, на наших зашифрованих серверах є поштова скринька бази даних SQLite для linux@example.com, info@example.com, hello@example.com і так далі – по одному для кожного як a .sqlite файл бази даних. Ми також не називаємо файли бази даних адресою електронної пошти – натомість ми використовуємо BSON ObjectID та створені унікальні UUID, які не повідомляють, кому належить поштова скринька або під якою адресою електронної пошти вона знаходиться (наприклад, 353a03f21e534321f5d6e267.sqlite).

Кожна з цих баз даних зашифрована за допомогою вашого пароля (який є лише у вас). sqleet (ChaCha20-Poly1305). Це означає, що ваші поштові скриньки індивідуально зашифровані, самодостатні, пісочниця, і портативний.

Ми налаштували 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.

Паралелізм

tldr; Ми використовуємо rclone і WebSocket для одночасного читання та запису у ваші зашифровані поштові скриньки SQLite.

Читає

Ваш поштовий клієнт на вашому телефоні може вирішити проблему imap.forwardemail.net на одну з наших IP-адрес Digital Ocean – і ваш настільний клієнт може розпізнати окрему IP-адресу з іншої провайдер взагалі.

Незалежно від того, до якого сервера IMAP підключається ваш клієнт електронної пошти, ми хочемо, щоб з’єднання читало вашу базу даних у режимі реального часу зі 100% точністю:

  • Це досягається за допомогою rclone з --vfs-cache-mode off (за замовчуванням).

  • Замість використання кешу локального диска, кеш зчитується безпосередньо з віддаленого монтування (вашої бази даних) у режимі реального часу.

  • Якщо локальний файл не знайдено, це означає, що rclone не вдалося встановити або виникла проблема. У цьому випадку ми використовуємо a WebSocket запасний варіант для читання (що трохи знижує продуктивність, але все ще підтримує цілісність служби).

  • Кожен із наших серверів налаштовано на узгоджене підключення та сповіщає нас у режимі реального часу про будь-які помилки.

Пише

Запис у вашу базу даних дещо відрізняється, оскільки SQLite є вбудованою базою даних і ваша поштова скринька за замовчуванням знаходиться в одному файлі.

Ми досліджували такі варіанти, як litestream, rqlite, і dqlite нижче – проте жоден із них не задовольняв наших вимог.

Для виконання запису за допомогою попереднього запису журналу ("WAL") увімкнено – нам потрібно переконатися, що за це відповідає лише один сервер ("Основний"). WAL суттєво прискорює паралелізм і дозволяє працювати одному автору та декільком читачам.

Основний працює на серверах даних із підключеними томами, що містять зашифровані поштові скриньки. З точки зору розповсюдження, ви можете розглянути всі окремі сервери IMAP imap.forwardemail.net бути вторинними серверами («Secondary»).

Ми здійснюємо двосторонній зв'язок з WebSockets:

  • Основні сервери використовують екземпляр ws's WebSocketServer сервер.
  • Вторинні сервери використовують екземпляр ws's WebSocket клієнт, який загорнутий у websocket-as-promised і reconnecting-websocket. Ці дві обгортки гарантують, що WebSocket повторно підключається та може надсилати та отримувати дані для певних записів бази даних.

Резервні копії

tldr; Резервні копії ваших зашифрованих поштових скриньок створюються щодня. Ви також можете миттєво запросити нову резервну копію або завантажити останню резервну копію в будь-який час з Мій рахунок Домени Псевдоніми.

Для резервного копіювання ми просто запускаємо SQLite VACUUM INTO щодня під час обробки команди IMAP, яка використовує ваш зашифрований пароль із з’єднання IMAP у пам’яті. Резервні копії зберігаються, якщо існуюча резервна копія не виявлена або якщо SHA-256 хеш файлу змінився порівняно з останньою резервною копією.

Зверніть увагу, що ми використовуємо VACUUM INTO команди на відміну від вбудованої backup оскільки якщо сторінку змінено під час a backup командну операцію, тоді її потрібно починати спочатку. The VACUUM INTO команда зробить знімок. Перегляньте ці коментарі на GitHub і Хакерські новини для більшого розуміння.

Додатково використовуємо VACUUM INTO на відміну від backup, тому що backup команда залишить базу даних незашифрованою на короткий період, поки rekey викликається (див. цей GitHub коментар для розуміння).

Другий навчатиме Первинний WebSocket з’єднання для виконання резервного копіювання – і Основний отримає команду на це, а потім:

  1. Підключіться до зашифрованої поштової скриньки.
  2. Отримайте блокування запису.
  3. Запустіть контрольну точку WAL через wal_checkpoint(PASSIVE).
  4. Запустіть VACUUM INTO Команда SQLite.
  5. Переконайтеся, що скопійований файл можна відкрити за допомогою зашифрованого пароля (захист/фіктивний захист).
  6. Завантажте його в Cloudflare R2 для зберігання (або у свого постачальника, якщо вказано).
  7. Стисніть отриманий файл резервної копії за допомогою gzip.
  8. Завантажте його в Cloudflare R2 для зберігання (або у свого постачальника, якщо вказано).

Пам’ятайте, що ваші поштові скриньки зашифровані – і хоча ми використовуємо обмеження IP та інші заходи автентифікації для зв’язку WebSocket – у разі невдалої дії ви можете бути впевнені, що якщо корисне навантаження WebSocket не має вашого пароля IMAP, воно не зможе відкрити вашу базу даних. .

Наразі для кожної поштової скриньки зберігається лише одна резервна копія, але в майбутньому ми можемо запропонувати відновлення на певний момент часу ("PITR").

Наші сервери IMAP підтримують SEARCH команда зі складними запитами, регулярними виразами тощо.

Завдяки швидкому пошуку FTS5 і регулярний вираз sqlite.

Зберігаємо Date значення в поштових скриньках SQLite як ISO 8601 рядки через Date.prototype.toISOString (з часовим поясом UTC для належного функціонування порівняння рівності).

Індекси також зберігаються для всіх властивостей, які є в пошукових запитах.

Проекти

Ось таблиця з описом проектів, які ми використовуємо у вихідному коді та процесі розробки (відсортовані за алфавітом):

Демонструватипризначення
АнсібльПлатформа автоматизації DevOps для легкого обслуговування, масштабування та керування всім нашим парком серверів.
БріПланувальник завдань для Node.js і JavaScript із підтримкою cron, dates, ms, later і зручною для людини.
КабінаЗручна для розробників бібліотека журналів JavaScript і Node.js з урахуванням безпеки та конфіденційності.
ДозволяєФреймворк Node.js, який забезпечує всю нашу архітектуру та інженерний дизайн із MVC тощо.
MongoDBРішення бази даних NoSQL, яке ми використовуємо для зберігання всіх інших даних за межами поштових скриньок (наприклад, ваш обліковий запис, налаштування, домени та конфігурації псевдонімів).
МангустМоделювання об’єктного документа MongoDB («ODM»), яке ми використовуємо в усьому нашому стеку. Ми написали спеціальні помічники, які дозволяють просто продовжувати використовувати Mongoose з SQLite 🎉
Node.jsNode.js — це міжплатформне середовище виконання JavaScript із відкритим кодом, яке запускає всі процеси нашого сервера.
Розсилка нотатокПакет Node.js для надсилання електронних листів, створення з’єднань тощо. Ми є офіційним спонсором цього проекту.
RedisБаза даних у пам’яті для кешування, публікації/підписки на канали та запитів DNS через HTTPS.
SQLite3MultipleCiphersРозширення шифрування для SQLite, яке дозволяє шифрувати цілі файли бази даних (включно з журналом попереднього запису ("WAL»), журнал, відкат, …).
SQLiteStudioВізуальний редактор SQLite (який також можна використовувати) для тестування, завантаження та перегляду поштових скриньок розробки.
SQLiteРівень вбудованої бази даних для масштабованого, автономного, швидкого та стійкого зберігання IMAP.
Сканер спамуІнструмент Node.js для захисту від спаму, фільтрації електронної пошти та запобігання фішингу (наша альтернатива Spam Assassin і rspamd).
МандаринЗапити DNS через HTTPS за допомогою Node.js і кешування за допомогою Redis, що забезпечує глобальну узгодженість і багато іншого.
ThunderbirdНаша команда розробників використовує це (і також рекомендує) як бажаний поштовий клієнт для використання з пересиланням електронної пошти.
UTMНаша команда розробників використовує ці віртуальні машини для iOS і macOS, щоб тестувати різні клієнти електронної пошти (паралельно) з нашими серверами IMAP і SMTP.
UbuntuСучасна серверна операційна система на базі Linux із відкритим вихідним кодом, яка підтримує всю нашу інфраструктуру.
WildDuckБібліотека сервера IMAP – див. примітки до неї дедуплікація вкладень і Підтримка протоколу IMAP.
better-sqlite3-multiple-ciphersШвидка та проста бібліотека API для Node.js для програмної взаємодії з SQLite3.
email-шаблониЗручна для розробників структура електронної пошти для створення, попереднього перегляду та надсилання спеціальних електронних листів (наприклад, сповіщень облікового запису тощо).
json-sqlКонструктор запитів SQL із використанням синтаксису в стилі Mongo. Це економить час нашої команди розробників, оскільки ми можемо продовжувати писати в стилі Mongo по всьому стеку за допомогою підходу до бази даних. Це також допомагає уникнути атак SQL-ін’єкцій за допомогою параметрів запиту.
knex-schema-inspectorУтиліта SQL для отримання інформації про існуючу схему бази даних. Це дозволяє нам легко перевірити, що всі індекси, таблиці, стовпці, обмеження тощо є дійсними та 1:1 як вони повинні бути. Ми навіть написали автоматизовані помічники для додавання нових стовпців та індексів у разі внесення змін до схем бази даних (також із надзвичайно детальним сповіщенням про помилки).
knexКонструктор запитів SQL, який ми використовуємо лише для міграції бази даних і перевірки схеми knex-schema-inspector.
мандаринАвтоматичний i18n переклад фраз із підтримкою використання Markdown Google Cloud Translation API.
mx-connectПакет Node.js для вирішення та встановлення з’єднань із серверами MX і обробки помилок.
pm2Менеджер виробничих процесів Node.js із вбудованим балансувальником навантаження (налаштований для виконання).
smtp-серверБібліотека SMTP-сервера – ми використовуємо її для нашого обміну поштою ("MX") і вихідних SMTP-серверів.
ImapTestКорисний інструмент для перевірки серверів IMAP на відповідність стандартам і RFC-специфікації протоколу IMAP. Цей проект був створений голубник команда (активний сервер IMAP і POP3 з відкритим кодом з липня 2002 р.). Ми ретельно протестували наш сервер IMAP за допомогою цього інструменту.

Ви можете знайти інші проекти, які ми використовуємо наш вихідний код на GitHub.

Провайдери

Провайдерпризначення
ХмараПостачальник DNS, перевірки працездатності, балансувальники навантаження та використання резервного сховища Cloudflare R2.
Цифровий океанВиділений серверний хостинг, блокове сховище SSD і керовані бази даних.
VultrВиділений серверний хостинг і блочне сховище SSD.

Думки

Принципи

Пересилання електронної пошти розроблено відповідно до таких принципів:

  1. Будьте завжди дружніми до розробників, зосереджені на безпеці та конфіденційності та прозорі.
  2. Дотримуватись MVC, Unix, KISS, DRY, YAGNI, Фактор дванадцять, Бритва Оккама, і тестування
  3. Націлюйтеся на уривчасті, початкові та рамен-прибутковий розробник

Експерименти

tldr; Зрештою, використання S3-сумісного сховища об’єктів та/або віртуальних таблиць технічно неможливе з міркувань продуктивності та схильне до помилок через обмеження пам’яті.

Ми провели кілька експериментів, що призвели до нашого остаточного рішення SQLite, як описано вище.

Одним із них було спробувати використати rclone і SQLite разом із S3-сумісним рівнем зберігання.

Цей експеримент привів нас до глибшого розуміння та виявлення граничних випадків, пов’язаних із rclone, SQLite та VFS використання:

  • Якщо ви ввімкнете --vfs-cache-mode writes прапорець із rclone, тоді читання буде нормальним, однак запис буде кешовано.
    • Якщо у вас є кілька серверів IMAP, розповсюджених у всьому світі, кеш буде вимкнено на них, якщо у вас немає одного автора та кількох слухачів (наприклад, підхід pub/sub).
    • Це неймовірно складно, і додавання будь-якої додаткової складності, як це, призведе до збільшення одиничних точок відмови.
    • S3-сумісні постачальники сховищ не підтримують часткові зміни файлів, тобто будь-які зміни в .sqlite призведе до повної зміни та повторного завантаження бази даних.
    • Інші рішення, як rsync існують, але вони не зосереджені на попередньому записі журналу ("WAL") підтримку – тому ми завершили перегляд Litestream. На щастя, наше використання шифрування вже шифрує WAL файли для нас, тому нам не потрібно покладатися на Litestream для цього. Однак ми ще не були впевнені в Litestream для використання у виробництві, і нижче є кілька приміток щодо цього.
    • Використовуючи цей варіант --vfs-cache-mode writes ( тільки спосіб використання SQLite rclone для записів) намагатиметься скопіювати всю базу даних з нуля в пам’яті – обробка однієї поштової скриньки розміром 10 ГБ допустима, однак обробка кількох поштових скриньок із надзвичайно великим об’ємом пам’яті спричинить обмеження пам’яті серверів IMAP і ENOMEM помилки, помилки сегментації та пошкодження даних.
  • Якщо ви спробуєте використовувати SQLite Віртуальні столи (наприклад, використовуючи s3db), щоб мати живі дані на S3-сумісному рівні зберігання, ви зіткнетеся з кількома іншими проблемами:
    • Читання та запис будуть надзвичайно повільними, оскільки кінцеві точки S3 API потрібно буде обробляти за допомогою HTTP GET, PUT, HEAD, і POST методи.
    • Тести розробки показали, що перевищення 500K-1M+ записів у оптоволоконному Інтернеті все ще обмежене пропускною здатністю запису та читання для 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 буде чистішим і простішим підходом (також легше перенести, оскільки ми можемо зберігати a Boolean прапор чи колонка – або навіть використання PRAGMA user_version=1 для стиснення або user_version=0 без стиснення як метаданих бази даних).
    • На щастя, у нашому сховищі сервера IMAP уже реалізовано дедуплікацію вкладень – тому кожне повідомлення з однаковим вкладенням не зберігатиме копію вкладення – натомість одне вкладення зберігається для кількох повідомлень і потоків у поштовій скриньці (і іноземній посилання використовується згодом).
  • Проект Litestream, який є рішенням для реплікації та резервного копіювання SQLite, є дуже перспективним, і ми, швидше за все, будемо використовувати його в майбутньому.
  • Відновлення резервної копії має бути легким і тривіальним. Використовуючи таке рішення, як MongoDB з mongodump і mongoexport не тільки стомлює, але вимагає багато часу та має складність конфігурації.
    • Бази даних SQLite роблять це простим (це один файл).
    • Ми хотіли розробити рішення, за якого користувачі могли б взяти свою поштову скриньку та залишити її в будь-який момент.
      • Прості команди Node.js для fs.unlink('mailbox.sqlite')) і його назавжди стерто з дискового сховища.
      • Так само ми можемо використовувати S3-сумісний API з HTTP DELETE для легкого видалення знімків і резервних копій для користувачів.
    • SQLite був найпростішим, найшвидшим і найвигіднішим рішенням.

Безальтернативність

Наскільки нам відомо, жодні інші служби електронної пошти не розроблені таким чином і не є відкритими.

ми думаю, що це може бути пов'язано до існуючих служб електронної пошти, які використовують застарілу технологію код спагетті 🍝.

Більшість, якщо не всі існуючі постачальники послуг електронної пошти мають закритий вихідний код або рекламуються як відкритий, але насправді тільки їхній інтерфейс є відкритим.

Найбільш чутлива частина електронної пошти (фактична взаємодія сховища/IMAP/SMTP) все виконується на сервері (сервері). ні на передній частині (клієнт).

Спробуйте переслати електронну пошту

Зареєструйтеся сьогодні за адресою https://forwardemail.net! 🚀