SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

Stalwart VPS 邮件服务器:能替代 Postfix 和 Dovecot 吗

了解 Stalwart v0.16.19 的单一 Rust 二进制文件能替代哪些 Postfix、Dovecot 和 Rspamd 组件,哪些问题仍需自行解决,以及何时应选择 mailcow。

Stalwart 如何整合为一个二进制文件

Stalwart 是一款邮件服务器,您可以将其作为单个 Rust 二进制文件运行在单台 VPS 上。它在同一个进程中处理 SMTP、IMAP、POP3、JMAP、CalDAV、CardDAV 和 WebDAV 请求,并内置了垃圾邮件过滤器、消息存储和 ACME 客户端。传统的邮件栈需要通过 Postfix、Dovecot、Rspamd、账户数据库以及独立的证书工具来完成同样的工作。Stalwart 用一个服务单元和一个位于 /etc/stalwart/config.json 的配置文件取代了上述所有组件。

下文中的所有数字、设置名称和命令均引用自 Stalwart 的官方文档、发布页面及安装脚本。首次查阅时间为 2026 年 8 月 28 日(针对 2026 年 8 月 24 日发布的 v0.16.19 版本),并于 2026 年 10 月 12 日进行了复核(当时最新版本为 2026 年 10 月 11 日发布的 v0.16.26)。以下命令供您在自己的服务器上运行。每条命令后均附有验证步骤,用于确认执行结果。

Stalwart 采用 GNU Affero General Public License v3.0 (AGPL-3.0) 和 Stalwart Enterprise License v2 双重许可。部分功能仅限企业版使用。文档中的 HTTP 端点列表已在 /scim/v2/* 处进行了标记。在围绕某项您尚未亲自测试的功能规划部署之前,请务必阅读许可条款。

“单个二进制文件”确实减少了活动组件的数量。但这并不会减少决定邮件能否送达的两个关键因素。

端口 25 和 DNS 信誉度与您运行的软件无关

出站 TCP 端口 25 是第一道关卡。许多 VPS 提供商会在新账户上默认封禁该端口,而端口 25 被封意味着您的服务器无法直接向其他人的邮件服务器投递邮件。在安装任何软件之前,请先进行测试。

sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 alt1.aspmx.l.google.com 25

如果连接正常,Connection to alt1.aspmx.l.google.com ... 25 port [tcp/smtp] succeeded! 会在大约一秒内显示。如果端口被封,通常会出现两种情况。如果数据包在上游被丢弃,系统不会返回重置信号,因此 nc 会挂起五秒钟,然后显示 nc: connect to alt1.aspmx.l.google.com port 25 (tcp) failed: Connection timed out。如果防火墙拒绝连接,它会返回一个 ICMP 错误(netfilter 的 reject 默认返回端口不可达,除非配置为发送其他错误,例如管理禁止),因此失败会立即返回,通常显示为 Connection refused 或 No route to host。无论哪种情况,请向您的提供商提交工单。

如果提供商拒绝开放端口,唯一的解决方法是使用中继。Stalwart 可以通过中继路由将所有出站邮件交给智能主机(smarthost)。该路由的端口默认为 25,但接受 1 到 65535 之间的任何值,并配有 implicitTls 开关,以及用于 465 或 587 端口认证中继的 authUsername 和 authSecret 字段。此时,您的邮件将使用中继服务器的信誉度而非您自己的信誉度进行发送。

第二道关卡是接收方网络对您的 IP 地址和域名的看法。这涉及 IP 的反向 DNS、SPF、DKIM、DMARC 以及您所在 IP 地址段的发送历史。我们在 2026 年 8 月 28 日查阅 Stalwart 的 DNS 设置页面时,其明确指出相关工作的位置:反向 DNS 记录“通常由托管服务提供商配置,而非由 Stalwart 本身配置”。该类别中的其他项目也是如此。它们存在于您的 DNS 区域和提供商的控制面板中,而非邮件服务器内。

因此,本页面不再重复讲解这些记录。我们有专门的页面介绍:SPF、DKIM 和 DMARC 的一次性配置指南。如果您尚未决定是否要自建邮件服务,请先阅读 我们关于自建邮件服务是否仍有价值的客观分析。选择 Stalwart 并不会改变这些考量因素。

小型 VPS 运行 Stalwart 邮件服务器的资源需求

根据 2026 年 10 月 12 日查阅的 Stalwart 系统需求页面,其资源需求如下。空闲内存占用约为 100 MB。对于 5 到 10 个用户的小型部署,1 GB 内存即可满足需求。约 5 个用户的低流量环境可在单核 CPU 上运行;该页面同时指出,“随着并发量和活跃度的增加,需要更多的 CPU 核心以维持低延迟和高吞吐量”。默认并发连接上限为 8,192 个,该数值支持配置。

该页面未规定最小磁盘空间,因此请根据预期的邮件存储量规划磁盘大小,并预留足够的空间供存储压缩使用。

必须确保三条出站路径畅通,否则服务器会出现与邮件功能无关的故障。服务器需从 https://github.com/stalwartlabs/webui/releases/latest/ 获取 Web 界面包。需连接 https://acme-v02.api.letsencrypt.org/directory 以获取证书。需通过 UDP 和 TCP 53 端口进行 DNS 查询,以解析 MX 和身份验证记录。若出口防火墙配置过严导致无法访问第一个地址,将导致邮件服务器虽能运行但无法使用管理界面。

安装指定版本,而非 “latest”

官方安装程序是一个 shell 脚本。运行前请先阅读它。

curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh -o install.sh
less install.sh
sudo sh install.sh

在 2026 年 10 月 12 日阅读该脚本,可以明确其执行逻辑。它会创建一个 stalwart 服务账户及其所需的目录。随后从 https://github.com/stalwartlabs/stalwart/releases/latest/download 下载文件。二进制文件被放置在 /usr/local/bin/stalwart,权限为 0755。配置文件存放在 /etc/stalwart/config.json,数据存放在 /var/lib/stalwart,日志存放在 /var/log/stalwart,这三个目录的权限均为 0750,所有者为 stalwart。环境变量文件被写入 /etc/stalwart/stalwart.env,权限为 0640,所有者为 root:stalwart。该脚本接受一个可选的安装前缀和一个用于 FoundationDB 构建的 --fdb 标志。它不接受版本参数。

最后一点至关重要。该脚本始终拉取最新版本,因此相隔一周构建的两台服务器运行的代码版本并不一致。请在安装后手动锁定二进制文件版本,这也是 v0.16.26 版本说明中给出的升级路径:“如果您从 v0.16.x 升级,请替换二进制文件(或运行 docker pull)。”在 2026 年 8 月 24 日至 10 月 11 日期间发布了 7 个补丁版本,其中包含多个安全修复,因此请锁定最新版本,并在需要时手动更新。

STALWART_TAG=v0.16.26
curl -fsSLO "https://github.com/stalwartlabs/stalwart/releases/download/${STALWART_TAG}/stalwart-x86_64-unknown-linux-gnu.tar.gz"
tar zxf stalwart-x86_64-unknown-linux-gnu.tar.gz
sudo systemctl stop stalwart
sudo install -m 0755 -o root -g root stalwart /usr/local/bin/stalwart
sudo systemctl start stalwart
systemctl is-active stalwart

systemctl is-active stalwart 应当输出 active。如果输出其他内容,请阅读 journalctl -u stalwart -n 50。每个发布资源都附带一个对应的 .sigstore.json 软件包,因此在安装前可以验证下载文件的签名。

脚本写入的单元文件以 User=stalwart 用户身份运行,并设置了 AmbientCapabilities=CAP_NET_BIND_SERVICE。该能力使得非特权账户能够绑定 25、443、465 和 993 端口。如果您后续自行编写单元文件并遗漏了该行,服务将在启动时失败,因为普通用户无法绑定 1024 以下的端口。

初始管理员密码的输出位置

Stalwart 以引导模式启动,并在服务日志中写入一次性的 16 字符临时密码。

sudo journalctl -u stalwart -n 200 | grep -A8 'bootstrap mode'

设置向导通过 8080 端口监听明文 HTTP,因此不要暴露该端口。改用 SSH 从笔记本电脑建立隧道:

ssh -N -L 8080:127.0.0.1:8080 you@your-vps

然后打开 http://127.0.0.1:8080/admin,使用 admin 登录,密码使用日志中的值。向导会要求设置服务器主机名、默认邮件域、TLS、存储、账户目录、日志记录和 DNS 处理方式。完成后重启服务,之后使用 https://<your-host>/admin。

如果密码已从日志中滚动过去,请改为设置固定密码。/etc/stalwart/stalwart.env 提供了专门用于此目的的注释配置项,其中包括 STALWART_RECOVERY_ADMIN=admin:changeme、STALWART_RECOVERY_MODE=true 和 STALWART_RECOVERY_MODE_PORT(默认值为 8080)。取消注释后重启并登录,然后再次将其注释掉。Stalwart 的加固页面建议仅在紧急情况下保留该凭据,并明确禁止使用管理员账户登录 IMAP、JMAP 或 WebDAV。

同一页面列出了应保留的监听器:25 端口用于入站 SMTP,465 端口用于隐式 TLS 的提交,993 端口用于 IMAPS,443 端口用于所有 HTTP 流量。该页面将 587、143、4190、110、995 和 8080 标记为非必要端口,并要求在设置完成后关闭 8080。

使用固定标签在 Docker 中运行

文档中使用的镜像是 stalwartlabs/stalwart。截至 2026 年 10 月 12 日,Docker Hub 上存在 v0.16.26 标签,以及 -alpine 变体。Stalwart 的 Docker 页面建议在生产环境中使用 v0.16 次要版本标签。出于与上述二进制文件相同的原因,请锁定补丁版本。

services:
  stalwart:
    image: stalwartlabs/stalwart:v0.16.26
    container_name: stalwart
    restart: unless-stopped
    ports:
      - "25:25"
      - "465:465"
      - "993:993"
      - "443:443"
      - "127.0.0.1:8080:8080"
    volumes:
      - stalwart-etc:/etc/stalwart
      - stalwart-data:/var/lib/stalwart
volumes:
  stalwart-etc:
  stalwart-data:

该文件是将文档中的 docker run 命令转换为 Compose 格式后的内容,已移除不必要的监听器,并将设置端口绑定到 localhost。启动该服务并查看相同的引导行:

docker compose up -d
docker compose logs stalwart 2>&1 | grep -A8 'bootstrap mode'

Docker 页面还记录了 -e STALWART_RECOVERY_ADMIN=admin:mySecretPass 作为在启动时设置固定凭据的方法,如果您更倾向于使用该方式而非读取日志,可以使用 Compose 的 environment: 键。

完整的文档端口列表,以及为何此文件更精简

Stalwart 的 Docker 页面发布了 443、8080、25、587、465、143、993、110、995 和 4190 端口。其加固页面指出 587、143、110、995 和 4190 为非必要端口,并建议在设置完成后禁用 8080。仅添加客户端实际需要的端口。如果手机必须使用 STARTTLS 提交,则发布 587。如果用户通过桌面客户端编写 Sieve 规则,则发布 4190。

如果您不熟悉 Compose,我们的 VPS Docker Compose 指南 涵盖了文件布局及此处使用的命名卷模型。特别提醒邮件服务器用户:Docker 通过写入自身的防火墙规则来发布端口,这些规则的优先级高于 ufw,因此 ufw deny 8080 无法关闭 Compose 发布的端口。在端口映射中绑定到 127.0.0.1 才是真正关闭端口的方法,这也是上述文件采用该方式且 SSH 隧道依然有效的原因。

无需 Certbot 的 TLS 及其代价

Stalwart 直接内置了 ACME(自动证书管理环境)实现,因此无需使用 certbot,也不需要续期钩子。文档列出了四种验证方法。HTTP-01 通过 80 端口响应质询请求。TLS-ALPN-01 使用 ACME 专用的 ALPN 协议,在 443 端口提供专用的证书。DNS-01 通过发布临时 TXT 记录进行验证,它是支持签发通配符证书的两种方法之一。DNS-PERSIST-01 使用长效授权 TXT 记录,无需在每次续期时写入新记录。

其代价是 Stalwart 要求接管 TLS 握手。TLS-ALPN-01 通过自行完成握手来工作,因此它无法在负责 TLS 终止的反向代理后成功运行。如果 nginx 或 Caddy 已经在该服务器上占用了 443 端口,你有三种解决方案。Stalwart 官方的 nginx 指南将 nginx 配置为 TCP 透传,使用 listen 443; proxy_pass 127.0.0.1:10443; proxy_protocol on;,从而使 TLS 连接在不被处理的情况下直接到达 Stalwart。这会将 443 端口上的所有连接交给 Stalwart,因此适用于该端口上没有运行其他服务的服务器。否则,请将 Stalwart 切换为 DNS-01 或 HTTP-01 验证,或者为其分配独立的 IP 地址。

DANE 和 MTA-STS,以及需要了解的默认值

两者都在 Web 界面的 MtaTlsStrategy 对象中,路径为 Settings、MTA、Outbound、TLS Strategies,按 TLS 策略分别配置。dane 字段默认为 optional:当收件方发布 TLSA 记录时尝试进行 DANE 验证;如果没有发布,则回退到普通 STARTTLS。设置为 require 后,只有在 TLSA 记录可验证时才会继续投递。mtaSts 字段的行为相同,默认值为 optional。相关超时设置为 tlsTimeout(默认 3 分钟)和 mtaStsTimeout(默认 5 分钟)。

在入站方向,Stalwart 可以在 https://mta-sts.<domain>/.well-known/mta-sts.txt 发布您自己的 MTA-STS 策略,但必须开放 443 端口。MtaSts 单例包含 mode(默认 testing)、maxAge(默认 7 天)和 mxHosts;当该字段为空时,系统会回退到 TLS 证书中的主机名。您需要提供两条 DNS 记录:一条指向邮件主机的 mta-sts CNAME 记录,以及一条包含策略标识符的 _mta-sts TXT 记录。

dig +short TXT _mta-sts.example.org
curl -s https://mta-sts.example.org/.well-known/mta-sts.txt

TXT 查询应返回 v=STSv1; id=... 字符串,curl 应返回策略正文。如果 curl 没有返回内容,说明 443 端口未开放,或尚未为 mta-sts.example.org 签发证书。

在这两项检查通过前,将 mode 保持为 testing。证书损坏时,处于 enforce 模式的策略会阻止其他服务器向您投递邮件;用户会先发现问题并向您反馈,而不是由日志通知您。DANE 也有一个类似的陷阱:它要求 DNSSEC 签名的区域,而且每次 ACME 续期后,都必须重新发布固定叶证书的 TLSA 记录。您可以改为固定签发 CA,或者接受定期更新 TLSA 记录的维护工作。

静态加密不等同于端到端加密

这是最常被误解的功能,以下是文档的准确说明。每个用户的明文消息在写入磁盘前,会自动使用其 OpenPGP 或 S/MIME 证书进行加密。encryptAtRest 默认启用,适用于通过 SMTP 或 LMTP 到达的消息,前提是收件人已注册加密密钥。encryptOnAppend 默认值为 false,“这使得追加的消息保持不变,以便客户端对其存储的内容保持完全控制”。OpenPGP 使用 PGP/MIME 而非较旧的 PGP/Inline,采用 AES-256 或 AES-128 加密。Stalwart 不会生成密钥:用户需导出 ASCII 封装的公钥,并将其作为 PublicKey 对象在“账户”下的“公钥”中注册。

因此,该功能可以保护被窃取的磁盘镜像、被窃取的备份,以及运维人员在消息投递后读取存储内容的情况。没有私钥,存储的字节数据将无法读取,管理员也无法解密。

它无法保护传输中的消息。消息在互联网上传输时,使用两台服务器协商的任何 TLS 版本,到达时为明文,Stalwart 在此时对其进行加密。发送方、发送方的服务提供商以及任何剥离了 TLS 的中间节点都已经查看过明文。

还有三个限制值得明确说明。你的“已发送”和“草稿”文件夹由客户端写入,这属于追加操作,且 encryptOnAppend 默认值为 false,因此除非你更改此设置,否则这些内容将保持明文。我在 2026 年 10 月 12 日重读的文档仅描述了消息内容,并未说明信封数据、邮件头或索引条目会被加密,因此请勿假设它们已加密。文档也未说明在上传密钥之前已存储的消息会被重新加密,因此请假设它们不会被重新加密并进行检查。文档也未说明全文搜索是否仍能在加密的正文中工作。在向任何人承诺此功能之前,请先在测试账户上进行验证。

此外,如果用户丢失了私钥,其邮件将永久丢失。根据设计,不存在恢复路径。

WKD 是 Web 服务器任务,而非邮件服务器任务

WKD (Web Key Directory) 是 OpenPGP 体系的另一半,用于解决不同的问题。它将您的公钥发布在域名下的固定 HTTPS URL 中,以便发送方的邮件客户端能在邮件发出前找到公钥并加密消息。这实现了端到端加密。Stalwart 的静态加密(at-rest encryption)针对的是存储在磁盘上的副本。配置其中一项并不能替代另一项。

Stalwart 不提供 WKD 服务。截至 2026 年 10 月 12 日,其文档记录的 HTTP 端点列出了 jmap、caldav、carddav、oauth-authorization-server、openid-configuration、acme-challenge、mta-sts.txt、mail-v1.xml 和自动配置的众所周知路径。其中不包含 openpgpkey 路径。请使用普通的静态 Web 服务器来托管它。

该规范定义了两种布局。高级方法使用 https://openpgpkey.example.org/.well-known/openpgpkey/example.org/hu/iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=Joe.Doe。直接方法使用 https://example.org/.well-known/openpgpkey/hu/iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=Joe.Doe。那个 32 字符的字符串是本地部分(local part)小写后的 SHA-1 哈希值,并以 z-base-32 编码,因此切勿手动创建这些文件名。请使用 GnuPG 为您生成。

gpg --export --armor you@example.org > you.asc
gpg-wks-client --print-wkd-url you@example.org
gpg-wks-client --install-key you.asc you@example.org

--print-wkd-url 会打印客户端将要获取的 URL(使用子域名形式)。--install-key 会将密钥写入一个本地目录树,该目录树镜像了 WKD 布局,默认位于名为 openpgpkey 的顶层目录下,可通过 -C dir 进行更改。将该目录树复制到您的 Web 根目录中,在 hu 目录旁添加所需的 policy 文件(空文件即可),然后使用 curl 获取您自己的 URL,以确认其返回的是密钥字节而非 404 错误。

单个 VPS 上的存储

Stalwart 将存储分为 4 个角色:用于保存邮箱状态等结构化记录的数据存储,用于保存原始邮件内容和附件的 Blob 存储,用于建立全文索引的搜索存储,以及用于保存速率限制器、身份验证令牌和会话数据的内存存储。每个角色都可以指向不同的后端。支持的后端包括 RocksDB、FoundationDB、PostgreSQL、MySQL、SQLite、兼容 S3 的对象存储、Azure Blob Storage、Redis、ElasticSearch 和 Meilisearch。

在单个 VPS 上,答案很简单。文档称 RocksDB 是“单节点 Stalwart 部署的推荐后端,因为它速度快且可靠”。Redis 仅支持用作内存存储,不能用作数据存储或 Blob 存储,因此不需要单独运行 Redis 容器即可开始使用。邮箱超出磁盘容量后,再将 Blob 存储迁移到 S3。

备份方式取决于所用后端。对于外部数据库,请使用该数据库自己的备份流程。对于内置后端,FAQ 建议复制 /var/lib/stalwart 目录。请在服务停止后执行此操作,或从文件系统快照或卷快照中复制。对正在运行的键值存储执行文件级复制,可能会在其写入过程中捕获不完整状态;直到尝试恢复时,您才会发现备份不可用。

替代 Rspamd 的垃圾邮件过滤器

过滤在同一进程中运行,因此无需维护第二个守护进程。分类器在 Settings、Spam Filter、Classifier 下的 SpamClassifier singleton 中配置。它使用带特征哈希的 FTRL-Proximal 算法。对于大多数部署,推荐默认使用 FtrlFh。FtrlCcfh 会改用 cuckoo 特征哈希,以减少哈希冲突,适用于大规模部署。它会持续训练:用户将邮件标记为 spam 或 ham 时,该标签会直接反馈到后续决策中。

分类器周围还集成了 DNS blocklist、greylisting、钓鱼检测、spam trap 和 Pyzor;如果您有不愿放弃的规则,还可以选择通过 milter 调用 SpamAssassin。

何时仍应选择 mailcow

Stalwart 没有内置 Webmail。这是它与 mailcow 之间最大的差距,且差距显著。截至 2026 年 10 月 12 日查阅的 mailcow 文档显示,其包含 SOGo 在内的 16 个组件,可直接为用户提供浏览器收件箱以及 CalDAV 和 CardDAV 接口。Stalwart 在 2025 年 6 月 20 日的路线图文章中提到,内置 Webmail “在我们的计划中,但目前并非当务之急”,计划在 1.0 版本后使用 Rust 和 Dioxus 开发,“很可能在 2026 年的某个时间”。截至 2026 年 10 月 12 日,项目博客尚未发布相关公告。因此,若使用 Stalwart,你必须自行部署 Roundcube,或要求每位用户自行配置邮件客户端。

Stalwart 确实拥有 Web 管理界面,因此这并非人们预想中的短板。第二个差距在于版本的成熟度。FAQ 指出 Stalwart 仍处于 0.x 版本,数据布局和配置在 v1.0 之前可能会发生变化,这可能需要进行迁移。项目在 2026 年 6 月发布的文章标题为《零未解决 Bug 报告:通往 Stalwart 1.0 之路》,这说明了其现状:接近完成,但尚未发布。截至 2026 年 10 月 12 日,最新版本仍为 v0.16.26。

第三个差距是功能列表中通常不会提及的:Postfix、Dovecot 和 Rspamd 拥有长达十年的技术积累和文档支持。在凌晨两点,当邮件堆积且用户等待处理时,搜索到一个匹配的错误字符串比优雅的架构更有价值。如果你正处于这种情况,我们的 mailcow 安装指南涵盖了整个技术栈的端到端部署,这能让你少熬夜。

如果你需要单个二进制文件、单个配置文件和 JMAP 支持,并且乐于尝试新技术,请选择 Stalwart。如果你需要现成的 Webmail 以及庞大的现有解决方案库,请选择 mailcow。

迁移现有邮件

通用方案是使用 imapsync 在 IMAP 和 IMAP 之间迁移,与两端运行的具体软件无关。请先执行试运行。

imapsync --dry \
  --host1 old.example.org --user1 you@example.org --passfile1 /root/.old.pw \
  --host2 mail.example.org --user2 you@example.org --passfile2 /root/.new.pw

--dry 会让 imapsync“实际不执行任何操作,只打印计划执行的操作”,因此移除该标志前请先检查输出。每个密码文件的第一行包含密码,因此请同时 chmod 600 两个文件,之后删除这些文件。

Stalwart 还提供了较新的工具,大多数第三方指南尚未更新相关内容。其博客介绍了 Vandelay,这是一款 JMAP 导入和导出工具(29 May 2026);还介绍了用于零停机升级的迁移代理(10 June 2026)。规划大型迁移前,请先阅读这两篇文章,因为它们比其他渠道几乎所有相关资料都新。

故障模式及常见错误信息

管理界面无法加载。 FAQ 中明确提到了此问题:Web 界面包在首次运行时从 GitHub 下载,因此如果服务器无法向 github.com 发起出站 HTTPS 请求,服务虽然可以运行,但 Web 界面路由会全部返回 404。请在服务器上使用 curl -sI https://github.com/stalwartlabs/webui/releases/latest/ 进行检查。FAQ 列出的其他常见原因包括 HTTP 或 HTTPS 协议不匹配,以及反向代理未转发客户端 IP。

日志中没有引导密码。 密码仅在引导模式启动时打印一次。如果服务在此之后已重启,请使用 sudo journalctl -u stalwart --since today | grep -A8 'bootstrap mode' 扩大查看范围。如果密码确实丢失,请在 /etc/stalwart/stalwart.env 中设置 STALWART_RECOVERY_ADMIN 并重启服务。

通过本地代理的中继被拒绝。 v0.16.19 版本说明记录了一个关于中继路由被 host resolves loopback address 拒绝的修复。如果遇到该特定字符串,说明您运行的是旧版本。请升级版本,不要尝试绕过此问题。

编写自定义 unit 文件后服务无法启动。 若缺少 AmbientCapabilities=CAP_NET_BIND_SERVICE,stalwart 用户将无法绑定 25、443、465 或 993 端口,导致服务在尝试监听第一个端口时启动失败。请从安装程序生成的 unit 文件中复制 capability 行。

证书无法签发。 HTTP-01 验证需要 80 端口可达且未被占用。TLS-ALPN-01 验证需要 Stalwart 本身在 443 端口响应 TLS 握手。如果服务器上其他进程占用了上述任一端口,ACME 将持续静默失败,而其他服务看起来一切正常。

FAQ

Stalwart 能否在一台 VPS 上替代 Postfix、Dovecot 和 Rspamd?

可以。Stalwart 是一个 Rust 二进制程序,可处理 SMTP、IMAP、POP3、JMAP、CalDAV、CardDAV 和 WebDAV,并内置了垃圾邮件过滤、邮件存储和 ACME 客户端。它仅需一个 systemd 单元和一个位于 /etc/stalwart/config.json 的配置文件,无需维护四个守护进程及其胶水代码。它无法替代的是你的 DNS 区域设置或服务商的 25 端口策略,这才是自建邮件服务成败的关键。

Stalwart 邮件服务器需要多少内存?

根据 2026 年 10 月 12 日查阅的 Stalwart 系统需求页面,其空闲时占用约 100 MB 内存,并建议 1 GB 内存适用于 5 到 10 用户的中小型部署。约 5 用户的低流量配置可在单核 CPU 上运行。所有服务的默认并发连接限制为 8,192,该值可配置,因此上限随连接数和邮件量增长,而非仅取决于用户数。官方未发布最小磁盘空间要求,请根据你保留的邮件量规划磁盘大小。

切换到 Stalwart 能否提高邮件送达率?

不能。送达率取决于 VPS 的出站 TCP 25 端口是否开放、IP 的反向 DNS 设置,以及域名的 SPF、DKIM 和 DMARC 配置。Stalwart 确实支持 DANE、MTA-STS 和 SMTP TLS 报告,并能为你发布 MTA-STS 策略,但这些功能旨在保障传输安全,而非决定接收网络是否信任你的地址。在安装任何软件前,请先使用 nc -vz -w 5 alt1.aspmx.l.google.com 25 测试 25 端口。

Stalwart 是否包含 Webmail?

截至 2026 年 10 月 12 日尚不包含。它提供的是 Web 管理界面,这与 Webmail 不同。项目 2025 年 6 月 20 日的路线图文章称,计划在 1.0 版本后开发基于 Rust 和 Dioxus 的 Webmail 客户端,预计 “很有可能在 2026 年某个时间” 发布,目前项目博客尚未发布相关公告。如果用户现在就需要浏览器收件箱,请部署 Roundcube 或使用捆绑了 SOGo 的技术栈。

Stalwart 的静态加密能防范什么?

它在将消息写入磁盘前,会使用用户各自的 OpenPGP 或 S/MIME 公钥进行加密,因此磁盘被盗、备份被窃或管理员读取存储内容时,均无法恢复邮件原文。这不是端到端加密:消息以明文到达并在投递时加密,因此在此之前的每一跳都能看到内容。encryptOnAppend 默认设为 false,因此除非你进行更改,否则客户端编写的“已发送”和“草稿”邮件将保持明文。文档仅涵盖消息内容,未提及元数据、索引条目或对上传密钥前存储的邮件进行重加密,请务必自行验证,切勿想当然。

#stalwart#email#自托管#mail-server#smtp