Подробное описание: как мы используем квантовобезопасные зашифрованные почтовые ящики SQLite для нашей безопасной службы электронной почты, ориентированной на конфиденциальность.

В отличие от других почтовых служб , мы гарантируем, что доступ к вашему почтовому ящику всегда будет только у вас .

предисловие

тлдр; Наша служба электронной почты 100% открытый исходный код и ориентированы на конфиденциальность благодаря безопасным и зашифрованным почтовым ящикам SQLite.

Пока мы не запустили Поддержка IMAPмы использовали MongoDB для постоянного хранения данных.

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

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

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

Продолжайте читать, пока мы глубоко погружаемся ниже с сравнение поставщиков услуг электронной почты, как работает наш сервис, наш технологический стек, и более.

Сравнение поставщиков услуг электронной почты

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

В отличие от других поставщиков услуг электронной почты, при пересылке электронной почты вам не нужно платить за хранилище для каждого домена или псевдонима. Хранилище используется всей вашей учетной записью, поэтому, если у вас есть несколько собственных доменных имен и несколько псевдонимов для каждого, мы — идеальное решение для вас. Обратите внимание, что при желании вы все равно можете установить ограничения на хранилище для каждого домена или псевдонима.

Прочитайте сравнение служб электронной почты

Как это работает

  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 Enterprise»❌ Реляционная база данных❌ AGPL и SSPL-1.0
rqliteТолько сеть❌ Реляционная база данныхMIT
dqliteНепроверено и еще не поддерживается?Непроверено и еще не поддерживается?LGPL-3.0-only
PostgreSQLда❌ Реляционная база данныхPostgreSQL (похожий на BSD или MIT)
МарияДБТолько для InnoDB❌ Реляционная база данныхGPLv2 а также BUSL-1.1
ТараканДБФункция только для предприятий❌ Реляционная база данныхBUSL-1.1 и другие

Вот сообщение в блоге, в котором сравниваются несколько вариантов хранения базы данных SQLite в таблице выше.

Безопасность

Мы всегда используем шифрование в состоянии покоя (AES-256), шифрование при передаче (TLS), DNS через HTTPS («DoH») с помощью 🍊 мандарин, а также Склит (ЧаЧа20-Поли1305) шифрование в почтовых ящиках. Кроме того, мы используем двухфакторную аутентификацию на основе токенов (в отличие от SMS, в которой есть подозрения, что атаки «человек посередине»), ротация ключей SSH с отключенным корневым доступом, эксклюзивный доступ к серверам через ограниченные IP-адреса и многое другое.

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

Наша цель — иметь как можно меньше единая точка отказа насколько это возможно.

Почтовые ящики

тлдр; Наши серверы IMAP используют индивидуально зашифрованные базы данных SQLite для каждого из ваших почтовых ящиков.

SQLite — чрезвычайно популярный встроенная база данных – в настоящее время она работает на вашем телефоне и компьютере – и используется почти всеми основными технологиями.

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

Каждая из этих баз данных зашифрована с использованием вашего пароля (который есть только у вас), используя Склит (ЧаЧа20-Поли1305). Это означает, что ваши почтовые ящики индивидуально зашифрованы, автономны, в песочницеи портативный.

Мы настроили SQLite следующим образом: PRAGMA:

PRAGMAЦель
cipher=chacha20ChaCha20-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.

Параллелизм

тлдр; Мы используем rclone а также WebSocket для одновременного чтения и записи в ваши зашифрованные почтовые ящики SQLite.

Читает

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

Независимо от того, к какому IMAP-серверу подключается ваш почтовый клиент, мы хотим, чтобы соединение считывало данные из вашей базы данных в режиме реального времени со 100% точностью:

  • Это достигается с помощью rclone с --vfs-cache-mode off (по умолчанию).

  • Вместо использования локального дискового кэша кеш считывается непосредственно с удаленного монтирования (вашей базы данных) в режиме реального времени.

  • Если локальный файл не найден, это означает, что rclone не удалось смонтировать или возникла проблема. В этом случае мы используем WebSocket резервное копирование для чтения (что немного снижает производительность, но сохраняет целостность службы).

  • Каждый из наших серверов настроен на согласованное монтирование и в режиме реального времени предупреждает нас о любых ошибках.

Пишет

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

Мы рассматривали такие варианты, как litestream, rqlite, а также dqlite ниже – однако ни один из них не удовлетворял нашим требованиям.

Для выполнения записи с упреждающей записью ("WAL") включено — нам нужно убедиться, что за это отвечает только один сервер («Основной»). WAL радикально ускоряет параллелизм и позволяет одному писателю и нескольким читателям.

Основной работает на серверах данных с смонтированными томами, содержащими зашифрованные почтовые ящики. С точки зрения распространения вы можете рассмотреть все отдельные серверы IMAP, стоящие за imap.forwardemail.net быть вторичными серверами («Вторичные»).

Мы осуществляем двустороннюю связь с Вебсокеты:

  • Первичные серверы используют экземпляр WSх WebSocketServer сервер.
  • Вторичные серверы используют экземпляр WSх WebSocket клиент, который обернут веб-сокет, как обещано а также повторное подключение-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 для хранения (или у своего провайдера, если указано).
  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, дат, мс, позже и удобной для пользователя поддержкой.
КабинаУдобная для разработчиков библиотека журналов JavaScript и Node.js с учетом безопасности и конфиденциальности.
ПозволятьФреймворк Node.js, который обеспечивает всю нашу архитектуру и инженерное проектирование с помощью MVC и многого другого.
МонгоБДРешение для базы данных NoSQL, которое мы используем для хранения всех других данных за пределами почтовых ящиков (например, вашей учетной записи, настроек, доменов и конфигураций псевдонимов).
МангустаМоделирование объектных документов MongoDB («ODM»), которое мы используем во всем нашем стеке. Мы написали специальные помощники, которые позволяют нам просто продолжать использовать Мангуст с SQLite 🎉
Node.jsNode.js — это кроссплатформенная среда выполнения JavaScript с открытым исходным кодом, в которой выполняются все наши серверные процессы.
Почтовая программа заметокПакет Node.js для отправки электронной почты, создания соединений и многого другого. Мы являемся официальным спонсором данного проекта.
РедисБаза данных в памяти для кэширования, каналов публикации/подписки и запросов DNS через HTTPS.
SQLite3MultipleCiphersРасширение шифрования для SQLite, позволяющее шифровать все файлы базы данных (включая журнал упреждающей записи ("WAL"), журнал, откат, …).
SQLiteStudioРедактор Visual SQLite (который вы также можете использовать) для тестирования, загрузки и просмотра почтовых ящиков разработки.
SQLiteВстроенный уровень базы данных для масштабируемого, автономного, быстрого и отказоустойчивого хранилища IMAP.
Спам сканерИнструмент Node.js для защиты от спама, фильтрации электронной почты и предотвращения фишинга (наша альтернатива Спам-убийца а также рспамд).
мандаринЗапросы DNS через HTTPS с помощью Node.js и кэширование с использованием Redis, что обеспечивает глобальную согласованность и многое другое.
ТандербердНаша команда разработчиков использует это (и рекомендует) как предпочтительный почтовый клиент для использования с пересылкой электронной почты.
UTMНаша команда разработчиков использует это создание виртуальных машин для iOS и macOS для тестирования различных почтовых клиентов (параллельно) с нашими серверами IMAP и SMTP.
УбунтуСовременная серверная операционная система на базе Linux с открытым исходным кодом, которая обеспечивает работу всей нашей инфраструктуры.
WildDuckБиблиотека сервера IMAP – см. примечания к ней на дедупликация вложений а также Поддержка протокола IMAP.
лучше-sqlite3-множественные шифрыБыстрая и простая библиотека API для Node.js для программного взаимодействия с SQLite3.
email-шаблоныУдобная для разработчиков платформа электронной почты для создания, предварительного просмотра и отправки пользовательских электронных писем (например, уведомлений об учетной записи и т. д.).
json-sqlПостроитель SQL-запросов с использованием синтаксиса в стиле Mongo. Это экономит время нашей команды разработчиков, поскольку мы можем продолжать писать в стиле Mongo для всего стека, используя агностический подход к базе данных. Это также помогает избежать атак с внедрением SQL-кода с помощью параметров запроса.
Knex-схема-инспекторУтилита SQL для извлечения информации о существующей схеме базы данных. Это позволяет нам легко проверить, что все индексы, таблицы, столбцы, ограничения и т. д. действительны и верны. 1:1 с тем, какими они должны быть. Мы даже написали автоматические помощники для добавления новых столбцов и индексов в случае внесения изменений в схемы базы данных (с чрезвычайно подробным оповещением об ошибках).
КнексПостроитель SQL-запросов, который мы используем только для миграции баз данных и проверки схемы через knex-schema-inspector.
мандаринАвтоматический i18n перевод фраз с поддержкой Markdown с помощью API облачного перевода Google.
MX-подключениеПакет Node.js для разрешения и установления соединений с серверами MX и обработки ошибок.
pm2Менеджер производственного процесса Node.js со встроенным балансировщиком нагрузки (точно настроенный за производительность).
smtp-серверБиблиотека SMTP-серверов – мы используем ее для нашего почтового обмена («MX») и исходящих SMTP-серверов.
ИмапТестПолезный инструмент для тестирования серверов IMAP на соответствие эталонным тестам и совместимости протокола IMAP со спецификацией RFC. Этот проект был создан компанией Голубятня team (активный сервер IMAP и POP3 с открытым исходным кодом с июля 2002 г.). Мы тщательно протестировали наш IMAP-сервер с помощью этого инструмента.

Вы можете найти другие проекты, которые мы используем в наш исходный код на GitHub.

Провайдеры

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

Мысли

Принципы

Электронная почта для пересылки разработана в соответствии со следующими принципами:

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

Эксперименты

тлдр; В конечном итоге использование S3-совместимого объектного хранилища и/или виртуальных таблиц технически невозможно по соображениям производительности и подвержено ошибкам из-за ограничений памяти.

Мы провели несколько экспериментов, которые привели к нашему окончательному решению SQLite, как обсуждалось выше.

Одним из них была попытка использовать клонировать и 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, вы столкнетесь с еще несколькими проблемами:
    • Чтение и запись будут чрезвычайно медленными, поскольку конечные точки API S3 необходимо будет использовать HTTP. GET, PUT, HEAD, а также POST методы.
    • Тесты разработки показали, что превышение 500–1 млн записей в оптоволоконном Интернете по-прежнему ограничено пропускной способностью записи и чтения для 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-совместимый API с HTTP. DELETE чтобы легко удалять снимки и резервные копии для пользователей.
    • SQLite был самым простым, быстрым и экономичным решением.

Отсутствие альтернатив

Насколько нам известно, никакие другие почтовые службы не разработаны таким образом и не имеют открытого исходного кода.

Мы думаю, это может быть из-за к существующим службам электронной почты, использующим устаревшие технологии с код спагетти 🍝.

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

Самая чувствительная часть электронной почты (фактическое взаимодействие хранилища/IMAP/SMTP) все делается на внутреннем сервере (сервере), и нет на внешнем интерфейсе (клиенте).

Попробуйте переслать электронную почту

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