自架服務 Stalwart 信箱伺服器 Rust SMTP JMAP

自架信箱不必再拼裝十幾個容器:Stalwart 用一支 Rust binary 接管 SMTP、IMAP、JMAP

Mailcow 動輒十幾個容器、Postfix 加 Dovecot 加 Rspamd 拼裝起來又是另一場硬仗。Stalwart 用一支 Rust binary 把 SMTP、IMAP、JMAP、CalDAV、反垃圾全部收齊,512MB 記憶體就能跑。本文解析它的架構、部署細節,以及自架信箱該不該換上來。

自架信箱伺服器在過去十年幾乎是一道沒人想再走一次的關卡。Postfix 負責 SMTP、Dovecot 負責 IMAP、Rspamd 負責反垃圾、OpenDKIM 處理簽章、ClamAV 掃毒、Roundcube 提供 Webmail——這還沒算上 LDAP、Redis、MySQL 這些底層。Mailcow 把這些東西打包成 docker-compose,一鍵起來看似輕鬆,實際上開機後要協調十五個以上的容器,記憶體至少吃 2GB,重啟一次要等好幾分鐘。

Stalwart Mail Server 從另一個方向解這個問題。它用 Rust 從頭實作了一支完整的信箱伺服器,把 SMTP、IMAP4rev2、POP3、JMAP、CalDAV、CardDAV、WebDAV、反垃圾、DKIM 簽章、ManageSieve 全部塞進同一支 binary。記憶體下限 512MB,啟動時間以秒計算。在臺灣自架信箱、又不想被 Mailcow 那一堆容器壓垮的人,現在多了一個值得認真評估的選項。

為什麼信箱伺服器要這麼多元件

傳統信箱架構的複雜不是設計者愛找麻煩,而是歷史包袱。SMTP、IMAP、POP3 是 1980 到 1990 年代分開長出來的協定,當時各自的 reference implementation 也分開維護。Postfix 寫 SMTP、Dovecot 寫 IMAP,兩邊都已經是十幾年的成熟專案,沒有人想合併。反垃圾這層更晚才獨立出來,Rspamd、SpamAssassin 都是後來的事。每多一個元件,就多一份設定檔、一條 Unix socket、一個失敗點。

這套組合在大型郵件營運商那邊運作得很好,因為他們有專職的郵件工程師,每個元件單獨擴展更有彈性。對自架用戶來說剛好相反——大部分人只想要一支 binary 收信、寄信、不要被當垃圾,三件事完成就好。

Mailcow、Mail-in-a-Box、Docker-Mailserver 都是試圖把這套組合「打包好」的方案,但本質上還是同一個架構,只是把痛苦藏在 compose 檔後面。Stalwart 是少數真的從零開始、把所有協定用一套程式碼實作完的專案。

一支 binary 裡面有什麼

Stalwart 的 GitHub 倉庫到 2026 年 5 月已經累積一萬兩千多顆星,AGPLv3 授權,作者宣布專案已經「feature complete」,下一步是收尾到 1.0。它對外提供的功能可以拆成三層:

協定層完整支援現代與傳統的所有信箱協定:SMTP(含 ESMTP、Submission、TLS 全套)、IMAP4rev2 並向下相容 IMAP4rev1、POP3、JMAP for Mail。JMAP 是 IETF 在 2019 年標準化的新一代信箱協定,把 IMAP 那種「保持連線、逐封同步」的模式換成 HTTP/JSON,行動裝置上的同步效率明顯改善。Fastmail 已經整套切過去,但開源端真正完整支援的伺服器不多,Stalwart 是其中之一。

協作層順手把 CalDAV、CardDAV、WebDAV 也補齊,意思是同一支伺服器就能當行事曆、聯絡簿、雲端硬碟用。這部分在功能上類似 Radicale 加 Nextcloud 的子集,深度不及 Nextcloud,但對個人或小型團隊夠用。

處理層包含 DKIM 簽章、SPF/DMARC/ARC 驗證、貝氏與統計分類的反垃圾、DNS 黑名單查詢、灰名單、ManageSieve 過濾腳本。較新版本還支援 LLM 輔助的內容分類,把可疑郵件丟給本地端模型再判斷一次。

後端儲存可以選 RocksDB(預設、零設定)、PostgreSQL、MySQL、SQLite、FoundationDB、S3 相容物件儲存。對個人架站來說,RocksDB 用起來最省事,啟動時自動建檔,不需要另外管資料庫。

JMAP 的價值在哪裡

IMAP 的設計假設是「使用者開一個視窗、伺服器把資料夾狀態推給他、視窗關掉前連線一直開著」。在 PC 時代這個模型沒問題,到了行動裝置就開始崩壞——手機螢幕關掉、4G 切換、Wi-Fi 漫遊,每一次都意味著 IMAP 要重新 IDLE、重新對齊 UID。同一個信件清單可能被同步好幾次,電池一直被吃。

JMAP 改用 HTTP 短連線加上一個 state token。客戶端問伺服器「我上次同步到 state=42,給我之後的變更」,伺服器丟回變更清單,連線就斷掉。手機從睡眠醒來時,只要再問一次 state,馬上就能對齊到最新狀態。對信箱應用程式來說,這個改動讓背景同步快上一個量級,行動數據用量也下降。

問題是 JMAP 客戶端還少。iOS 內建 Mail、Apple Mail、大多數 Android 客戶端目前仍是 IMAP-only。能用 JMAP 的有 Thunderbird 的實驗性支援、Fastmail 自家客戶端、少數開源專案。所以 Stalwart 同時支援 JMAP 與 IMAP 是務實的——現在用 IMAP,等客戶端跟上就直接切過去,不必再換伺服器。

部署起來真的就一支 binary 嗎

最簡單的安裝方式是執行官方提供的 shell script:

1
curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh | sh -s -- /opt/stalwart all

腳本會把 binary 放到 /opt/stalwart,建立 systemd unit,然後啟動一個 Web 設定精靈。第一次連上 https://your-ip:8080 會跳出初始化頁面,問你要不要產生 self-signed 憑證、建立 admin 帳號、選擇儲存後端。整個流程不到五分鐘。

Docker 方式則是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
services:
stalwart:
image: stalwartlabs/stalwart:latest
container_name: stalwart
ports:
- "25:25"
- "465:465"
- "587:587"
- "110:110"
- "995:995"
- "143:143"
- "993:993"
- "110:110"
- "995:995"
- "4190:4190"
- "8080:8080"
- "443:443"
volumes:
- ./data:/opt/stalwart
restart: unless-stopped

對外只要開這幾個 port,反向代理可以直接掛在 8080 前面用 Caddy 或 Nginx 包 TLS。如果直接讓 Stalwart 自己處理 TLS,它內建 ACME 客戶端,把網域指向 IP 之後會自動申請 Let’s Encrypt 憑證。

DNS 設定才是真的關卡

把 Stalwart 跑起來只佔自架信箱整件事的兩成,剩下八成是 DNS。少做任何一項都會被 Gmail、Outlook、iCloud 退信或直接送進垃圾匣。

最低必要的記錄有:

  1. mail.example.com 的 A/AAAA 記錄指向 VPS 公網 IP
  2. example.com 的 MX 記錄指向 mail.example.com,優先級 10
  3. SPF:example.com TXT 記錄寫 v=spf1 mx -all,意思是只有 MX 指向的伺服器有權代寄
  4. DKIM:在 Stalwart Web 後台產生金鑰,把 selector 那串 TXT 加到 DNS
  5. DMARC:_dmarc.example.com TXT 記錄寫 v=DMARC1; p=quarantine; rua=mailto:[email protected]
  6. PTR:請 VPS 服務商把 IP 的反查指向 mail.example.com

PTR 是最常被忽略的一項,也是最致命的。Gmail 收到郵件後會反查發送方 IP,如果反查結果跟 EHLO 宣告的主機名稱對不上,那封信幾乎一定進垃圾匣。臺灣本地的 VPS 服務商在這方面差異很大,有些後台直接讓你改 PTR,有些要開 ticket。下訂 VPS 之前先確認這項,比事後想搬家容易得多。

Port 25 才是真正的天花板

技術設定全部做對,最後撞上的天花板叫 port 25。AWS、Azure、Google Cloud 預設封 25 對外出站,要解封要填表、說明用途、等審核。DigitalOcean、Vultr、Linode 通常要求新帳號跑滿幾個月才會開。對於想架信箱的人來說,VPS 提供商願不願意給 port 25 比規格高低重要得多。

選 VPS 時可以直接寫信問業者:是否預設開放 port 25 對外出站、是否能設定 PTR。臺灣本地的 VPS 業者在這方面通常彈性比較大,至少不會把 25 當預設封鎖。一旦業者點頭,剩下的就是把 Stalwart 跑好。

反垃圾與信譽:技術解決不了的部分

Stalwart 內建的反垃圾在實測中表現不錯,貝氏分類器加上 DNSBL 查詢,對量小的個人信箱足以擋掉九成以上的垃圾郵件。但反向的問題更難:如何讓你寄出去的信不被當垃圾。

新申請的 IP 沒有信譽分數,前幾週寄出去的信很可能直接被 Gmail 丟掉。解法只有一個,叫 IP warm-up——前兩週只寄少量信給願意收的對象,慢慢累積發送量。Stalwart 沒有自動 warm-up 功能,這部分要靠人工控制。

如果是電子報這類大量發送,建議搭配 Postmark、Amazon SES 或自架 Postal 作為出站轉發。Stalwart 處理收信和個人寄信很適合,但商業級的大量寄送需要更專門的工具。

Stalwart 還缺什麼

要說缺點,目前最明顯的是沒有內建 Webmail。Stalwart 提供 JMAP API,但 Web 介面只有管理後台,沒有讓使用者收發信件的頁面。實務上要另外搭一個 Roundcube、SnappyMail 或新一代的 JMAP 客戶端如 Cypht。

中文文件相當稀缺,遇到問題大多要翻官方英文文件或 GitHub issue。社群規模比 Mailcow 小,踩到問題不一定能在中文討論區找到答案。

對於跑了五年以上的 Mailcow 用戶來說,從 Stalwart 0.x 跳過去是有風險的。1.0 還沒釋出,資料庫 schema 還在收斂,未來升級可能需要遷移工具。

該換還是不該換

如果是從零開始架信箱、預算或機器資源有限、想用 JMAP、不需要太花俏的 Webmail,Stalwart 是目前最值得試的選項。512MB 記憶體就能跑、一支 binary 包辦所有事,運維負擔遠低於 Mailcow。

如果現有 Mailcow 跑得很順、團隊已經習慣 SOGo Webmail、需要 ClamAV 防毒整合、寄信量大且需要詳細 deliverability 追蹤,那暫時沒有非換不可的理由。等 Stalwart 1.0 釋出、生態圈成熟一些再評估也不遲。

如果只是想做企業出站郵件追蹤(電子報、API 寄信),Postal 仍然是專門解這個問題的工具,Stalwart 並不是這個方向。


自架信箱的成敗從來不只在於選了哪個軟體,VPS 提供商願不願意開 port 25、能不能設定 PTR、機房 IP 的信譽分數,才是決定郵件能不能順利送達的根本。NCSE Network 在臺灣是方電訊機房提供的 VPS 預設開放 port 25 對外,PTR 可在後台自助設定,搭配 Intel Gold CPU 與 NVMe SSD,跑 Stalwart 這類 Rust 應用所需資源遠低於規格上限。想自架信箱伺服器或其他需要乾淨 IP 的服務,可以參考 NCSE Network 的 VPS 方案

需要穩定的雲端主機?

NCSE Network 提供企業級 VPS,7 天免費試用,臺灣是方電訊機房,99% SLA 保證。

查看 VPS 方案 →