基于 Chasquid 配置邮件发送服务器

在开发 Web 应用时,经常会遇到发送验证码、密码重置邮件或者系统通知邮件的需求。最开始我考虑过直接部署 Mailcow,但研究之后发现,对于一个只需要发送邮件的场景来说,Mailcow 显得有些过于庞大了。

Mailcow 集成了 SMTP、IMAP、POP3、WebMail、反垃圾邮件、病毒扫描等完整邮件系统所需的组件,部署后会运行十多个 Docker 容器。对于企业邮箱服务而言这是合理的设计,但对于一个只需要发送验证码的应用来说,大量资源都处于闲置状态。

因此我开始寻找更加轻量的替代方案,最终选择了 Chasquid。

为什么选择 Chasquid

Chasquid 是一个使用 Go 编写的轻量级邮件服务器。与 Postfix、Exim 等传统邮件服务器相比,它的配置更加简单;与 Mailcow、iRedMail 等完整解决方案相比,它又足够轻量。

对于验证码和系统通知邮件,通常只需要这些能力:

  • SMTP Submission(587)
  • SMTPS(465)
  • SMTP 服务器间投递(25)
  • DKIM 邮件签名
  • Let’s Encrypt TLS 证书
  • SMTP 用户认证

这些能力 Chasquid 都可以覆盖。

本文部署环境如下:

1
2
3
4
Ubuntu 24.04
Domain: example.com
SMTP Host: mail.example.com
Sender: notify@example.com

这里需要区分两个名字:

  • mail.example.com 是邮件服务器主机名,用于 SMTP banner、TLS 证书、PTR 反向解析。
  • example.com 是发件域名,用于 notify@example.com、SPF、DKIM、DMARC。

配置 DNS

在开始部署之前,先把 DNS 配好。

1
2
3
4
mail.example.com.        A      VPS 公网 IP
example.com. MX 10 mail.example.com.
example.com. TXT "v=spf1 a:mail.example.com -all"
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:mailauth-reports@example.com"

如果你使用 Cloudflare,mail.example.com 这条 A 记录必须是 DNS only,不能开启代理。SMTP 不是 HTTP 服务,不能走 Cloudflare 的橙云代理。

如果云服务商支持 PTR(反向解析),建议将服务器 IP 反向解析回:

1
mail.example.com

这不是绝对必须,但很多收件方会把 PTR 是否存在、PTR 是否和 SMTP 主机名对齐作为信誉评分的一部分。

安装 Chasquid

Ubuntu 可以直接安装 Chasquid:

1
2
sudo apt update
sudo apt install chasquid certbot acl

不同安装方式创建的运行用户可能不同。Ubuntu 包通常会使用 chasquid 用户;如果你自己编译或手写 systemd service,也可能使用 mail 用户。

后面的命令用一个变量表示运行用户:

1
CHASQUID_USER=chasquid

如果你的服务实际使用 mail 用户,就改成:

1
CHASQUID_USER=mail

可以通过下面的命令确认:

1
systemctl cat chasquid

写入主配置

Chasquid 的配置文件是 protobuf text 格式,语法是:

1
key: value

不是 key = value

编辑 /etc/chasquid/chasquid.conf

1
sudo vim /etc/chasquid/chasquid.conf

写入:

1
2
3
4
5
6
7
hostname: "mail.example.com"

smtp_address: ":25"
submission_address: ":587"
submission_over_tls_address: ":465"

mail_log_path: "<syslog>"

这几个字段分别表示:

  • hostname:SMTP banner、邮件头和默认证书选择会用到。
  • smtp_address:服务器到服务器投递端口,通常是 25。
  • submission_address:应用程序提交邮件端口,通常是 587,配合 STARTTLS。
  • submission_over_tls_address:隐式 TLS 提交端口,通常是 465。

配置写完后,可以先检查解析结果:

1
sudo -u "$CHASQUID_USER" chasquid-util print-config

如果配置语法错了,这一步会直接报错。

准备数据目录

Chasquid 默认使用 /var/lib/chasquid 保存队列、缓存和本地 RPC socket。目录需要让运行用户可写:

1
2
3
sudo mkdir -p /var/lib/chasquid
sudo chown -R "$CHASQUID_USER:$CHASQUID_USER" /var/lib/chasquid
sudo chmod 750 /var/lib/chasquid

如果这个目录权限不对,启动时可能会看到:

1
Error opening domain info database: mkdir /var/lib/chasquid: permission denied

创建邮件域和用户

Chasquid 默认将域相关配置保存在 /etc/chasquid/domains 目录下。

1
2
3
sudo mkdir -p /etc/chasquid/domains/example.com
sudo chown -R "$CHASQUID_USER:$CHASQUID_USER" /etc/chasquid/domains/example.com
sudo chmod 750 /etc/chasquid/domains/example.com

创建 SMTP 用户:

1
sudo -u "$CHASQUID_USER" chasquid-util user-add notify@example.com

这个账号就是后续应用程序连接 SMTP 时使用的账号。

如果想非交互式创建,也可以直接传入密码:

1
sudo -u "$CHASQUID_USER" chasquid-util user-add notify@example.com --password='YOUR_STRONG_PASSWORD'

可以用下面的命令验证账号密码是否正确:

1
sudo -u "$CHASQUID_USER" chasquid-util authenticate notify@example.com --password='YOUR_STRONG_PASSWORD'

配置 DKIM

现代邮件系统几乎离不开 DKIM。

很多人第一次接触 DKIM 时容易产生一个误解:认为它需要类似 HTTPS 那样的第三方证书机构签发。实际上并不是。DKIM 本质上是邮件服务器使用私钥对邮件内容签名,收件方从 DNS 中获取公钥进行验证。

Chasquid 约定 DKIM 私钥文件名格式为:

1
dkim:SELECTOR.pem

比如 selector 使用 20260619,文件就是:

1
/etc/chasquid/domains/example.com/dkim:20260619.pem

生成 DKIM key:

1
2
3
4
sudo -u "$CHASQUID_USER" chasquid-util dkim-keygen \
example.com \
20260619 \
/etc/chasquid/domains/example.com/dkim:20260619.pem

生成 DNS TXT 记录:

1
2
3
4
sudo -u "$CHASQUID_USER" chasquid-util dkim-dns \
example.com \
20260619 \
/etc/chasquid/domains/example.com/dkim:20260619.pem

输出会类似:

1
20260619._domainkey.example.com TXT "v=DKIM1; k=rsa; p=..."

把它添加到 DNS。注意 TXT 记录名里的 20260619 就是 selector;如果你的 selector 是 mail,才会是 mail._domainkey.example.com

配置 TLS

DKIM 解决的是邮件真实性问题,而 TLS 解决的是传输安全问题。

推荐使用 Let’s Encrypt 给 mail.example.com 签发证书。

如果服务器的 80 端口空闲,可以用 standalone:

1
sudo certbot certonly --standalone -d mail.example.com

如果 80 端口已经被 Nginx 占用,或者你使用 Cloudflare,也可以使用 DNS 插件签发:

1
sudo apt install python3-certbot-dns-cloudflare
1
2
3
4
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/cloudflare.ini \
-d mail.example.com

证书签好后通常会在:

1
2
/etc/letsencrypt/live/mail.example.com/fullchain.pem
/etc/letsencrypt/live/mail.example.com/privkey.pem

Chasquid 会从 /etc/chasquid/certs 读取证书目录。创建软链接:

1
2
3
sudo mkdir -p /etc/chasquid/certs
sudo ln -sfn /etc/letsencrypt/live/mail.example.com \
/etc/chasquid/certs/mail.example.com

还需要确保 Chasquid 运行用户能读取 Let’s Encrypt 的私钥。用 ACL 比直接 chown /etc/letsencrypt 更合适:

1
2
3
sudo setfacl -R -m "u:$CHASQUID_USER:rX" /etc/letsencrypt/live /etc/letsencrypt/archive
sudo find /etc/letsencrypt/live /etc/letsencrypt/archive -type d \
-exec setfacl -m "d:u:$CHASQUID_USER:rX" {} +

可以验证一下:

1
2
sudo -u "$CHASQUID_USER" test -r /etc/chasquid/certs/mail.example.com/privkey.pem
echo $?

输出 0 说明可读。

建议再加一个 certbot 续期后的重启钩子:

1
2
3
4
5
6
sudo tee /etc/letsencrypt/renewal-hooks/deploy/restart-chasquid.sh >/dev/null <<'EOF'
#!/bin/sh
systemctl try-restart chasquid.service
EOF

sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/restart-chasquid.sh

处理 Systemd Socket Activation

有些发行版的 Chasquid 包会启用 systemd socket activation。此时配置里可能会看到类似:

1
2
3
SMTP Addresses: ["systemd"]
Submission Addresses: ["systemd"]
Submission+TLS Addresses: ["systemd"]

如果对应 socket 没启用,服务可能会报:

1
No address to listen on

对于只做验证码和系统通知发送的场景,我更倾向于直接让 Chasquid 自己监听端口,也就是前面配置里的:

1
2
3
smtp_address: ":25"
submission_address: ":587"
submission_over_tls_address: ":465"

如果系统里存在 chasquid.socket,可以禁用它:

1
sudo systemctl disable --now chasquid.socket

然后启动 Chasquid:

1
sudo systemctl enable --now chasquid

查看状态:

1
systemctl status chasquid --no-pager -l

正常情况下会看到类似:

1
2
3
4
5
6
7
Loading certificates:
mail.example.com
Loading domains:
example.com (1 users, 0 aliases, 1 DKIM keys)
Server listening on :25 (SMTP)
Server listening on :587 (submission)
Server listening on :465 (submission+TLS)

再检查端口:

1
sudo ss -ltnp | grep -E ':(25|465|587)\b'

测试 SMTP 提交

应用程序建议使用 587 + STARTTLS

1
2
3
4
5
Host: mail.example.com
Port: 587
Security: STARTTLS
Username: notify@example.com
Password: 创建用户时设置的密码

也可以使用 465 + TLS

1
2
3
4
5
Host: mail.example.com
Port: 465
Security: TLS
Username: notify@example.com
Password: 创建用户时设置的密码

使用 swaks 测试:

1
sudo apt install swaks
1
2
3
4
5
6
7
8
9
swaks \
--server mail.example.com:587 \
--tls \
--auth PLAIN \
--auth-user notify@example.com \
--auth-password 'YOUR_STRONG_PASSWORD' \
--from notify@example.com \
--to your@email.com \
--header "Subject: Chasquid delivery test"

提交成功不等于远端邮箱一定已经收下。还要看 Chasquid 队列和日志:

1
journalctl -u chasquid --since "10 minutes ago" --no-pager

如果投递成功,会看到类似:

1
2
3
Queued from notify@example.com to [your@email.com] - MESSAGE_ID
MESSAGE_ID from=notify@example.com to=your@email.com sent
MESSAGE_ID from=notify@example.com all done

队列应为空:

1
sudo find /var/lib/chasquid/queue -type f | wc -l

检查认证结果

进一步可以将测试邮件发送到 Gmail,然后查看原始邮件头中的:

1
Authentication-Results

理想情况下应该看到:

1
2
3
spf=pass
dkim=pass
dmarc=pass

如果邮件被收件方接受,但进入垃圾箱,通常要继续检查:

  • PTR 是否指向 mail.example.com
  • mail.example.com 是否正向解析回同一个 IP
  • SPF、DKIM、DMARC 是否都通过
  • 服务器 IP 是否在常见黑名单里
  • 邮件内容是否过于像营销或垃圾邮件
  • 验证码发送是否有频控,避免短时间大量重复邮件

关于 25 端口

Chasquid 作为邮件服务器直接投递到 Gmail、QQ、163 等收件方时,需要能从服务器连接对方 MX 的 TCP 25 端口。

可以测试:

1
nc -vz gmail-smtp-in.l.google.com 25

如果这里超时或被拒绝,说明你的 VPS、机房上游或网络策略可能限制了 outbound 25。此时应用仍然可以通过 587 把邮件提交给 Chasquid,但 Chasquid 可能无法继续投递到外部邮箱。

这种情况下有两个选择:

  • 向 VPS 服务商申请放行 outbound 25。
  • 使用外部 SMTP relay/smarthost,通过 587、465 或 2525 转发。

总结

对于只需要发送验证码和通知邮件的场景而言,Chasquid 是一个非常有吸引力的选择。

相比 Mailcow,它没有庞大的容器集群和复杂的邮件生态;相比 Postfix,它又拥有更现代、更容易理解的配置方式。整个部署过程中最容易踩坑的地方主要有几个:

  • chasquid.conf 使用 key: value,不是 key = value
  • 监听端口字段是 smtp_addresssubmission_addresssubmission_over_tls_address
  • DKIM 文件名要使用 dkim:SELECTOR.pem,DNS 记录名也要使用同一个 selector。
  • Let’s Encrypt 私钥必须让 Chasquid 运行用户可读。
  • /var/lib/chasquid 必须让 Chasquid 运行用户可写。
  • DNS、PTR、SPF、DKIM、DMARC 都要对齐。
  • 直接投递外部邮箱时,outbound 25 必须可用。

完成这些配置后,一个轻量级邮件发送服务器就具备了生产环境所需的核心能力。对于个人项目、小型 SaaS 服务以及内部系统,这样的方案通常已经足够。


基于 Chasquid 配置邮件发送服务器
https://xxyyue.pages.dev/2026/06/19/chasquid-mail-server/
作者
xxyyue
发布于
2026年6月19日
许可协议