在procmail中可以拒绝某些电子邮件吗?

让我们假设一个典型的设置,从sendmail调用procmail来过滤收到的电子邮件到正确的邮箱。 这样做,而传入的SMTP连接到sendmail仍然是活动的,或者是在电子邮件已被接受后完成?

如果前者然后我明白可能procmail返回给sendmail一个错误,以便sendmail答复错误代码,例如554 Transaction failed而接受SMTP数据 ,而不是通常的200?

在我的情况下,sendmail从别名数据库调用procmail,像这样的条目:

 theaddres: theaddres-somedomain-com.virtual theaddres-somedomain-com.virtual: |"/usr/libexec/sm.bin/someuser.virtual somedomain@theaddress" 

然后执行procmail脚本:

 root@mda:/etc/mail # less /usr/libexec/sm.bin/someuser.virtual /usr/local/bin/procmail -a $1 /usr/local/etc/procmailrc/someuser.virtual 

编辑:

添加更详细的解释。 首先,我想确定下面列出的基于维基百科例子的stream程是否可以在SMTP协议中使用。 如果是的话,那么如果这是可能的与procmail。 然后,如果没有(我猜是这样的话),如果存在一个实现(例如milter),在这个实现中是可能的。

 S: 220 smtp.example.com ESMTP Postfix C: HELO relay.example.org S: 250 Hello relay.example.org, I am glad to meet you C: MAIL FROM:<[email protected]> S: 250 Ok C: RCPT TO:<[email protected]> S: 250 Ok C: RCPT TO:<[email protected]> S: 250 Ok C: DATA S: 354 End data with <CR><LF>.<CR><LF> C: From: "Bob Example" <[email protected]> C: To: "Alice Example" <[email protected]> C: Cc: [email protected] C: Date: Tue, 15 January 2008 16:02:43 -0500 C: Subject: Test message C: C: Hello Alice. C: This is a test message with 5 header fields and 4 lines in the message body. Now this is what I would like to see: S (after receiving the first 2 lines out of 4): 452 Requested action not taken: insufficient system storage C: QUIT S: 221 Bye {The server closes the connection} 

因此,服务器停止接收电子邮件(例如,因为它在电子邮件中检测到序列“这是一个testing消息”),并回复给客户端一个错误。 在这种情况下,它是452,但它可能是有效的任何错误响应数据请求 。 而客户可能会或可能不会用QUIT回应,我不在乎。

这可能取决于如何在TCP级别上实现SMTP协议。 我可以限制从客户端收到的数据量,比如可以说是50个初始字节(例如通过限制TCP帧的大小)吗? 当客户端发送DATA的内容时,SMTP协议是否允许我回复错误?

另外,如果服务器在接收到DATA的初始部分之后有目的地断开连接(而不是试图向客户端发送错误),则在传输电子邮件时TCP连接被意外丢弃将没有什么不同。 一个行为良好的MTA会尝试重新连接并重新发送电子邮件,垃圾邮件发送者不会麻烦重试。

你所描述的是完全可行的,但Sendmail 在这种情况下产生一个反弹的信息; 这是协议devise的一部分。 这样做的方法是让Procmail放弃一个合适的退出代码,将退回原因通知给Sendmail。

例如,要返回“用户未知”错误,

 :0 * ^Received: from badhelo \(badhost \[10\.9\.8\.7\]\) by yourhost { EXITCODE=67 HOST= } 

EXITCODE指定要退出的返回代码,并重新分配HOST具有晦涩但logging良好的副作用,即立即中止Procmail。

有关更多详细信息,请参阅http://www.iki.fi/era/procmail/mini-faq.html#exitcode ,例如sysexits.h以获取实际退出代码的列表。

您将无法控制是否在SMTP交易完成期间或之后发生这种情况。 我从Sendmail仍然很受欢迎的回忆中得知,它实际上在收到消息的同时处理Procmail规则,但这是一个实现细节,可能取决于各种情况,也可能在版本之间进行更改。 无论哪种方式,SMTP是一个存储和转发协议; 如果事务失败,并且客户端已经断开连接,服务器将尝试连接回发送者的MX服务器来实现反弹。 (在某些情况下,这是不受欢迎的,例如,弹跳反弹不应该产生和传递。)

无论哪种方式,为了使Procmail能够处理任何事情,您将需要已经收到整个消息; 在这个晚期明确地拒绝SMTP DATA事务是毫无意义的,因为你不能撤消接收。 如果您希望在DATA完成后悄悄地丢弃消息,只需将其发送到/dev/null

也就是说,尽早拒绝是有益的。 如果您可以针对不好的发件人实施IP级别的阻止,那么在networking堆栈上会更简单和更温和。 (在我读“僵尸networking”的线条之间 – 你知道这些发送者是否被Spamhaus DNSBLs阻挡吗?)

我认为procmail是一个邮件接收后运行的本地邮件程序。 基本上,这是交付的下一步。 所以它不会影响接收邮件到sendmail进程的连接。 将电子邮件本地发送给其他本地用户时,请考虑另一个示例。 首先接受sendmail过程,如果其他本地用户丢失,则会通过另一封电子邮件收到错误消息。

你有没有考虑过使用milter(例如MIMEDefang.org milter)?
MIMEDefang行为由可定制的perl脚本控制。 应该可以根据消息内容在smtp会话中获得拒绝。 它也将使解决scheme可移植到其他MTA如Postfix。

经典的MIMEDefang示例包括拒绝具有高SpamAssassin(垃圾邮件)分数的邮件。 它可能单独阻止大多数这样的电子邮件。