我的 exim 服务器正在遭受持续攻击。我正尝试使用以下 acl 来延迟攻击尝试
deny condition = ${if and {\
{>{$rcpt_count}{10}}\
{<{$recipients_count}{${eval:$rcpt_count/2}}} }}
delay = 5s
message = Rejected for too many bad recipients
logwrite = REJECT [$sender_host_address]: bad recipient count high [${eval:$rcpt_count-$recipients_count}]
.endif
前 10 次尝试后会延迟一次。
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:34 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Unrouteable address
2023-09-10 12:14:39 REJECT [212.164.218.15]: bad recipient count high [11]
2023-09-10 12:14:39 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Rejected for too many bad recipients
2023-09-10 12:14:39 REJECT [212.164.218.15]: bad recipient count high [12]
2023-09-10 12:14:39 H=([212.164.218.15]) [212.164.218.15] F=<[email protected]> rejected RCPT <[email protected]>: Rejected for too many bad recipients
我希望它延迟每次后续尝试。我该如何实现?
答案1
我遇到了同样的问题/疑问,并做了一些研究和测试。
首先你需要知道的是,SMTP 最初是严格基于命令-响应的,这意味着客户端只能向服务器发送一个命令,并且必须等待响应才能发送下一个命令。由于这种来回往复每次都需要等待一段时间,因此会产生延迟,RFC 2920后来引入了“SMTP 管道”。这允许客户端批量向服务器发送多个命令,服务器处理这些命令并返回响应。在 exim 中,可以通过选项控制“SMTP 管道”的可用性pipelining_advertise_hosts
,默认情况下,该选项允许所有人使用。我认为您的配置也是如此。
我认为您的情况是,连接到您的 exim 服务器的客户端(又称垃圾邮件发送者)被告知它支持“SMTP 管道”,因此它发送了一批 100 条RCPT TO:
命令。您的服务器收到这些命令并开始处理它们,为每个收件人运行 acl acl_smtp_rcpt
。前 10 条命令都返回了一个550 Unrouteable address
响应,550
其中RFC5321 错误代码含义Requested action not taken
后跟一个人类可读的原因。该原因可以在 exim 中使用message
指令设置,并且也会在冒号后打印在日志中。客户端可能只是忽略了它们;毕竟它正在寻找有效的收件人。
处理第 11 个命令/收件人时,规则条件deny
被评估为真,exim 延迟(休眠)5 秒;这是您看到的一次延迟。之后,它将响应发送550 Rejected for too many bad recipients
给客户端。由于包含的(众所周知的)原因,客户端检测到它越界了,并且不再有机会找到有效的收件人;所有后续命令也将被拒绝。由于没有什么值得期待/获得的东西,它会终止连接而不等待其余的响应(并且可能立即转向下一个受害者)。当您的服务器注意到这一点时(因为使用了 TCP),它仍会继续处理命令批处理。但由于与客户端的 SMTP 连接已经终止,因此没有必要再延迟;它唯一会延迟的就是它自己。因此延迟将被忽略,您的服务器将运行命令,直到整个批处理完成。
如果客户端不终止连接,这将按您预期的方式工作:第 10 个收件人之后的每个收件人都会有 5 秒的延迟。
假设上述内容正确,我能想到的最佳解决方案是删除默认原因/消息。如果服务器只是继续响应类似 的内容550 Unrouteable address
,客户端就无法知道它是否越界并且无法保释。根据客户端的工作方式,将其更改/重新表述为与默认值不同的内容可能就足够了,这样就不会进行特殊处理。
或者,您可以使用上述选项在服务器中禁用“SMTP 管道”。客户端在看到第 11 个带有明显原因的答案后可能仍会中止,并且您的服务器仍然只会延迟一次,但至少您不会在日志中看到其他 89 个失败的收件人。明显的缺点是您“减慢”了每个客户端的速度,但可以通过仅为选定的“已知良好”客户端启用“SMTP 管道”来稍微改善这种情况。
顺便提一下:延迟不一定是静态值,也可以是表达式。这样就可以实现渐进式延迟,每增加一个无效接收者,延迟时间就会变长。邮件交换器的垃圾邮件过滤HowTo 中有一个例子。