跳转到主要内容

于 2025年04月22日 摘录自 Postfix Per-Client/User/etc. Access Control

Postfix 限制类

Postfix SMTP 服务器支持访问限制,例如 reject_rbl_clientreject_unknown_client_hostname。这使您能够为不同客户端或用户实施不同的垃圾邮件限制。

为每个收件人指定访问限制列表很快就会变得繁琐。Postfix 限制类允许您为一组 UCE 限制(如"宽松"、"严格"等)分配易于记忆的名称。

Postfix 限制类真正存在的理由更为实际:您无法在 Postfix 访问表的右侧指定查找表。这是因为 Postfix 需要提前打开查找表,但读者可能并不关心这些底层细节。

示例:

/etc/postfix/main.cf:
smtpd_restriction_classes = restrictive, permissive
# 在 Postfix 2.3 之前,请指定 reject_unknown_client。
restrictive = reject_unknown_sender_domain reject_unknown_client_hostname ...
permissive = permit
smtpd_recipient_restrictions = 
    permit_mynetworks
    # reject_unauth_destination 在此处无需设置,如果邮件
    # 通过 smtpd_relay_restrictions
    # 指定了中继策略(Postfix 2.10 及更高版本可用)。
    reject_unauth_destination
    check_recipient_access hash:/etc/postfix/recipient_access
    ...
/etc/postfix/recipient_access:
[email protected] permissive
[email protected] restrictive

配置完成后,您可以在客户端、HELO、发件人或收件人 SMTP 访问表的右侧使用 "restrictive" 或 "permissive"。

本文档的其余部分将通过示例说明如何使用 Postfix 访问限制类来:

这些问题经常被提出,示例希望能够明确指出 Postfix 限制类并非理想解决方案。它们应用于其设计用途,即为不同客户端或用户设置不同的垃圾邮件限制。

保护内部邮件分发列表

我们希望实现一个内部邮件分发列表。例如[email protected],该地址别名指向所有员工。我的第一想法是使用别名映射,但这会导致"所有"邮件可被"外部"访问,而这并非我们所期望的... :-)

Postfix 支持基于地址的访问控制。以下配置基于 SMTP 客户端 IP 地址,因此易受 IP 欺骗攻击。

/etc/postfix/main.cf:
smtpd_recipient_restrictions =
    ...
    check_recipient_access hash:/etc/postfix/access
    ...常规设置...
/etc/postfix/access:
[email protected] permit_mynetworks,reject
[email protected] permit_mynetworks,reject

如果您的系统使用 dbm 文件而非 db 文件,请将 hash 替换为 dbm。要查看 Postfix 支持的映射类型,请使用命令 postconf -m

如果您的机器直接从互联网接收所有互联网邮件,上述设置已足够。如果您的网络规模超过一个办公室,这种情况不太可能发生。例如,您的备用 MX 主机可能会"清洗"来自外部邮件的客户端 IP 地址,使其看起来像是来自受信任的机器。

在一般情况下,您需要两个查找表:一个表列出需要保护的目的地,另一个表列出允许向受保护目的地发送邮件的域名。

以下内容基于发件人 SMTP 信封地址,因此易受 SMTP 发件人伪造攻击。

/etc/postfix/main.cf:
smtpd_recipient_restrictions =
    ...
    check_recipient_access hash:/etc/postfix/protected_destinations
    ...常规设置...
smtpd_restriction_classes = insiders_only
insiders_only = check_sender_access hash:/etc/postfix/insiders, reject
/etc/postfix/protected_destinations:
[email protected] insiders_only
[email protected] insiders_only
/etc/postfix/insiders:
my.domain OK 匹配 my.domain 及其子域名
another.domain OK 匹配 another.domain 及其子域名

绕过此方案相对简单,因为只需伪造 SMTP 发件人地址即可。

如果内部列表流量较低,或许将其设置为受限列表更合理。

限制用户向外部目的地发送邮件

如何配置 Postfix 使部分用户能够向互联网发送邮件,而其他用户无法发送?无权限的用户应收到通用退信信息。请勿讨论此类访问限制的必要性,此决策非我所为。

Postfix支持按用户设置限制。这些限制由SMTP服务器实现。因此,违反策略的用户其邮件将被SMTP服务器拒绝。例如:

554 <user@remote>: 访问被拒绝

该实现使用了两张查找表。一张表定义了哪些用户在哪些位置发送邮件受限,另一张表定义了哪些目的地是本地。读者可自行将此方案修改为仅允许部分用户向外部目的地发送邮件,而大多数用户受限的方案。

示例假设使用DB/DBM文件,但也可通过LDAP或SQL实现。

/etc/postfix/main.cf:
smtpd_recipient_restrictions =
    ...
    check_sender_access hash:/etc/postfix/restricted_senders
    ...其他内容...
smtpd_restriction_classes = local_only
local_only = 
    check_recipient_access hash:/etc/postfix/local_domains, reject
/etc/postfix/restricted_senders:
foo@domain local_only
bar@domain local_only
/etc/postfix/local_domains:
this.domain OK 匹配 this.domain 及其子域
that.domain OK 匹配 that.domain 及其子域

如果您的系统使用 dbm 文件而非 db 文件,请将 hash 替换为 dbm。要查看 Postfix 支持的映射类型,请使用命令 postconf -m

注意:此方案不会验证用户身份,因此可通过多种方式绕过:

  • 通过使用权限较低的邮件中继主机发送邮件。
  • 以具有权限发送邮件到外部目的地的其他用户身份发送邮件。