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

Предисловие
Important
Наш почтовый сервис — 100% открытый исходный код, он обеспечивает конфиденциальность благодаря безопасным и зашифрованным почтовым ящикам SQLite.
До запуска Поддержка IMAP мы использовали MongoDB для постоянного хранения данных.
Эта технология удивительна, и мы используем ее по сей день, но для того, чтобы использовать шифрование данных в состоянии покоя с помощью MongoDB, вам необходимо обратиться к провайдеру, который предлагает MongoDB Enterprise, например Digital Ocean или Mongo Atlas, или приобрести корпоративную лицензию (и впоследствии смириться с задержками в работе отдела продаж).
Нашей команде Переслать электронное письмо требовалось удобное для разработчиков, масштабируемое, надежное и зашифрованное решение для хранения почтовых ящиков IMAP. Как разработчики с открытым исходным кодом, мы не хотели использовать технологию, требующую оплаты лицензии за шифрование данных в состоянии покоя, поэтому мы провели эксперименты, исследования и разработали новое решение с нуля для решения этих задач.
Вместо того, чтобы использовать общую базу данных для хранения ваших почтовых ящиков, мы храним и шифруем каждый из них индивидуально, используя ваш пароль (который есть только у вас). Наш почтовый сервис настолько безопасен, что если вы забудете пароль, вы потеряете свой почтовый ящик (и вам придётся восстанавливать его с помощью резервных копий в автономном режиме или начинать всё заново).
Продолжайте читать, и ниже мы подробно рассмотрим сравнение поставщиков услуг электронной почты, как работает наш сервис, наш технологический стек и другие.
Сравнение поставщиков услуг электронной почты
Мы являемся единственным поставщиком услуг электронной почты с полностью открытым исходным кодом, ориентированным на конфиденциальность, который хранит индивидуально зашифрованные почтовые ящики SQLite, предлагает неограниченное количество доменов, псевдонимов и пользователей, а также имеет поддержку исходящих сообщений SMTP, IMAP и POP3:
В отличие от других почтовых сервисов, при использовании Forward Email вам не нужно платить за хранилище по каждому домену или псевдониму. Хранилище распределяется по всей вашей учётной записи, поэтому, если у вас несколько доменных имён и несколько псевдонимов для каждого из них, мы — идеальное решение для вас. Обратите внимание, что вы по-прежнему можете устанавливать ограничения на хранилище для каждого домена или псевдонима.
Читать сравнение почтовых сервисов
Как это работает
- Используя свой почтовый клиент, такой как Apple Mail, Thunderbird, Gmail или Outlook, вы подключаетесь к нашим защищенным серверам IMAP, используя свое имя пользователя и пароль:
- Ваше имя пользователя — это ваш полный псевдоним с вашим доменом, например,
hello@example.com
. - Ваш пароль генерируется случайным образом и отображается только в течение 30 секунд после нажатия кнопки «Сгенерировать пароль» из раздела Моя учётная запись Домены Псевдонимы.
-
После подключения ваш почтовый клиент отправит Команды протокола IMAP на наш IMAP-сервер для синхронизации вашего почтового ящика. Это включает в себя написание и хранение черновиков писем, а также другие действия, которые вы можете выполнять (например, отмечать письма как важные или как спам/нежелательную почту).
-
Почтовые серверы (обычно называемые MX-серверами) получают новые входящие письма и сохраняют их в вашем почтовом ящике. При этом ваш почтовый клиент получает уведомление и синхронизирует ваш почтовый ящик. Наши почтовые серверы могут пересылать ваши письма одному или нескольким получателям (включая веб-хуки), сохранять их в вашем зашифрованном IMAP-хранилище у нас, или делать и то, и другое!
Tip
Хотите узнать больше? Прочитайте как настроить пересылку электронной почты, как работает наша служба почтового обмена или просмотрите наши гиды.
- Наша защищенная система хранения электронной почты работает двумя способами, обеспечивая шифрование ваших почтовых ящиков и предоставляя доступ к ним только вам:
-
Когда вам приходит новое письмо от отправителя, наши серверы обмена почтой записывают его в индивидуальный, временный и зашифрованный почтовый ящик для вас.
-
Когда вы подключаетесь к нашему IMAP-серверу с помощью почтового клиента, ваш пароль шифруется в памяти и используется для чтения и записи в ваш почтовый ящик. Доступ к вашему почтовому ящику и запись в него возможны только с этим паролем. Имейте в виду, что, поскольку этот пароль известен только вам, только вы** можете читать и писать в свой почтовый ящик при доступе к нему. При следующей попытке почтового клиента запросить почту или синхронизироваться ваши новые сообщения будут перенесены из этого временного почтового ящика и сохранены в вашем файле почтового ящика с использованием предоставленного вами пароля. Обратите внимание, что этот временный почтовый ящик впоследствии будет очищен и удален, так что сообщения останутся только в вашем защищенном паролем почтовом ящике.
-
Если вы подключены к протоколу IMAP (например, используете почтовый клиент, такой как Apple Mail или Thunderbird), нам не нужно записывать данные во временное дисковое хранилище. Вместо этого извлекается и используется ваш зашифрованный пароль IMAP, хранящийся в памяти. В режиме реального времени, когда сообщение пытается быть доставлено вам, мы отправляем WebSocket-запрос всем серверам IMAP, спрашивая, есть ли у них активный сеанс для вас (это этап извлечения), а затем передаем этот зашифрованный пароль, хранящийся в памяти. Поэтому нам не нужно записывать данные во временный почтовый ящик, мы можем записывать данные в ваш настоящий зашифрованный почтовый ящик, используя ваш зашифрованный пароль.
- Резервные копии ваших зашифрованных почтовых ящиков создаются ежедневно. Вы также можете запросить новую резервную копию в любое время или скачать последнюю из них из раздела Моя учётная запись Домены Псевдонимы. Если вы решите перейти на другой почтовый сервис, вы сможете легко перенести, скачать, экспортировать и удалить свои почтовые ящики и резервные копии в любое время.
Технологии
Базы данных
Мы рассмотрели другие возможные уровни хранения базы данных, однако ни один из них не удовлетворял нашим требованиям так, как 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
выполнить резервное копирование, а первичный сервер получит команду на выполнение этого и впоследствии выполнит следующее:
- Подключитесь к своему зашифрованному почтовому ящику.
- Получите блокировку записи.
- Запустите контрольную точку WAL через
wal_checkpoint(PASSIVE)
. - Выполните команду SQLite
VACUUM INTO
. - Убедитесь, что скопированный файл можно открыть с помощью зашифрованного пароля (защита/фиктивная защита).
- Загрузите его в хранилище 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 | Хостинг выделенного сервера. |
Мысли
Принципы
Пересылка электронной почты разработана в соответствии со следующими принципами:
- Всегда будьте дружелюбны к разработчикам, ориентированы на безопасность и конфиденциальность, а также прозрачны.
- Соблюдайте MVC, Unix, KISS, DRY, YAGNI, Двенадцать факторов, Бритва Оккама и догфудинг
- Ориентируйтесь на разработчиков, которые не любят хаотичного, нестандартного и рамен-прибыльный.
Эксперименты
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-методов
.sqlite
0,.sqlite
1,.sqlite
2 и.sqlite
3. -
Тесты разработки показали, что превышение от 500 тыс. до 1 млн записей по оптоволоконному интернету по-прежнему ограничено пропускной способностью записи и чтения к S3-совместимым провайдерам. Например, наши разработчики запускали циклы
.sqlite
4 как для последовательных SQL-запросов.sqlite
5, так и для пакетной записи больших объёмов данных. В обоих случаях производительность была поразительно низкой. * Виртуальные таблицы не могут иметь индексов, операторов.sqlite
6 и.sqlite
7.sqlite
8, что приводит к задержкам до 1-2 минут и более в зависимости от объёма данных. -
Объекты хранились в незашифрованном виде, а встроенная поддержка шифрования отсутствует.
-
Мы также исследовали использование
.sqlite
9, который концептуально и технически аналогичен предыдущему пункту (и поэтому имеет те же проблемы). Одним из возможных подходов было бы использование специальной сборкиrsync
0, обёрнутой шифрованием, например,rsync
1 (которую мы сейчас используем в нашем решении выше) черезrsync
2. -
Другим потенциальным подходом было использование
rsync
3, однако он имеет ограничение в 32 ГБ и потребует сложных задач по сборке и разработке. * Обязательны операторыrsync
4 (что полностью исключает использование виртуальных таблиц). Операторыrsync
5 необходимы для корректной работы нашего хука сrsync
6, что гарантирует сохранность данных и преобразование извлекаемых строк в корректные документы в соответствии с определениями нашей схемыrsync
7 (включая проверку ограничений, типов переменных и произвольных данных). -
Практически все S3-совместимые проекты, связанные с SQLite в сообществе разработчиков ПО с открытым исходным кодом, написаны на Python (а не на JavaScript, который мы используем на 100%).
-
Библиотеки сжатия, такие как
rsync
8 (см.rsync
9), выглядят многообещающе, но __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! 🚀