告诉 Postfix 在“中继访问被拒绝”后立即关闭连接

Shi*_*ker 3 postfix

我在一些设置良好的邮件服务器上看到过,它们会在出错后立即终止连接

454 4.7.1 <spammer@spamserver.com>: Relay access denied
Run Code Online (Sandbox Code Playgroud)

这可能会节省大量资源和流量。而且我的 Postfix 仍然为将来的命令打开 SMTP 会话,这些命令可能只是垃圾邮件。

在向垃圾邮件发送者提供此错误后,如何告诉 Postfix 立即终止会话(如那些智能服务器)?

信息

  • 后缀版本 2.10.1

  • 输出 postconf -n

    [root@mail ~]# postconf -n
    config_directory = /etc/postfix
    header_checks = pcre:/etc/postfix/header_check
    inet_protocols = ipv4
    local_recipient_maps =
    mydestination = example.com, $myhostname, localhost.$myhostname, $mydomain, localhost.$mydomain
    mydomain = example.com
    myhostname = mail.example.com
    mynetworks = 127.0.0.0/8 10.0.0.0/16
    myorigin = example.com
    relay_domains = example.com
    smtpd_banner = $myhostname ESMTP
    smtpd_recipient_restrictions = 
        permit_mynetworks, 
        reject_unauth_destination, 
        reject_invalid_hostname, 
        reject_unauth_pipelining, 
        reject_non_fqdn_sender, 
        reject_unknown_recipient_domain, 
        reject_unknown_sender_domain, 
        check_sender_access hash:/etc/postfix/access
    smtpd_sender_restrictions = 
        check_recipient_access hash:/etc/postfix/recipients,
        reject_non_fqdn_sender,
        reject_rhsbl_sender blackhole.securitysage.com,
        reject_unknown_sender_domain
    transport_maps = hash:/etc/postfix/transport
    
    Run Code Online (Sandbox Code Playgroud)

mas*_*oeh 5

关于这个问题,我有好消息和坏消息要告诉你。

好消息是 Postfix 确实有一种机制,可以在客户端行为不端时断开连接。它记录在此页面上。三个参数控制行为:smtpd_soft_error_limitsmtpd_hard_error_limitsmtpd_error_sleep_time。这个伪代码将说明它是如何工作的。

While smtpd get connection from client
    error_counter = 0

    if there ERROR* in SMTP transaction
        error_counter = error_counter + 1

    if error_counter > $smtpd_soft_error_limit
        show the error message with delay $smtpd_soft_error_delay
    else if error_counter > $smtpd_hard_error_limit
        DISCONNECT client
    else
        show the error message IMMEDIATELY

    if one message transfered successfully
        error_counter = 0 //reset the counter
Run Code Online (Sandbox Code Playgroud)

注意:在后缀术语中,ERROR*当客户端请求未被识别或未实现、客户端请求违反访问限制或发生其他错误时触发。

看,如果我们设置为smtpd_hard_error_limit1,则 postfix 会很乐意在发生错误时断开客户端。

坏消息是我们无法过滤触发 smtpd_hard_error_limit 的错误。您将这种断开连接行为限制为Relay Access Denied错误的意图无法实现。设置smtpd_hard_error_limit为 1 后,每个错误都像

Recipient access rejected, user not Found
Run Code Online (Sandbox Code Playgroud)

或者

Sender address rejected: Domain not found;
Run Code Online (Sandbox Code Playgroud)

将导致客户端断开连接。后缀文档说明了当smtpd_hard_error_limit = 1.

在压力大的情况下,使用 1 的 smtpd_hard_error_limit 而不是默认的 20。这有助于在单个错误后断开客户端连接,让其他客户端有机会连接。但是,这可能会导致合法邮件的严重延迟,例如邮件列表中包含一些不想取消订阅的不再活跃的用户名。只要此措施只是暂时使用,就不会丢失任何邮件。


替代方案

对于类似僵尸客户端的替代解决方案,您可以在 postfix 中启用 postscreen。Postscreen 会为 smtpd 进程添加一层,因此服务器应该处理合法的客户端。请参阅此处此处的文档


为什么我的服务器显示错误 4XX 而不是 5XX?

Postfix 2.10 引入了一个名为smtpd_relay_restriction. 您可以阅读postconf(5) 中的文档。默认情况下,此参数具有值

smtpd_relay_restrictions = 
    permit_mynetworks 
    permit_sasl_authenticated 
    defer_unauth_destination
Run Code Online (Sandbox Code Playgroud)

参数defer_unauth_destination将抛出错误 4xx 而不是 5xx。

最好的建议是将限制拆分为两个参数 smtpd_relay_restriction 和 smtpd_recipient_restriction。但是,如果您坚持保留旧配置(例如仅在 smtpd_recipient_restriction 中),您可以将 smtpd_relay_restriction 设置为空main.cf

smtpd_relay_restriction = 
Run Code Online (Sandbox Code Playgroud)