摘要

  • 在 Postfix 的特权主进程模式下,多数服务先打开必要文件,再于处理请求前永久放弃 root;四种投递服务会保留已保存的 root 身份,以完成范围受限的操作。
  • 无特权主进程降低了监督进程的权限,却削弱了内部隔离;服务遭入侵后,可接触的密钥与日志更多,而且该模式只适用于少数生产配置。

问一台邮件服务器“是否以 root 运行”,很难说明真正的风险。Postfix 的设计提示了更具体的判断方式:哪个进程在请求的哪个阶段需要何种权限?它能读写哪些文件,又能代表哪些用户操作?

SMTP 或 QMQP 消息首先进入面向网络的 Postfix 服务。服务检查输入后,把信封和正文交给 cleanup(8)。cleanup 完成入队前的最后处理,将邮件写入 incoming 队列,并通知 qmgr(8)。队列管理器再选择投递代理。它只维护容量受限的 active 队列,因此积压增加时,不必一次打开所有待投递邮件。常驻的 master(8) 负责监督服务、按需启动进程,并执行配置中的进程数量限制。

监督进程与处理请求的服务承担不同工作。在 Postfix 的特权主进程模式下,服务可以先以 root 权限启动,读取 TLS 私钥、数据库密码等敏感文件,再于处理请求前不可逆地放弃 root。Postfix 的安全文档指出,如果服务在放弃权限后遭到入侵,它将无法再打开这些敏感文件、数据库或日志。因此,root 权限用于初始化和权限分配,并不意味着每个网络服务进程在整个生命周期内都拥有 root。

这个模型有例外。多数服务会彻底放弃 root;local(8)、pipe(8)、spawn(8) 和 virtual(8) 则保留已保存的有效 root 身份。它们需要据此切换到目标用户,或操作 Postfix 以外的资源,例如用户邮箱或外部命令。Postfix 区分两种用途:root 可以在 Postfix 内部划分服务权限,也可以在服务触及用户文件或外部程序时提供权限约束。“root 进程”这个笼统说法会掩盖这两条不同边界。

Wietse Venema 在 2010 年的 LISA 演讲中把 Postfix 描述为分区式最小权限架构。他提到,一种防火墙设计曾以低权限、chroot 的进程分隔邮件接收与投递,这是 Postfix 的影响来源之一。他还说明,建好通信基础设施后,把功能拆成小程序有助于维护。这是对当时设计思路的回顾,并非目前的守护进程数量,也不是安全成效的测量。现在的 Postfix 架构文档则具体展示了接收、清理、队列管理和投递服务如何分工。

近期变化并不是在宣称“主进程不再是 root,整套系统就一定更安全”。Postfix 文档记载,Venema 于 2025 年先为未发布的集成测试实现无特权 master(8);2026 年收到客户询问后,他才把它调整为有限的生产用途并补充文档。在这种模式下,master 固定以 postfix 用户运行。服务在初始化和处理请求时都使用同一组 Postfix 权限。项目说明,这样无法保留 Postfix 内部的权限分离,也无法维持访问外部文件、投递至用户邮箱或执行外部命令时原有的限制。

差异会落在具体文件权限上。Postfix 的密钥文件必须能由 postfix 用户读取,因此服务一旦遭到入侵,就可能读出这些密钥。可选的 Postfix 日志须由 postfix 拥有,受损服务也就能查看、改写或删除日志。配置文件则不能归 postfix 所有。多实例安装也不能混用两种模式:要么每个实例都用特权主进程,要么全部使用无特权主进程。

生产使用边界很窄。Postfix 文档允许无特权主进程用于所有邮件都经 SMTP 或 LMTP 转发的部署;若本地服务可能执行 Postfix 之外的程序,或把邮件投递到邮箱文件,则明确禁止用于生产。文档举例说,用户 .forward 文件中的命令会以 postfix 权限运行,而非目标用户权限,可能使用户控制邮件系统。这个警告针对特定配置,但措辞明确。

架构上的结论不是“root 安全”或“root 危险”。更改权限会把风险从一条边界移到另一条边界。对于受限的中继部署,无特权主进程可能合适;但此时各服务共享对密钥和日志的访问,而特权模式可以在初始化后把这些资源隔离起来。运维人员应先梳理邮件如何投递,再决定是否更改主进程身份,并核对每个服务实际能触及的文件与命令。公开文档界定了这种取舍,却没有说明哪种模式更常见,也没有给出实际部署中的安全结果。

来源