bg-tutorials

如何在 Qmail 上安装 SSL 证书

本教程将向您展示如何在 Qmail 上安装 SSL/TLS 证书,Qmail 是最初由 D. J. Bernstein 编写的邮件传输代理。安装流程和 Qmail 多年来一直使用的方式相同:构建一个包含私钥、服务器证书和中间证书链的单个 PEM 文件,放置在 /var/qmail/control/servercert.pem,然后重启 Qmail。

开始之前:Qmail 是一个传统 MTA

Qmail 本身自 1998 年最初的 qmail-1.03 版本发布以来就没有更新过。D. J. Bernstein 在 2007 年将代码归入公共领域,但没有恢复开发。知名的社区分支 netqmail 于 2007 年发布了最终的 1.06 版本,此后十多年未再维护。活跃的现代继任者是 notqmail(当前版本 1.09,2024 年 5 月发布),它延续了错误修复和现代系统兼容性改进,同时保持与原版的即插即用兼容性。

对本指南同样重要的是:原生 qmail 并不支持 SSL/TLS。TLS 是通过以下两种第三方方式之一添加的:

  • 由 Frederik Vermeulen 编写的 qmail-tls 补丁,为 qmail-smtpd 添加了 STARTTLS 支持,并从硬编码路径读取证书:/var/qmail/control/servercert.pem。大多数现代 qmail 软件包(包括 netqmail 和 notqmail 构建版本、s/qmail 发行版以及许多供应商软件包)都自带了此补丁或等效功能。
  • 在 qmail-smtpd 前面使用 stunnel,在 465 端口(SMTPS)上用 TLS 封装连接。由于 TLS 终止发生在 Qmail 之外,因此这种方式适用于任何 qmail 构建版本。

如果您维护的是现有的 qmail 部署,以下步骤仍然适用。如果您正在从头搭建新的邮件服务器,请考虑改用 Postfix 或 OpenSMTPD:两者都拥有原生且维护良好的 TLS 支持以及活跃的安全团队。我们还有一份关于如何在 Postfix 上安装 SSL 证书的单独教程。

为 Qmail 生成 CSR 代码

如果您已经生成了 CSR 并从 CA 处收到了 SSL 文件,请直接跳到在 Qmail 上安装 SSL 证书部分。

CSR 代表证书签名请求(Certificate Signing Request):一段包含您域名和组织信息的编码文本。您需要将其提交给证书颁发机构(CA),以便对方验证您的请求并颁发证书。生成 CSR 的同时也会创建对应的私钥,该私钥保存在您的服务器上,并且是安装过程所必需的。您有两种方式:

用任意纯文本编辑器打开 CSR 文件,将整个代码块(包括 BEGIN CERTIFICATE REQUEST 和 END CERTIFICATE REQUEST 这两行)复制到订单表单的 CSR 字段中。请妥善保存私钥文件:您将在下一节中把它合并到 PEM 文件里。

在 Qmail 上安装 SSL 证书

验证完成后,CA 会通过邮件发送一个 ZIP 压缩包,其中包含您的 SSL 文件:主(服务器)证书和一个或多个中间(CA)证书。将压缩包解压到您的服务器上,然后按照以下步骤操作。

第 1 步:将密钥、证书和证书链合并为一个 PEM 文件

qmail-tls 补丁(以及 netqmail、notqmail 和 s/qmail 中的等效实现)从一个 PEM 文件中读取终止 TLS 所需的全部内容。请按以下顺序拼接文件:先是您的私钥,然后是您的服务器证书,最后是中间(CA)证书链。不需要包含根证书(客户端已经信任它)。在存放解压文件的目录下运行:

cat yourdomain.key yourdomain.crt yourdomain.ca-bundle > servercert.pem

如果您的 CA 提供的中间证书是多个单独文件而不是一个 .ca-bundle 文件,请在服务器证书之后依次列出每一个,末端证书在前,根签发的中间证书在后:

cat yourdomain.key yourdomain.crt intermediate1.crt intermediate2.crt > servercert.pem

在文本编辑器中打开生成的文件以确认结构。它应该看起来像这样,每个代码块周围都有真正的五连字符标记:

-----BEGIN RSA PRIVATE KEY-----
(the text of your private key)
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
(the text of your primary SSL certificate)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(the text of the intermediate CA certificate)
-----END CERTIFICATE-----

较新的密钥可能标记为 BEGIN PRIVATE KEY 而不是 BEGIN RSA PRIVATE KEY;两者都可以。密钥不能使用密码短语加密,因为 qmail-smtpd 在启动时会直接加载它,不会提示输入密码。如果您的 CA 颁发的是 ECDSA 证书,密钥块将是 BEGIN EC PRIVATE KEY;其他部分不变。

第 2 步:将文件移动到 Qmail 的控制目录

文件名和路径由 qmail-tls 补丁固定。将合并后的 PEM 文件移动到 Qmail 的控制目录中,并收紧其权限,因为它包含您的私钥:

sudo mv servercert.pem /var/qmail/control/servercert.pem
sudo chmod 600 /var/qmail/control/servercert.pem
sudo chown root:qmail /var/qmail/control/servercert.pem

所有者和组取决于您系统上运行 qmail-smtpd 的用户是谁。在标准的 netqmail 或 notqmail 安装中,通常是 qmaild 用户或 qmail 组,因此使用 root:qmail 配合 600 模式即可。在基于 vpopmail 的设置中,qmail-smtpd 以 vpopmail 身份运行,因此请使用:

sudo chown vpopmail:vchkpw /var/qmail/control/servercert.pem
sudo chmod 640 /var/qmail/control/servercert.pem

不管哪种方式,目标都是一样的:qmail-smtpd 进程必须能够读取该文件,而其他任何用户都不应有此权限。

第 3 步:针对自定义构建进行调整

大多数 qmail 变体都在默认位置查找证书,但也有少数使用环境变量代替。请根据您的构建版本进行匹配:

  • 带有 qmail-tls 补丁的原生 qmail(netqmail / notqmail / 供应商软件包):无需进一步配置。qmail-smtpd 会自动读取 /var/qmail/control/servercert.pem。要让 qmail-smtpd 在 EHLO 响应中通告 STARTTLS,必须在 qmail-smtpd 运行脚本(通常是 /var/qmail/supervise/qmail-smtpd/run)中设置 UCSPITLS 环境变量:在 qmail-smtpd 那一行之前导出 UCSPITLS=””。若要求在认证之前必须加密,还需设置 FORCE_TLS=1。
  • 带有 ucspi-ssl 的 s/qmail:证书路径不是硬编码的。请在您的 qmail-smtpd 运行脚本(或对应的 tcpserver / sslserver 包装器)中设置以下环境变量:CERTFILE 用于服务器证书,KEYFILE 用于私钥(两者可以指向同一个合并后的 PEM 文件),以及 CERTCHAINFILE 用于中间证书。有关您所用版本的具体指令名称,请参阅 s/qmail 文档。
  • stunnel 前端(465 端口的 SMTPS):将 stunnel 的 cert 指令指向 /var/qmail/control/servercert.pem,并让其 exec 启动 qmail-smtpd。这种方式完全不需要 qmail-tls 补丁;TLS 在 stunnel 处终止。

如果您不确定您的 qmail-smtpd 是用哪个补丁构建的,可以检查二进制文件:

strings /var/qmail/bin/qmail-smtpd | grep -iE 'tls|starttls|servercert'

如果您看到有关 STARTTLS、servercert.pem 或 UCSPITLS 的引用,说明该二进制文件已编译进 qmail-tls 补丁。

第 4 步:重启 Qmail

Qmail 在进程启动时读取证书,因此需要重启 qmail-smtpd。在大多数使用附带的控制脚本的安装环境中:

sudo qmailctl restart

如果您的发行版是将 Qmail 包装成 systemd 服务,请使用:

sudo systemctl restart qmail

在 daemontools / runit 设置中,请改为通过 svc 向 qmail-smtpd 发送 TERM 信号:

sudo svc -t /service/qmail-smtpd

启动过程中请留意日志(通常是 /var/log/qmail/smtpd/current)中的错误。格式错误的 PEM 文件或所有权不正确是 qmail-smtpd 拒绝启用 TLS 的最常见原因。

测试您的 SSL 安装

使用 OpenSSL 确认 Qmail 是否提供 STARTTLS 并展示正确的证书。将 mail.yourdomain.com 替换为您的邮件服务器主机名:

openssl s_client -starttls smtp -connect mail.yourdomain.com:25 -servername mail.yourdomain.com </dev/null 
| openssl x509 -noout -issuer -subject -dates

输出应打印出您证书的主体(通用名称)、颁发者(CA)和有效期。如果您改为通过 stunnel 在 465 端口设置了 SMTPS,请去掉 -starttls smtp,直接连接到 465 端口:

openssl s_client -connect mail.yourdomain.com:465 -servername mail.yourdomain.com

在握手过程的末尾查找 Verify return code: 0 (ok)。如果您看到证书链错误,说明中间证书没有包含在 servercert.pem 中:请添加它们并重启 qmail-smtpd。如需查看证书、证书链和协议支持的完整报告,请对您的邮件主机名运行我们的 SSL 检测工具。

常见问题

Qmail 从哪里读取 SSL 证书?

从文件 /var/qmail/control/servercert.pem 读取。该路径硬编码在为 qmail-smtpd 添加 STARTTLS 支持的 qmail-tls 补丁中,每个常见的 qmail 变体(netqmail、notqmail、供应商软件包)都使用同样的路径。该文件必须依次包含私钥、服务器证书和中间证书链。使用 ucspi-ssl 的 s/qmail 是个例外:它改为读取 CERTFILE、KEYFILE 和 CERTCHAINFILE 环境变量。

servercert.pem 中各文件的放置顺序是怎样的?

先是私钥,然后是服务器(末端)证书,最后是中间 CA 证书。不需要根证书,因为邮件客户端已经信任它。一行命令即可构建:
cat yourdomain.key yourdomain.crt yourdomain.ca-bundle > servercert.pem
如果顺序不对,qmail-smtpd 将无法在启动时加载证书,也就不会提供 TLS。如果您怀疑是这个问题,请检查 /var/log/qmail/smtpd/ 下的日志。

原生 qmail 支持 TLS 吗?

不能单独支持。1998 年发布的原始 qmail-1.03 版本没有 SSL 或 TLS 支持。TLS 是通过 qmail-tls 补丁(编译进 qmail-smtpd 二进制文件,在 25 和 587 端口添加 STARTTLS)或在 qmail-smtpd 前面运行 stunnel(用于 465 端口的 SMTPS)来添加的。几乎所有现代 qmail 软件包都已经预先应用了 qmail-tls 补丁,因此您通常不需要自己修补源代码。

Qmail 是否仍在维护?

原始 Qmail(qmail-1.03)自 1998 年以来就没有更新过。第一个社区分支 netqmail 于 2007 年发布了最后的 1.06 版本。活跃的现代继任者是 notqmail,它在 2024 年 5 月发布了 1.09 版本,并持续提供错误修复和现代系统兼容性补丁。对于新的邮件服务器,大多数运维人员会选择 Postfix 或 OpenSMTPD,两者都拥有原生且积极维护的 TLS 支持。

为什么 qmail-smtpd 启动了但不提供 STARTTLS?

通常有三个常见原因。第一,qmail-smtpd 运行脚本中没有导出 UCSPITLS 环境变量:请在 qmail-smtpd 那一行之前设置 UCSPITLS=””(值可以为空)并重启服务。第二,qmail-smtpd 二进制文件在构建时没有加入 qmail-tls 补丁:可以用 strings /var/qmail/bin/qmail-smtpd | grep -i tls 来确认。第三,/var/qmail/control/servercert.pem 文件缺失、qmail-smtpd 用户无法读取,或者格式不正确;请检查权限以及 PEM 代码块的顺序。

重启 Qmail 之后如何验证证书?

使用 OpenSSL 连接到 SMTP 端口,读取 Qmail 通过 STARTTLS 展示的证书:
openssl s_client -starttls smtp -connect mail.yourdomain.com:25 -servername mail.yourdomain.com </dev/null | openssl x509 -noout -issuer -subject -dates
这会打印出主体、颁发者和有效期。如果是通过 stunnel 在 465 端口实现的 SMTPS,请去掉 -starttls smtp 参数。请确认颁发者与您的 CA 一致,并且握手结果显示 Verify return code: 0 (ok)。

立即订购 SSL 证书, 可节省 10% 的费用!

快速发行, 强大加密, 99.99% 的浏览器信任度, 专业支持和 25 天退款保证. 优惠券代码 SAVE10

龙飞行的详细图像
撰写人

经验丰富的内容撰稿人, 擅长 SSL 证书. 将复杂的网络安全主题转化为清晰, 引人入胜的内容. 通过有影响力的叙述, 为提高数字安全作出贡献.

Avatar of Sergiu Rosca
Technical Review by Sergiu Rosca

Sergiu Rosca is the core web developer behind SSL Dragon. He manages the technical infrastructure, platform performance, and backend integrations that keep the site running smoothly and securely. At SSL Dragon, Sergiu shares practical insights on web development, site optimization, and technical troubleshooting.

All SSL Dragon installation guides are tested on live server environments and undergo a strict peer-review process to ensure your infrastructure remains secure. Read our full Editorial Policy.