Szyfrowane skrzynki pocztowe SQLite dla Twojej prywatności
W przeciwieństwie do innych usług e-mailowych zapewniamy, że tylko Ty masz stały dostęp do swojej skrzynki pocztowej .
- Strona wyszukiwania
- Spis treści
Przedmowa
tldr; Nasza usługa e-mail jest W 100% otwarte i zorientowane na prywatność dzięki bezpiecznym i szyfrowanym skrzynce pocztowej SQLite.
Dopóki nie wystartowaliśmy Obsługa protokołu IMAP, użyliśmy MongoDB do naszych stałych potrzeb w zakresie przechowywania danych.
Ta technologia jest niesamowita i nadal jej używamy – ale aby mieć szyfrowanie w MongoDB, musisz skorzystać z dostawcy oferującego MongoDB Enterprise, takiego jak Digital Ocean lub Mongo Atlas – lub zapłacić za licencję dla przedsiębiorstw (i później muszą pracować nad opóźnieniami zespołu sprzedaży).
Nasz zespół o godz Prześlij dalej e-mail potrzebował przyjaznego dla programistów, skalowalnego, niezawodnego i szyfrowanego rozwiązania do przechowywania skrzynek pocztowych IMAP. Jako twórcy oprogramowania open source korzystanie z technologii wymagającej uiszczenia opłaty licencyjnej, aby móc korzystać z funkcji szyfrowania w stanie spoczynku, było sprzeczne z nasze zasady – dlatego eksperymentowaliśmy, badaliśmy i opracowaliśmy od podstaw nowe rozwiązanie, aby sprostać tym potrzebom.
Zamiast korzystać ze wspólnej bazy danych do przechowywania Twoich skrzynek pocztowych, przechowujemy je indywidualnie i szyfrujemy Twoim hasłem (które masz tylko Ty). Nasza usługa e-mail jest tak bezpieczna, że jeśli zapomnisz hasła, utracisz skrzynkę pocztową (i musisz odzyskać dane za pomocą kopii zapasowych offline lub zacząć od nowa).
Czytaj dalej, gdy zagłębimy się poniżej w porównanie dostawców usług e-mail, jak działa nasz serwis, nasz stos technologii, i więcej.
Porównanie dostawców usług e-mail
Jesteśmy jedynym dostawcą usług e-mail w pełni open source i zorientowanym na prywatność, który przechowuje indywidualnie zaszyfrowane skrzynki pocztowe SQLite, oferuje nieograniczoną liczbę domen, aliasów i użytkowników oraz obsługuje wychodzące SMTP, IMAP i POP3:
W przeciwieństwie do innych dostawców poczty e-mail, w przypadku usługi Forward Email nie musisz płacić za przechowywanie w oparciu o domenę lub alias. Miejsce na dane jest współdzielone na całym koncie – więc jeśli masz wiele niestandardowych nazw domen i wiele aliasów na każdej z nich, jesteśmy dla Ciebie idealnym rozwiązaniem. Pamiętaj, że w razie potrzeby możesz nadal egzekwować limity miejsca na domenę lub alias.
Przeczytaj Porównanie usług e-mail
Jak to działa
-
Korzystając z klienta poczty e-mail, takiego jak Apple Mail, Thunderbird, Gmail lub Outlook – łączysz się z naszym bezpiecznym IMAP serwery korzystające z Twojej nazwy użytkownika i hasła:
- Twoja nazwa użytkownika to pełny alias z Twoją domeną, np
hello@example.com
. - Twoje hasło jest generowane losowo i wyświetlane tylko przez 30 sekund po kliknięciu Wygeneruj hasło z Moje konto Domeny Skróty.
- Twoja nazwa użytkownika to pełny alias z Twoją domeną, np
-
Po nawiązaniu połączenia Twój klient poczty e-mail wyśle wiadomość Polecenia protokołu IMAP do naszego serwera IMAP, aby synchronizować skrzynkę pocztową. Obejmuje to pisanie i przechowywanie wersji roboczych wiadomości e-mail oraz inne czynności, które możesz wykonać (np. oznaczenie wiadomości e-mail jako ważnej lub oznaczenie wiadomości e-mail jako spam/śmieci).
-
Serwery wymiany poczty (powszechnie zwane serwerami „MX”) odbierają nowe przychodzące wiadomości e-mail i przechowują je w Twojej skrzynce pocztowej. Gdy tak się stanie, Twój klient poczty e-mail otrzyma powiadomienie i zsynchronizuje Twoją skrzynkę pocztową. Nasze serwery wymiany poczty mogą przekazywać Twoją pocztę e-mail do jednego lub większej liczby odbiorców (w tym webhooki), przechowuj u nas swoje wiadomości e-mail w zaszyfrowanym magazynie IMAP, lub oba!
Chcesz dowiedzieć się więcej? Czytać jak skonfigurować przekazywanie wiadomości e-mail, jak działa nasza usługa wymiany pocztylub obejrzyj nasi przewodnicy.
-
Za kulisami nasz projekt bezpiecznego przechowywania wiadomości e-mail działa na dwa sposoby, aby Twoje skrzynki pocztowe były szyfrowane i dostępne tylko dla Ciebie:
-
Po otrzymaniu nowej poczty od nadawcy nasze serwery wymiany poczty zapisują ją w indywidualnej, tymczasowej i zaszyfrowanej skrzynce pocztowej.
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!
-
Kiedy łączysz się z naszym serwerem IMAP za pomocą swojego klienta poczty e-mail, Twoje hasło jest następnie szyfrowane w pamięci i używane do odczytu i zapisu w Twojej skrzynce pocztowej. Z Twojej skrzynki pocztowej można czytać i zapisywać tylko przy użyciu tego hasła. Pamiętaj, że ponieważ jesteś jedyną osobą znającą to hasło, tylko ty może czytać i pisać w Twojej skrzynce pocztowej, gdy uzyskujesz do niej dostęp. Następnym razem, gdy Twój klient poczty e-mail będzie próbował odpytać pocztę lub przeprowadzić synchronizację, nowe wiadomości zostaną przeniesione z tymczasowej skrzynki pocztowej i zapisane w rzeczywistym pliku skrzynki pocztowej przy użyciu podanego hasła. Pamiętaj, że ta tymczasowa skrzynka pocztowa jest później czyszczona i usuwana, dzięki czemu wiadomości znajdują się tylko w Twojej skrzynce pocztowej chronionej hasłem.
-
Jeśli jesteś podłączony do protokołu IMAP (np. korzystasz z klienta poczty e-mail, takiego jak Apple Mail lub Thunderbird), nie musimy zapisywać danych na dysku tymczasowym. Zamiast tego zostanie pobrane i użyte Twoje hasło IMAP zaszyfrowane w pamięci. W czasie rzeczywistym, gdy próbujemy dostarczyć Ci wiadomość, wysyłamy żądanie WebSocket do wszystkich serwerów IMAP z pytaniem, czy mają dla Ciebie aktywną sesję (jest to część pobierania), a następnie przekazujemy to dalej zaszyfrowane hasło w pamięci – dzięki temu nie musimy pisać do tymczasowej skrzynki pocztowej, możemy pisać do Twojej rzeczywistej zaszyfrowanej skrzynki pocztowej, używając zaszyfrowanego hasła.
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!
-
-
Kopie zapasowe zaszyfrowanych skrzynek pocztowych są robione codziennie. Możesz także w dowolnym momencie poprosić o utworzenie nowej kopii zapasowej lub pobrać najnowszą kopię zapasową z witryny Moje konto Domeny Skróty. Jeśli zdecydujesz się przejść na inną usługę e-mail, możesz w dowolnym momencie łatwo migrować, pobierać, eksportować i czyścić swoje skrzynki pocztowe i kopie zapasowe.
Technologie
Bazy danych
Zbadaliśmy inne możliwe warstwy przechowywania baz danych, jednak żadna nie spełniła naszych wymagań w takim stopniu jak SQLite:
Baza danych | Szyfrowanie w stanie spoczynku | W piaskownicy Skrzynki pocztowe | Licencja | Używany wszędzie |
---|---|---|---|---|
Sqlite ⭐ | ✅Tak z SQLite3MultipleCiphers | ✅ | ✅ Domena publiczna | ✅ |
MongoDB | ❌ „Dostępne tylko w MongoDB Enterprise” | ❌ Relacyjna baza danych | ❌ AGPL i SSPL-1.0 | ❌ |
rqlite | ❌ Tylko sieć | ❌ Relacyjna baza danych | ✅ MIT | ❌ |
dqlite | ❌ Nieprzetestowany i jeszcze nieobsługiwany? | ❌ Nieprzetestowany i jeszcze nieobsługiwany? | ✅ LGPL-3.0-only | ❌ |
PostgreSQL | ✅ tak | ❌ Relacyjna baza danych | ✅ PostgreSQL (podobny do BSD lub MIT ) | ❌ |
MariaDB | ✅ Tylko dla InnoDB | ❌ Relacyjna baza danych | ✅ GPLv2 oraz BUSL-1.1 | ❌ |
KaraluchDB | ❌ Funkcja dostępna tylko dla przedsiębiorstw | ❌ Relacyjna baza danych | ❌ BUSL-1.1 i inni | ❌ |
Tutaj jest wpis na blogu porównujący kilka opcji przechowywania baz danych SQLite w tabeli powyżej.
Bezpieczeństwo
Cały czas używamy szyfrowanie w stanie spoczynku (AES-256), szyfrowanie w transporcie (TLS), DNS przez HTTPS („DoH”) za pomocą 🍊 Mandarynka, oraz kwadrat (ChaCha20-Poly1305) szyfrowanie skrzynek pocztowych. Dodatkowo stosujemy uwierzytelnianie dwuskładnikowe oparte na tokenach (w przeciwieństwie do SMS-ów, które mogą być podejrzane). ataki typu man-in-the-middle), obrócone klucze SSH z wyłączonym dostępem roota, wyłącznym dostępem do serwerów poprzez zastrzeżone adresy IP i nie tylko.
W przypadku atak złej pokojówki lub nieuczciwego pracownika od zewnętrznego dostawcy, nadal możesz otworzyć swoją skrzynkę pocztową tylko za pomocą wygenerowanego hasła. Rest assured, we don't rely upon any third-party vendors other than our SOC Type 2 complaint server providers of Cloudflare, DataPacket, Digital Ocean, and Vultr.
Naszym celem jest mieć ich jak najmniej pojedynczy punkt awarii jak to możliwe.
Skrzynki pocztowe
tldr; Nasze serwery IMAP korzystają z indywidualnie zaszyfrowanych baz danych SQLite dla każdej Twojej skrzynki pocztowej.
SQLite jest niezwykle popularny wbudowana baza danych – aktualnie działa na Twoim telefonie i komputerze – i wykorzystywane przez prawie wszystkie główne technologie.
Na przykład na naszych zaszyfrowanych serwerach znajduje się skrzynka pocztowa bazy danych SQLite linux@example.com
, info@example.com
, hello@example.com
i tak dalej – po jednym dla każdego jako a .sqlite
plik bazy danych. Nie nazywamy również plików bazy danych adresem e-mail – zamiast tego używamy BSON ObjectID i wygenerowanych unikalnych identyfikatorów UUID, które nie informują, do kogo należy skrzynka pocztowa ani pod jakim adresem e-mail się znajduje (np. 353a03f21e534321f5d6e267.sqlite
).
Każda z tych baz danych jest szyfrowana przy użyciu Twojego hasła (które tylko Ty posiadasz). kwadrat (ChaCha20-Poly1305). Oznacza to, że Twoje skrzynki pocztowe są indywidualnie szyfrowane, samodzielne, piaskownicai przenośny.
Dopracowaliśmy SQLite w następujący sposób PRAGMA:
PRAGMA | Zamiar |
---|---|
cipher=chacha20 | Szyfrowanie bazy danych SQLite ChaCha20-Poly1305. Odniesienie better-sqlite3-multiple-ciphers pod Projektowanie aby uzyskać więcej informacji. |
key="****************" | To jest Twoje odszyfrowane hasło przechowywane wyłącznie w pamięci, które jest przesyłane przez połączenie IMAP Twojego klienta poczty e-mail z naszym serwerem. Dla każdej sesji odczytu i zapisu tworzone są i zamykane nowe instancje bazy danych (w celu zapewnienia piaskownicy i izolacji). |
journal_model=WAL | Dziennik zapisu z wyprzedzeniem („WAL") co zwiększa wydajność i umożliwia równoczesny dostęp do odczytu. |
busy_timeout=5000 | Zapobiega błędom blokady zapisu podczas gdy inne zapisy mają miejsce. |
synchronous=NORMAL | Zwiększa trwałość transakcji bez ryzyka uszkodzenia danych. |
foreign_keys=ON | Wymusza wymuszanie odwołań do klucza obcego (np. relacji z jednej tabeli do drugiej). Domyślnie nie jest to włączone w SQLite, ale w celu sprawdzenia poprawności i integralności danych należy ją włączyć. |
encoding='UTF-8' | Domyślne kodowanie używać, aby zapewnić programistom zdrowy rozsądek. |
Wszystkie pozostałe wartości domyślne pochodzą z SQLite, jak określono w pliku oficjalna dokumentacja PRAGMY.
Konkurencja
tldr; Używamy
WebSocket
do równoczesnych odczytów i zapisów w zaszyfrowanych skrzynkach pocztowych SQLite.
Czyta
Klient poczty e-mail w telefonie może zostać rozwiązany imap.forwardemail.net
na jeden z naszych adresów IP Digital Ocean – a Twój klient stacjonarny może rozpoznać oddzielny adres IP od innego dostawca całkowicie.
Niezależnie od tego, z jakim serwerem IMAP łączy się Twój klient poczty e-mail, chcemy, aby połączenie odczytywało Twoją bazę danych w czasie rzeczywistym ze 100% dokładnością. Odbywa się to poprzez WebSockets.
Pisze
Zapisywanie w bazie danych przebiega nieco inaczej – ponieważ SQLite jest wbudowaną bazą danych, a Twoja skrzynka pocztowa domyślnie znajduje się w jednym pliku.
Rozważaliśmy opcje takie jak litestream
, rqlite
, oraz dqlite
poniżej – jednak żaden z nich nie spełniał naszych wymagań.
Aby wykonać zapisy z rejestrowaniem zapisu z wyprzedzeniem ("WAL„) włączone – musimy upewnić się, że tylko jeden serwer („Podstawowy”) jest za to odpowiedzialny. WAL drastycznie przyspiesza współbieżność i umożliwia jednemu pisarzowi i wielu czytelnikom.
Jednostka podstawowa działa na serwerach danych z zamontowanymi woluminami zawierającymi zaszyfrowane skrzynki pocztowe. Z punktu widzenia dystrybucji można wziąć pod uwagę wszystkie pojedyncze serwery IMAP imap.forwardemail.net
być serwerami dodatkowymi („Dodatkowe”).
Realizujemy dwustronną komunikację z WebSockety:
- Serwery główne korzystają z instancji ws'S
WebSocketServer
serwer. - Serwery dodatkowe korzystają z instancji ws'S
WebSocket
klient, który jest opakowany websocket-zgodnie z obietnicą oraz ponowne łączenie-websocket. Te dwie owijki zapewniają, żeWebSocket
ponownie łączy się i może wysyłać i odbierać dane w ramach określonych zapisów w bazie danych.
Kopie zapasowe
tldr; Kopie zapasowe zaszyfrowanych skrzynek pocztowych są tworzone codziennie. Możesz także natychmiast poprosić o nową kopię zapasową lub pobrać najnowszą kopię zapasową w dowolnym momencie ze strony Moje konto Domeny Skróty.
W przypadku kopii zapasowych po prostu uruchamiamy SQLite VACUUM INTO
polecenie codziennie podczas przetwarzania poleceń IMAP, które wykorzystuje zaszyfrowane hasło z połączenia IMAP w pamięci. Kopie zapasowe są przechowywane, jeśli nie zostanie wykryta żadna istniejąca kopia zapasowa lub jeśli SHA-256 hash w pliku uległ zmianie w porównaniu z najnowszą kopią zapasową.
Zauważ, że używamy VACUUM INTO
polecenie w przeciwieństwie do wbudowanego backup
polecenie, ponieważ jeśli strona zostanie zmodyfikowana podczas a backup
polecenia, to trzeba zacząć od nowa. The VACUUM INTO
polecenie wykona migawkę. Zobacz te komentarze dot GitHub oraz Wiadomości hakerskie aby uzyskać więcej informacji.
Dodatkowo używamy VACUUM INTO
w przeciwieństwie do backup
, ponieważ backup
polecenie pozostawi bazę danych niezaszyfrowaną na krótki okres do rekey
jest wywoływany (zobacz ten GitHub komentarz dla wglądu).
Szkoła Podstawowa będzie instruować Organizację Podstawową w zakresie WebSocket
połączenie w celu wykonania kopii zapasowej – a Podstawowy otrzyma wówczas polecenie, aby to zrobić, a następnie:
- Połącz się ze swoją zaszyfrowaną skrzynką pocztową.
- Zdobądź blokadę zapisu.
- Uruchom punkt kontrolny WAL poprzez
wal_checkpoint(PASSIVE)
. - Uruchom
VACUUM INTO
Polecenie SQLite. - Upewnij się, że skopiowany plik można otworzyć za pomocą zaszyfrowanego hasła (zabezpieczenie/zabezpieczenie fikcyjne).
- Prześlij go do Cloudflare R2 w celu przechowywania (lub u własnego dostawcy, jeśli określono).
Pamiętaj, że Twoje skrzynki pocztowe są szyfrowane — i chociaż mamy ograniczenia IP i inne środki uwierzytelniania dla komunikacji WebSocket — w przypadku złego aktora możesz mieć pewność, że jeśli ładunek WebSocket nie będzie zawierał Twojego hasła IMAP, nie będzie mógł otworzyć Twojej bazy danych .
Obecnie na każdą skrzynkę pocztową przechowywana jest tylko jedna kopia zapasowa, ale w przyszłości możemy zaoferować odzyskiwanie do określonego momentu („PITR").
Szukaj
Nasze serwery IMAP obsługują SEARCH
polecenia ze złożonymi zapytaniami, wyrażeniami regularnymi i nie tylko.
Szybka wydajność wyszukiwania jest dzięki FTS5 oraz sqlite-wyrażenie regularne.
przechowujemy Date
wartości w skrzynkach pocztowych SQLite jako ISO 8601 ciągi przez Date.prototype.toISOString (ze strefą czasową UTC, aby porównania równości działały prawidłowo).
Indeksy są również przechowywane dla wszystkich właściwości występujących w zapytaniach wyszukiwania.
Projektowanie
Oto tabela przedstawiająca projekty, których używamy w naszym kodzie źródłowym i procesie programowania (posortowane alfabetycznie):
Projekt | Zamiar |
---|---|
Ansible | Platforma automatyzacji DevOps do łatwego utrzymywania, skalowania i zarządzania całą naszą flotą serwerów. |
Bree | Harmonogram zadań dla Node.js i JavaScript z cron, date, ms, later i przyjazną dla człowieka obsługą. |
Kabina | Przyjazna dla programistów biblioteka rejestrowania JavaScript i Node.js z myślą o bezpieczeństwie i prywatności. |
Pozwolić | Framework Node.js, który wspiera całą naszą architekturę i projekty inżynieryjne za pomocą MVC i nie tylko. |
MongoDB | Rozwiązanie bazodanowe NoSQL, którego używamy do przechowywania wszystkich innych danych poza skrzynkami pocztowymi (np. Twoje konto, ustawienia, domeny i konfiguracje aliasów). |
Mangusta | Modelowanie dokumentów obiektowych MongoDB („ODM”), którego używamy w całym naszym stosie. Napisaliśmy specjalne pomocniki, które pozwalają nam po prostu kontynuować korzystanie Mangusta z SQLite 🎉 |
Node.js | Node.js to wieloplatformowe środowisko uruchomieniowe JavaScript o otwartym kodzie źródłowym, w którym uruchamiane są wszystkie nasze procesy serwerowe. |
Nodemailer | Pakiet Node.js do wysyłania e-maili, tworzenia połączeń i nie tylko. Jesteśmy oficjalnym sponsorem tego projektu. |
Redisa | Baza danych w pamięci do buforowania, kanałów publikowania/subskrypcji i DNS przez żądania HTTPS. |
SQLite3MultipleCiphers | Rozszerzenie szyfrowania dla SQLite umożliwiające szyfrowanie całych plików bazy danych (w tym dziennika zapisu z wyprzedzeniem („WAL"), dziennik, wycofanie, ...). |
SQLiteStudio | Wizualny edytor SQLite (którego możesz również użyć) do testowania, pobierania i przeglądania skrzynek pocztowych programistów. |
Sqlite | Wbudowana warstwa bazy danych zapewniająca skalowalne, samodzielne, szybkie i odporne przechowywanie IMAP. |
Skaner spamu | Narzędzie antyspamowe, filtrujące pocztę e-mail i zapobiegające phishingowi Node.js (nasza alternatywa dla Zabójca spamu oraz rspamd). |
Mandarynka | DNS przez żądania HTTPS z Node.js i buforowanie przy użyciu Redis – co zapewnia globalną spójność i wiele więcej. |
Ptak piorunowy | Nasz zespół programistów używa tego (i również to zaleca) jako preferowany klient poczty e-mail używany z funkcją przesyłania dalej. |
UTM | Nasz zespół programistów używa tej maszyny wirtualnej do tworzenia maszyn wirtualnych dla iOS i macOS w celu testowania różnych klientów poczty e-mail (równolegle) z naszymi serwerami IMAP i SMTP. |
Ubuntu | Nowoczesny serwerowy system operacyjny typu open source oparty na systemie Linux, który napędza całą naszą infrastrukturę. |
Dzika kaczka | Biblioteka serwerów IMAP – zobacz jej uwagi na deduplikacja załączników oraz Obsługa protokołu IMAP. |
lepsze-sqlite3-wiele-szyfrów | Szybka i prosta biblioteka API dla Node.js do programowej interakcji z SQLite3. |
Szablony wiadomości | Przyjazna dla programistów platforma e-mail do tworzenia, podglądu i wysyłania niestandardowych wiadomości e-mail (np. powiadomień o koncie i nie tylko). |
json-sql | Kreator zapytań SQL wykorzystujący składnię w stylu Mongo. Oszczędza to czas naszego zespołu programistów, ponieważ możemy kontynuować pisanie w stylu Mongo na całym stosie, stosując podejście niezależne od bazy danych. Pomaga także uniknąć ataków polegających na wstrzykiwaniu SQL poprzez użycie parametrów zapytania. |
Inspektor schematu knex | Narzędzie SQL do wyodrębniania informacji o istniejącym schemacie bazy danych. Pozwala nam to łatwo sprawdzić, czy wszystkie indeksy, tabele, kolumny, ograniczenia i inne są prawidłowe i są 1:1 z tym, jak powinny wyglądać. Napisaliśmy nawet automatyczne pomocniki, które dodadzą nowe kolumny i indeksy w przypadku wprowadzenia zmian w schematach baz danych (z niezwykle szczegółowym powiadamianiem o błędach). |
knex | Kreator zapytań SQL, którego używamy tylko do migracji baz danych i sprawdzania poprawności schematu knex-schema-inspector . |
mandarynka | Automatyczny 18n tłumaczenie fraz z obsługą Markdown przy użyciu API tłumaczenia w chmurze Google. |
połączenie mx | Pakiet Node.js do rozwiązywania i nawiązywania połączeń z serwerami MX oraz obsługi błędów. |
2:00 | Menedżer procesów produkcyjnych Node.js z wbudowanym modułem równoważenia obciążenia (dostrojony za wydajność). |
serwer smtp | Biblioteka serwerów SMTP – używamy jej do naszych serwerów wymiany poczty („MX”) i serwerów wychodzących SMTP. |
Test Imap | Przydatne narzędzie do testowania serwerów IMAP pod kątem testów porównawczych i zgodności protokołu IMAP ze specyfikacją RFC. Projekt ten został stworzony przez firmę Gołębnik zespół (aktywny serwer IMAP i POP3 o otwartym kodzie źródłowym od lipca 2002 r.). Za pomocą tego narzędzia dokładnie przetestowaliśmy nasz serwer IMAP. |
Możesz znaleźć inne projekty, w których używamy nasz kod źródłowy na GitHubie.
Dostawcy
Dostawca | Zamiar |
---|---|
Rozbłysk chmur | Dostawca DNS, kontrole stanu, moduły równoważenia obciążenia i miejsce na kopie zapasowe Cloudflare R2. |
Cyfrowy ocean | Dedykowany serwer hostingowy i zarządzane bazy danych. |
Vultr | Hosting na serwerze dedykowanym. |
Pakiet danych | Hosting na serwerze dedykowanym. |
Myśli
Zasady
Przesyłanie wiadomości e-mail zostało zaprojektowane zgodnie z następującymi zasadami:
- Zawsze bądź przyjazny dla programistów, skupiający się na bezpieczeństwie i prywatności oraz przejrzysty.
- Przestrzegaj MVC, Uniksa, KISS, DRY, YAGNI, Dwanaście czynników, Brzytwa Ockhama, oraz karmienie psów
- Celuj w scrappy, bootstrap i ramen-dochodowy deweloper
Eksperymenty
tldr; Ostatecznie korzystanie z pamięci obiektowej i/lub tabel wirtualnych zgodnych z S3 nie jest technicznie wykonalne ze względu na wydajność i jest podatne na błędy z powodu ograniczeń pamięci.
Przeprowadziliśmy kilka eksperymentów prowadzących do ostatecznego rozwiązania SQLite, jak omówiono powyżej.
Jednym z nich była próba użycia rclon i SQLite wraz z warstwą pamięci kompatybilną z S3.
Ten eksperyment doprowadził nas do lepszego zrozumienia i odkrycia przypadków brzegowych związanych z rclone, SQLite i VFS stosowanie:
- Jeśli włączysz
--vfs-cache-mode writes
flag za pomocą rclone, wtedy odczyty będą OK, jednak zapisy będą buforowane.- Jeśli masz wiele serwerów IMAP rozproszonych na całym świecie, pamięć podręczna będzie na nich wyłączona, chyba że masz jednego autora i wielu słuchaczy (np. podejście pub/sub).
- Jest to niezwykle złożone i dodanie dodatkowej złożoności tego typu spowoduje więcej pojedynczych punktów awarii.
- Dostawcy pamięci masowej kompatybilni z S3 nie obsługują częściowych zmian plików – co oznacza jakąkolwiek zmianę pliku
.sqlite
plik spowoduje całkowitą zmianę i ponowne przesłanie bazy danych. - Inne rozwiązania, np
rsync
istnieją, ale nie skupiają się na dzienniku zapisu z wyprzedzeniem („WAL") - więc ostatecznie sprawdziliśmy Litestream. Na szczęście nasze użycie szyfrowania już szyfruje WAL plików za nas, więc nie musimy w tym celu polegać na Litestream. Jednak nie byliśmy jeszcze pewni Litestream do użytku produkcyjnego i poniżej zamieszczamy kilka uwag na ten temat. - Korzystając z tej opcji
--vfs-cache-mode writes
(t tylko sposób na użycie SQLiterclone
do zapisu) podejmie próbę skopiowania całej bazy danych od zera do pamięci – obsługa jednej skrzynki pocztowej o pojemności 10 GB jest OK, jednak obsługa wielu skrzynek pocztowych o wyjątkowo dużej pojemności spowoduje, że serwery IMAP będą miały ograniczenia pamięci iENOMEM
błędy, błędy segmentacji i uszkodzenia danych.
- Jeśli spróbujesz użyć SQLite Wirtualne stoły (np. za pomocą s3db), aby dane znajdowały się w warstwie pamięci kompatybilnej z S3, napotkasz kilka dodatkowych problemów:
- Odczyt i zapis będą bardzo powolne, ponieważ punkty końcowe interfejsu API S3 będą musiały zostać trafione za pomocą protokołu HTTP
GET
,PUT
,HEAD
, orazPOST
metody. - Testy rozwojowe wykazały, że przekraczanie 500K-1M+ rekordów w Internecie światłowodowym jest w dalszym ciągu ograniczone przepustowością zapisu i odczytu dla dostawców kompatybilnych z S3. Na przykład nasi programiści pobiegli
for
pętle do wykonywania obu sekwencyjnych operacji SQLINSERT
instrukcje i te, które masowo zapisywały duże ilości danych. W obu przypadkach występ był zdumiewająco powolny. - Wirtualne stoły nie może mieć indeksów,
ALTER TABLE
wypowiedzi i Inny ograniczenia – co prowadzi do opóźnień sięgających 1-2 minut lub więcej, w zależności od ilości danych. - Obiekty były przechowywane w postaci niezaszyfrowanej i nie jest łatwo dostępna natywna obsługa szyfrowania.
- Odczyt i zapis będą bardzo powolne, ponieważ punkty końcowe interfejsu API S3 będą musiały zostać trafione za pomocą protokołu HTTP
- Zbadaliśmy także użycie sqlite-s3vfs który jest podobny koncepcyjnie i technicznie do poprzedniego punktu (więc ma te same problemy). Jedną z możliwości byłoby użycie zwyczaju
sqlite3
kompilacja owinięta szyfrowaniem, takim jak wxSQLite3 (którego obecnie używamy w naszym rozwiązaniu powyżej) poprzez edycja pliku instalacyjnego. - Innym potencjalnym podejściem było użycie metody przedłużenie multipleksu, jednakże ma to ograniczenie do 32 GB i wymagałoby skomplikowanych problemów związanych z budowaniem i programowaniem.
ALTER TABLE
wymagane są instrukcje (więc całkowicie wyklucza to użycie wirtualnych tabel). PotrzebujemyALTER TABLE
instrukcje, aby nasz hak zknex-schema-inspector
działać poprawnie – co gwarantuje, że dane nie zostaną uszkodzone, a odzyskane wiersze będą mogły zostać przekonwertowane na prawidłowe dokumenty zgodnie z naszymimongoose
definicje schematów (które obejmują ograniczenia, typ zmiennej i dowolną walidację danych).- Prawie wszystkie projekty kompatybilne z S3, związane z SQLite w społeczności open source, są w Pythonie (a nie w JavaScript, którego używamy w 100% naszego stosu).
- Biblioteki kompresji, takie jak sqlite-zstd (Widzieć uwagi) wyglądają obiecująco, ale mogą nie być jeszcze gotowe do użytku produkcyjnego. Zamiast tego kompresja po stronie aplikacji dla typów danych, takich jak
String
,Object
,Map
,Array
,Set
, orazBuffer
będzie czystszym i łatwiejszym podejściem (a także łatwiej jest migrować, ponieważ moglibyśmy przechowywać plikBoolean
flaga lub kolumna – lub nawet użyćPRAGMA
user_version=1
do kompresji lubuser_version=0
bez kompresji jako metadane bazy danych).- Na szczęście w pamięci naszego serwera IMAP wdrożono już funkcję usuwania duplikatów załączników — dlatego w każdej wiadomości z tym samym załącznikiem nie zostanie zachowana kopia załącznika — zamiast tego pojedynczy załącznik jest przechowywany dla wielu wiadomości i wątków w skrzynce pocztowej (a obcy później stosuje się odniesienie).
- Projekt Litestream, będący rozwiązaniem do replikacji i tworzenia kopii zapasowych SQLite, jest bardzo obiecujący i najprawdopodobniej będziemy z niego korzystać w przyszłości.
- Nie chcę dyskredytować autorów (autorów) – ponieważ uwielbiamy ich pracę i wkład w open source już od ponad dziesięciu lat – jednakże z rzeczywistego użytkowania wynika, że tak może powodować silny ból głowy oraz potencjalna utrata danych w wyniku użytkowania.
- Przywracanie kopii zapasowych musi być bezproblemowe i proste. Korzystanie z rozwiązania takiego jak MongoDB z
mongodump
orazmongoexport
jest nie tylko żmudne, ale także czasochłonne i wymaga złożoności konfiguracji.- Bazy danych SQLite sprawiają, że jest to proste (jest to pojedynczy plik).
- Chcieliśmy zaprojektować rozwiązanie, w którym użytkownicy będą mogli w każdej chwili zabrać swoją skrzynkę pocztową i wyjść.
- Proste polecenia Node.js do
fs.unlink('mailbox.sqlite'))
i jest trwale usuwany z pamięci dyskowej. - W podobny sposób możemy używać interfejsu API zgodnego z S3 z protokołem HTTP
DELETE
aby łatwo usuwać migawki i kopie zapasowe dla użytkowników.
- Proste polecenia Node.js do
- SQLite był najprostszym, najszybszym i najbardziej opłacalnym rozwiązaniem.
Brak alternatyw
Według naszej wiedzy żadne inne usługi e-mail nie są zaprojektowane w ten sposób ani nie są typu open source.
My myślę, że to może być spowodowane do istniejących usług e-mail, w których wykorzystywana jest starsza technologia kod spaghetti 🍝.
Większość, jeśli nie wszyscy, istniejących dostawców usług e-mail to dostawcy usług o zamkniętym kodzie źródłowym lub reklamujący się jako dostawcy o otwartym kodzie źródłowym, ale w rzeczywistości tylko ich front-end jest open-source.
Najbardziej wrażliwa część wiadomości e-mail (rzeczywista interakcja przechowywania/IMAP/SMTP) wszystko odbywa się na zapleczu (serwerze) i nie na froncie (klient).
Wypróbuj funkcję przesyłania dalej e-mailem
Zapisz się już dziś o godz https://forwardemail.net! 🚀