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

Предисловие

Important

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

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

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

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

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

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

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

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

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

Читать сравнение почтовых сервисов

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

  1. Используя свой почтовый клиент, такой как Apple Mail, Thunderbird, Gmail или Outlook, вы подключаетесь к нашим защищенным серверам IMAP, используя свое имя пользователя и пароль:
  • Ваше имя пользователя — это ваш полный псевдоним с вашим доменом, например, hello@example.com.
  • Ваш пароль генерируется случайным образом и отображается только в течение 30 секунд после нажатия кнопки «Сгенерировать пароль» из раздела Моя учётная запись Домены Псевдонимы.
  1. После подключения ваш почтовый клиент отправит Команды протокола IMAP на наш IMAP-сервер для синхронизации вашего почтового ящика. Это включает в себя написание и хранение черновиков писем, а также другие действия, которые вы можете выполнять (например, отмечать письма как важные или как спам/нежелательную почту).

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

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

  • Когда вы подключаетесь к нашему IMAP-серверу с помощью почтового клиента, ваш пароль шифруется в памяти и используется для чтения и записи в ваш почтовый ящик. Доступ к вашему почтовому ящику и запись в него возможны только с этим паролем. Имейте в виду, что, поскольку этот пароль известен только вам, только вы** можете читать и писать в свой почтовый ящик при доступе к нему. При следующей попытке почтового клиента запросить почту или синхронизироваться ваши новые сообщения будут перенесены из этого временного почтового ящика и сохранены в вашем файле почтового ящика с использованием предоставленного вами пароля. Обратите внимание, что этот временный почтовый ящик впоследствии будет очищен и удален, так что сообщения останутся только в вашем защищенном паролем почтовом ящике.

  • Если вы подключены к протоколу IMAP (например, используете почтовый клиент, такой как Apple Mail или Thunderbird), нам не нужно записывать данные во временное дисковое хранилище. Вместо этого извлекается и используется ваш зашифрованный пароль IMAP, хранящийся в памяти. В режиме реального времени, когда сообщение пытается быть доставлено вам, мы отправляем WebSocket-запрос всем серверам IMAP, спрашивая, есть ли у них активный сеанс для вас (это этап извлечения), а затем передаем этот зашифрованный пароль, хранящийся в памяти. Поэтому нам не нужно записывать данные во временный почтовый ящик, мы можем записывать данные в ваш настоящий зашифрованный почтовый ящик, используя ваш зашифрованный пароль.

  1. Резервные копии ваших зашифрованных почтовых ящиков создаются ежедневно. Вы также можете запросить новую резервную копию в любое время или скачать последнюю из них из раздела Моя учётная запись Домены Псевдонимы. Если вы решите перейти на другой почтовый сервис, вы сможете легко перенести, скачать, экспортировать и удалить свои почтовые ящики и резервные копии в любое время.

Технологии

Базы данных

Мы рассмотрели другие возможные уровни хранения базы данных, однако ни один из них не удовлетворял нашим требованиям так, как SQLite:

База данных Шифрование в состоянии покоя Sandboxed Почтовые ящики Лицензия Used Everywhere
SQLite ✅ Да с SQLite3MultipleCiphers ✅ Общественное достояние
MongoDB "Available in MongoDB Enterprise only" ❌ Реляционная база данных ❌ AGPL и SSPL-1.0 :х:
rqlite Network only ❌ Реляционная база данных MIT :х:
dqlite Untested and not yet supported? Untested and not yet supported? LGPL-3.0-only :х:
PostgreSQL Yes ❌ Реляционная база данных PostgreSQL (аналогично BSD или MIT) :х:
MariaDB For InnoDB only ❌ Реляционная база данных GPLv2 и BUSL-1.1 :х:
CockroachDB Enterprise-only feature ❌ Реляционная база данных BUSL-1.1 и другие :х:

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

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

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

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

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

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

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

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

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

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

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

PRAGMA Цель
cipher=chacha20 ChaCha20-Poly1305 SQLite database encryption. Для получения более подробной информации см. better-sqlite3-multiple-ciphers в разделе Projects.
key="****************" Это ваш расшифрованный пароль, хранящийся только в памяти, который передаётся через IMAP-подключение вашего почтового клиента на наш сервер. Для каждого сеанса чтения и записи создаются и закрываются новые экземпляры базы данных (для обеспечения изоляции и изоляции).
journal_model=WAL Журнал предварительной записи ("WAL") which boosts performance and allows concurrent read access.
busy_timeout=5000 Предотвращает ошибки блокировки записи while other writes are taking place.
synchronous=NORMAL Увеличивает долговечность транзакций without data corruption risk.
foreign_keys=ON Обеспечивает принудительное использование ссылок на внешние ключи (например, связи между таблицами). By default this is not turned on in SQLite, но для проверки достоверности и целостности данных ее следует включить.
encoding='UTF-8' Default encoding для использования с целью обеспечения работоспособности разработчика.

Все остальные значения по умолчанию взяты из SQLite, как указано в официальная документация PRAGMA.

Параллелизм

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

Читает

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

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

Записывает

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

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

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

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

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

  • Основные серверы используют экземпляр сервера WebSocketServer сервера ws.
  • Вторичные серверы используют экземпляр клиента WebSocket сервера ws, обёрнутый вебсокет-как-обещано и повторное подключение-websocket. Эти две обёртки обеспечивают повторное подключение WebSocket и возможность отправки и получения данных для определённых операций записи в базу данных.

Резервные копии

tldr; Резервное копирование ваших зашифрованных почтовых ящиков выполняется ежедневно. Вы также можете мгновенно запросить новую резервную копию или скачать последнюю в любое время в разделе Моя учётная запись Домены Псевдонимы.

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

Обратите внимание, что мы используем команду VACUUM INTO, а не встроенную команду backup, поскольку при изменении страницы во время выполнения команды backup её придётся начать заново. Команда VACUUM INTO создаст снимок текущего состояния. Подробнее см. комментарии к командам GitHub и Хакерские новости.

Кроме того, мы используем VACUUM INTO вместо backup, поскольку команда backup оставит базу данных незашифрованной на короткий период времени, пока не будет вызвана rekey (для получения более подробной информации см. комментарий на GitHub).

Вторичный сервер даст указание первичному серверу по соединению WebSocket выполнить резервное копирование, а первичный сервер получит команду на выполнение этого и впоследствии выполнит следующее:

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

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

В настоящее время для каждого почтового ящика хранится только одна резервная копия, но в будущем мы можем предложить восстановление на определенный момент времени («PITR»).

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

Высокая производительность поиска достигается благодаря FTS5 и sqlite-regex.

Значения Date сохраняются в почтовых ящиках SQLite как строки ISO 8601 через Date.prototype.toISOString (с часовым поясом UTC для корректной работы сравнений на равенство).

Индексы также сохраняются для всех свойств, которые есть в поисковых запросах.

Проекты

Ниже представлена таблица с описанием проектов, которые мы используем в нашем исходном коде и процессе разработки (в алфавитном порядке):

Проект Цель
Ansible Платформа автоматизации DevOps для простого обслуживания, масштабирования и управления всем нашим парком серверов.
Bree Планировщик заданий для Node.js и JavaScript с cron, датами, ms, later и удобной для пользователя поддержкой.
Cabin Удобная для разработчиков библиотека журналирования JavaScript и Node.js, ориентированная на безопасность и конфиденциальность.
Lad Фреймворк Node.js, на котором базируется вся наша архитектура и инженерное проектирование с использованием MVC и других основ.
MongoDB Решение базы данных NoSQL, которое мы используем для хранения всех остальных данных за пределами почтовых ящиков (например, вашей учетной записи, настроек, доменов и конфигураций псевдонимов).
Mongoose Объектно-документное моделирование (ODM) MongoDB, которое мы используем во всем нашем стеке. Мы написали специальные вспомогательные функции, которые позволяют нам просто продолжать использовать Mongoose с SQLite 🎉
Node.js Node.js — это кроссплатформенная среда выполнения JavaScript с открытым исходным кодом, которая запускает все наши серверные процессы.
Nodemailer Пакет Node.js для отправки электронных писем, создания связей и многого другого. Мы являемся официальным спонсором этого проекта.
Redis База данных в памяти для кэширования, каналов публикации/подписки и запросов DNS по HTTPS.
SQLite3MultipleCiphers Расширение шифрования для SQLite, позволяющее шифровать целые файлы базы данных (включая журнал предварительной записи ("WAL"), журнал, откат и т. д.).
SQLiteStudio Визуальный редактор SQLite (который вы также можете использовать) для тестирования, загрузки и просмотра почтовых ящиков разработки.
SQLite Встроенный уровень базы данных для масштабируемого, автономного, быстрого и отказоустойчивого хранилища IMAP.
Spam Scanner Инструмент Node.js для борьбы со спамом, фильтрации электронной почты и предотвращения фишинга (наша альтернатива Spam Assassin и rspamd).
Tangerine Запросы DNS через HTTPS с использованием Node.js и кэширование с использованием Redis, что обеспечивает глобальную согласованность и многое другое.
Thunderbird Наша команда разработчиков использует его (и рекомендует) как предпочтительный почтовый клиент для пересылки электронной почты.
UTM Наша команда разработчиков использует эти виртуальные машины для iOS и macOS для тестирования различных почтовых клиентов (параллельно) с нашими серверами IMAP и SMTP.
Ubuntu Современная серверная операционная система на базе Linux с открытым исходным кодом, которая обеспечивает работу всей нашей инфраструктуры.
WildDuck Библиотека сервера IMAP – см. примечания к attachment de-duplication и IMAP protocol support.
better-sqlite3-multiple-ciphers Быстрая и простая API-библиотека для Node.js для программного взаимодействия с SQLite3.
email-templates Удобная для разработчиков платформа электронной почты, позволяющая создавать, просматривать и отправлять пользовательские письма (например, уведомления об учетной записи и многое другое).
json-sql-enhanced Конструктор SQL-запросов с синтаксисом в стиле Mongo. Это экономит время нашей команды разработчиков, поскольку мы можем продолжать писать в стиле Mongo для всего стека, используя подход, не зависящий от базы данных. Это также помогает избежать атак SQL-инъекций благодаря использованию параметров запроса.
knex-schema-inspector Утилита SQL для извлечения информации о существующей схеме базы данных. Это позволяет нам легко проверить корректность всех индексов, таблиц, столбцов, ограничений и т.д. и их соответствие 1:1 требованиям. Мы даже написали автоматизированные помощники для добавления новых столбцов и индексов при внесении изменений в схемы базы данных (с очень подробными оповещениями об ошибках).
knex Конструктор SQL-запросов, который мы используем только для миграции баз данных и проверки схемы через knex-schema-inspector.
mandarin Автоматический перевод фразы i18n с поддержкой Markdown с использованием Google Cloud Translation API.
mx-connect Пакет Node.js для разрешения и установления соединений с серверами MX и обработки ошибок.
pm2 Менеджер производственных процессов Node.js со встроенным балансировщиком нагрузки (fine-tuned для производительности).
smtp-server Библиотека сервера SMTP — мы используем ее для нашего почтового обмена («MX») и исходящих SMTP-серверов.
ImapTest Полезный инструмент для тестирования IMAP-серверов на соответствие эталонным тестам и спецификации RFC. Этот проект был создан командой [Dovecot](https://en.wikipedia.org/wiki/Dovecot_\(software\) (активный сервер IMAP и POP3 с открытым исходным кодом с июля 2002 года). Мы провели тщательное тестирование нашего IMAP-сервера с помощью этого инструмента.

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

Поставщики

Поставщик Цель
Cloudflare Поставщик DNS, проверки работоспособности, балансировщики нагрузки и резервное хранилище с использованием Cloudflare R2.
Digital Ocean Выделенный серверный хостинг и управляемые базы данных.
Vultr Хостинг выделенного сервера.
DataPacket Хостинг выделенного сервера.

Мысли

Принципы

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

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

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

tldr; В конечном счете, использование 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 уровне хранения, вы столкнетесь с рядом других проблем:

  • Чтение и запись будут крайне медленными, поскольку к конечным точкам API S3 необходимо будет обращаться с помощью HTTP-методов .sqlite0, .sqlite1, .sqlite2 и .sqlite3.

  • Тесты разработки показали, что превышение от 500 тыс. до 1 млн записей по оптоволоконному интернету по-прежнему ограничено пропускной способностью записи и чтения к S3-совместимым провайдерам. Например, наши разработчики запускали циклы .sqlite4 как для последовательных SQL-запросов .sqlite5, так и для пакетной записи больших объёмов данных. В обоих случаях производительность была поразительно низкой. * Виртуальные таблицы не могут иметь индексов, операторов .sqlite6 и .sqlite7 .sqlite8, что приводит к задержкам до 1-2 минут и более в зависимости от объёма данных.

  • Объекты хранились в незашифрованном виде, а встроенная поддержка шифрования отсутствует.

  • Мы также исследовали использование .sqlite9, который концептуально и технически аналогичен предыдущему пункту (и поэтому имеет те же проблемы). Одним из возможных подходов было бы использование специальной сборки rsync0, обёрнутой шифрованием, например, rsync1 (которую мы сейчас используем в нашем решении выше) через rsync2.

  • Другим потенциальным подходом было использование rsync3, однако он имеет ограничение в 32 ГБ и потребует сложных задач по сборке и разработке. * Обязательны операторы rsync4 (что полностью исключает использование виртуальных таблиц). Операторы rsync5 необходимы для корректной работы нашего хука с rsync6, что гарантирует сохранность данных и преобразование извлекаемых строк в корректные документы в соответствии с определениями нашей схемы rsync7 (включая проверку ограничений, типов переменных и произвольных данных).

  • Практически все S3-совместимые проекты, связанные с SQLite в сообществе разработчиков ПО с открытым исходным кодом, написаны на Python (а не на JavaScript, который мы используем на 100%).

  • Библиотеки сжатия, такие как rsync8 (см. rsync9), выглядят многообещающе, но __PROTECTED_LINK_189__0. Вместо этого сжатие на стороне приложения для таких типов данных, как __PROTECTED_LINK_189__1, __PROTECTED_LINK_189__2, __PROTECTED_LINK_189__3, __PROTECTED_LINK_189__4, __PROTECTED_LINK_189__5 и __PROTECTED_LINK_189__6, будет более чистым и простым подходом (и его также проще переносить, поскольку мы могли бы хранить флаг или столбец __PROTECTED_LINK_189__7 – или даже использовать __PROTECTED_LINK_189__8 __PROTECTED_LINK_189__9 для сжатия или __PROTECTED_LINK_190__0 для отказа от сжатия в качестве метаданных базы данных).

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

  • Не хочу дискредитировать автора(ов), поскольку мы ценим их работу и вклад в развитие открытого исходного кода уже более десяти лет, однако, судя по реальному использованию, существуют __PROTECTED_LINK_190__1 и __PROTECTED_LINK_190__2.

  • Восстановление из резервной копии должно быть простым и беспроблемным. Использование такого решения, как MongoDB, с __PROTECTED_LINK_190__3 и __PROTECTED_LINK_190__4 не только утомительно, но и требует много времени и сложной настройки.

  • Базы данных SQLite упрощают этот процесс (это один файл).

  • Мы хотели разработать решение, позволяющее пользователям в любой момент забрать свой почтовый ящик и уйти.

  • Простые команды Node.js для __PROTECTED_LINK_190__5 безвозвратно удаляют его с диска. * Аналогичным образом, мы можем использовать совместимый с S3 API с HTTP __PROTECTED_LINK_190__6 для легкого удаления снимков и резервных копий для пользователей.

  • SQLite оказался самым простым, быстрым и экономичным решением.

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

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

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

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

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

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

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