![在 Postfix 中将功能实现为策略服务和 milter 有何区别?](https://linux22.com/image/791286/%E5%9C%A8%20Postfix%20%E4%B8%AD%E5%B0%86%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0%E4%B8%BA%E7%AD%96%E7%95%A5%E6%9C%8D%E5%8A%A1%E5%92%8C%20milter%20%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%EF%BC%9F.png)
我正在尝试使用 Postfix 实现 MTA。我对如何实现标准服务(如 SPF、DKIM 等)以及一些自定义服务感到困惑。它们可以作为策略委托服务实现并由 milters 调用check_policy_service
,smtpd
但我不知道哪种方法更合适以及为什么。
我认为策略服务将在应用范围方面提供更大的灵活性。文档还说策略服务还享有更广泛的操作列表,例如Defer
,Dunno
而这些操作列表不适用于 milter 操作。但 milter 的实现应该具有一些明显的优势。我想比较一下这两种实现类型。
答案1
对于大多数目的,包括基本消息认证检查(SPF、DMARC、BIMI 等),两种接口均适用。对于内容检查(阻止不需要的附件)、签名(DKIM、ARC)等,您需要一个可以为您提供该信息的界面,例如 milter 界面。
接口做提供大多数功能和基本操作,即两者都可以:
- 调查寄件地址、姓名和信封信息
- 永久拒绝(代码 5XX)或暂时推迟(代码 4XX 又名“tempfail”),可选择自定义 smtp 状态代码、扩展状态代码和(可能是多行)smtp 状态文本。
- 接收附加配置:
milter_macro_v
/policy_context
- 添加邮件标题(常见的选择是
Authentication-Results:
) - 安排一条消息进行静默丢弃或隔离,尽管发出了接受信号
该界面还分享一些限制,但具体细节有所不同:
- 您的软件在接收多收件人消息时不得出现故障
- 您的软件需要正确处理 IDN。(
xn--
域名中那些可爱的 A 标签) - 部分是由于其性质,部分是由于设计,两者都不接口允许以与处理 SMTP 提交相同的方式优雅地处理本地邮件投递(非 SMTP 提交)。
- 你的软件需要完成任务发送者在等待时——昂贵的处理、网络查找或不可靠的检查必须在某个时刻被中断,消息被推迟,并采取措施使其完成及时下次。
独特的 Milter 接口
milter 接口允许您解析并有选择地删除或重写任意标头或邮件正文(部分)。但是,最好在队列后处理、地址重写和多收件人陷阱中进行编辑。
无论如何,消息语法和编码功能都不能让你的软件出现问题。想想那些出了名的难以解析的地址标题和附件文件名。我还没有遇到过能 100% 正确完成此操作的软件。
如果您需要执行非默认 SMTP 命令,或者关心 SMTP 会话状态转换,则需要使用 milter 接口。在 milter 接口中,您可以处理诸如RSET
并(必须)相应地处理本地状态之类的事情 - 在策略接口中,postfix 使用有效的 protocol_state
。
当心:较温和的界面文档Postfix 对 sendmail 的目标还不明确错误兼容性以及它偏离的地方。此外,header hook 在过去被破坏过(在目前不受支持的版本中)。
Milters 通过(如果使用 C 库)返回固定SMFIS_*
代码(例如SMFIS_TEMPFAIL
,延期)向 postfix 发出最终决定的信号,但可能在此之前先进行一次smfi_setreply(…, "4XX", "4.X.X", text)
调用以定制返回。
策略守护进程接口独有
您可以选择限制类和守护进程之间的顺序 - 这比仅仅对过滤器与其他过滤器进行排序更加灵活。
defer_if_permit
如果您需要返回非 SMTP 结果(例如,或您的自定义),则需要使用策略接口。smtpd_restriction_classes
您需要这样做的情况包括出于性能考虑,需要跳过一些非常繁忙的服务器的检查。例如,当您的策略必须是,而不是成为可以接受或不接受的最终仲裁者时,只需选择一条消息班级在额外检查或路由决策中进行处理。
策略守护进程通过文本操作及其参数(如果适用)向 postfix 发出最终决定信号,例如action=DEFER optional text...
(这是一种更花哨的说法action=450 4.7.1 optional text...
)