我配置了一个 qmail 服务器,如果收件人没有在 rcpthosts 中列出,则拒绝邮件,并且我使用 tcp-env 与 xinetd 来允许本地进程向任何人发送电子邮件,并添加以下行/etc/hosts.allow
:
tcp-env: 127.0.0.1 : setenv RELAYCLIENT
在测试期间一切似乎都运行正常:
$ telnet mydomain.com 25
Trying xxx.xxx.xxx.xxx...
Connected to mydomain.com.
Escape character is '^]'.
220 mydomain.com ESMTP
HELO
250 mydomain.com
MAIL FROM: [email protected]
250 ok
RCPT TO: [email protected]
553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)
在现实生活中,队列中有很多这样的消息:
2744522 (1, remote)
Envelope Sender:
Envelope Recipient: [email protected] (To Be Delivered)
Date: 22 Apr 2014 07:38:14 -0000
From: [email protected]
To: [email protected]
Subject: failure notice
Size: 18.45KB (18889 Bytes)
QMail 应该为 rcpthosts 中列出的域发送失败通知,并且应该拒绝未列出的域的电子邮件而不发送失败通知。
谁能解释我做错了什么?
谢谢!
答案1
qmail 的一个缺点是,默认情况下,它在接受邮件之前不检查收件人地址的本地部分。它所做的只是检查收件人域是否在其允许的收件人域列表中。(这在 20 世纪 90 年代初期是一个合理的设计选择。现在不那么合理了。)这意味着,例如,垃圾邮件发送者使用字典喷洒,可以通过向不存在的收件人发送大量邮件来填满您的服务器。当 qmail 尝试传递邮件时,它会发现本地部分不存在,并会生成退回邮件。而且由于垃圾邮件发送者会伪造信封发件人,您的服务器将无法传递这些邮件,并且会填满队列。
最好的解决方案是首先不接受这些电子邮件。如果您的服务器可以立即拒绝电子邮件,那么发送邮件服务器的工作就是发出退回邮件,这样您就不会收到大量退回邮件。RCPT TO:[email protected]
另一个解决方案是减少 qmail 不断尝试发送退回邮件的时间,这样它们就会被尽早删除,从而也不会填满队列。
当然,您可以过滤传入的垃圾邮件并将其丢弃,而不是允许其产生退回。
拒绝未知的本地部分
实现此目的的唯一方法是修补 qmail,这样qmail-smtpd
将检查 localparts。您不能仅使用配置选项来执行此操作,您需要实际修补并重新编译和安装修补后的qmail-smtpd
。
有几个不同的补丁可以实现这一点。我不能推荐其中任何一个——当我管理 qmail 服务器时,我们有另一个系统充当代理,它执行过滤,所以我从来不需要使用它。但你可以在以下位置找到几个补丁netdevice.com/wmail/rcptck和code.dogmap.org/qmail/。
减少 qmail 尝试发送退回邮件的时间
如果这只适用于退回邮件,我不知道该怎么做。但您可以通过更改 的值来对所有邮件执行此操作queuelifetime
。man qmail-control
应该会告诉您如何操作。
垃圾邮件过滤
关于垃圾邮件过滤,要说的太多了,无法用一个答案来概括。我首先会考虑使用 RBL 样式的黑洞列表,并拒绝来自其中列出的 IP 地址的连接。当然,您需要谨慎选择黑洞列表,并且确实存在阻止“真实”邮件的风险。有关专门针对 qmail 的垃圾邮件过滤的一些信息,请访问Chris Hardie 的 qmail 反垃圾邮件指南,有关各种黑洞列表的信息请访问spamhaus.org。
我希望这些足以作为一个开始。我已经使用 qmail 几十年了,包括为拥有数百万用户的 ISP 运行邮件系统 - 但我还必须补充一点,如果我现在要设置这样的系统,qmail 将不再是我的首选。它在创建时是一个非常好的邮件服务器,它做了很多事情,但如今我可能会改用 postfix。时间和垃圾邮件发送者已经过去了,而 qmail 却没有。