A.12. 仅接受真实用户的退信

正如在 仅接受真实用户的退信 中讨论的那样,现在存在一个漏洞,使我们无法捕获发送给系统用户和别名的虚假 投递状态通知,例如postmaster. 在这里,我们介绍两种替代方法,以确保仅为实际发送外发邮件的用户接受退信。

A.12.1. 检查收件人邮箱

第一种方法在 acl_rcpt_to ACL 中执行。在这里,我们检查收件人地址是否对应于本地邮箱

  # Deny mail for users that do not have a mailbox (i.e. postmaster,
  # webmaster...) if no sender address is provided.  These users do
  # not send outgoing mail, so they should not receive returned mail.
  #
  deny
    message     = This address never sends outgoing mail. \
                  You are responding to a forged sender address.
    log_message = bogus bounce for system user <$local_part@$domain>
    senders     = : postmaster@*
    domains     = +local_domains
    !mailbox check

不幸的是,我们如何执行邮箱检查将取决于您如何投递邮件(与之前一样,我们提取收件人地址中第一个 "=" 符号之前的部分,以适应 信封发件人签名

由于在本地投递邮件的情况下,此邮箱检查重复了路由器中执行的某些逻辑,并且由于它特定于我们站点的邮件投递机制,因此对于我们中的完美主义者来说,这可能有点笨拙。因此,我们现在将提供另一种替代方法。

A.12.2. 在别名路由器中检查空发件人

您可能有一个名为system_aliases或类似的路由器,用于重定向发送给如下用户的邮件postmastermailer-demon. 通常,这些别名不用于外发邮件的发件人地址。因此,您可以通过向路由器添加以下条件来确保传入的 投递状态通知 不会通过它路由

!senders = : postmaster@*

一个别名路由器的示例现在可能如下所示

system_aliases:
  driver         = redirect
  domains        = +local_domains
  !senders       = : postmaster@*
  allow_fail
  allow_defer
  data           = ${lookup{$local_part}lsearch{/etc/aliases}}
  user           = mail
  group          = mail
  file_transport = address_file
  pipe_transport = address_pipe

尽管我们现在阻止了发送到某些系统别名的退信,但其他别名只是在影子化现有的系统用户(例如 "root""daemon" 等)。如果您通过accept驱动程序投递本地邮件,并使用check_local_user来验证收件人地址,您现在可能会发现自己将邮件直接路由到这些系统帐户。

为了解决这个问题,我们现在想在处理您的本地邮件(例如 local_user)的路由器中添加一个额外的条件,以确保收件人不仅存在,而且是 "regular" 用户。例如,如上所述,我们可以检查用户 ID 是否在 500 - 60000 范围内

  condition  = ${if and {{>={$local_user_uid}{500}}\
                         {<{$local_user_uid}{60000}}}\
                    {true}}

一个用于本地投递的路由器示例现在可能如下所示

local_user:
  driver           = accept
  domains          = +local_domains
  check_local_user
  condition        = ${if and {{>={$local_user_uid}{500}}\
                               {<{$local_user_uid}{60000}}}\
                              {true}}
  transport        = transport

请注意,如果您实施此方法,您的服务器对系统用户的虚假退信的拒绝响应将与对未知收件人的拒绝响应相同(在我们的例子中为 550 Unknown User)。