linus2k

君子常当当的博客

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  41 随笔 :: 1 文章 :: 21 评论 :: 0 Trackbacks

Postfixheader_checks/body_checks功能补充说明(if-endif)

 

适用于regexpheader_checks

语法:

if /regexp pattern 1/

/regexp pattern 2/

endif

 

应注意事项:

1. 不要在Windows下打好字再copy-paste,有可能有换行字符产生的错误;

2. 换行方式要严格依照上述结构,也不要为了美观而去缩排或加空格,不然Postfix会不接受(ignoring extra text after IF)

 

补充:

1. 如果你要match『否定』的pattern,那可以用 !/regexp pattern/ DISCARD,其中「!」就代表「与这个正规表示式相match的被排除适用;

2. 如果你要比对多个pattern,可以用 /(pattern_1|pattern_2|pattern_3)/,当然,!/(pattern_1|pattern_2|pattern_3)/也是可以的

 

以上,是根据资料和正规表示式所得到的结论。但是呢,天下没有这么简单的事,我的情况是,我要指定某些账号只接受某些特定寄件者的信,所以我的/etc/postfix/header_checks这样写:

if /^To:.*test@mail\.domain/

!/^From:.*(valid_mailbox1|valid_mailbox2|valid_mailbox3)/ DISCARD

endif

现在,问题来了,所有寄给这个信箱的信都被DISCARD了,为什么呢?

 

我试过简化版:(不用(|) )

if /^To:.*test@mail\.domain/

!/^From:.*valid_mailbox3/ DISCARD

endif

逻辑:从valid_mailbox3以外的信箱寄到test的信都应该被discard

实际:Postfixdiscard所有寄到这个信箱的信!

 

以及简化版二:(不用反义 ! )

if /^To:.*test@mail\.domain/

/^From:.*valid_mailbox3/ DISCARD

endif

逻辑:只有从valid_mailbox3的信箱寄到test的信才会被discard

实际:Postfix接受任何寄到这个信箱的信!

 

我崩溃了

 

其实答案就在这里

http://www.postfix.org/header_checks.5.html

 

"These rules operate on one logical message header or one body line at a time, and a decision made for one line is not carried over to the next line"

这些规则一次只检视一条表头(header_checks规则)或一行内文(body_checks规则),你不能把某一行的检查结果带到另一行去。

 

换句话说,假如我们订定一个检查规则,要求比对两个pattern

if /^From:.*sender@thatdomain/

/^To:.*recipient@thisdomain/ DISCARD

endif

only & only if有一行标头『同时符合』这两个patternPostfix才会对这个邮件执行DISCARD。而很明显的,不可能有哪一行文字『同时』以FromTo作起头,所以,这个DISCARD永远不会被执行!这个规则语法100%正确、实际上效果是0

 

再讲明确一点,在Postfixheader_checks检查邮件标头时,不管你要比对几个pattern,这几个patterns「必须位于邮件标头的同一行」才有效。

 

范例:

if /^Content\-Type:.*audio.*x\-midi/

/^.*name\=.*\.scr/ DISCARD drop the header inavalid

endif

并没有错,只是你必须注意,这个规则只对下面这一行标头生效:

Content-Type:*audio.*x-midi*name=*.scr (在此,*代表零或多个字符)

不是,重复一次,不是下面这样:

1. 发现Content-Type:*audio.x-midi*

2. 找寻标头档内其它地方还有没有*name=*.scr

3. 若有,抛弃这封邮件。

~~的!

 

此外,该文还说:

"Message headers added by the cleanup(8) daemon itself are excluded from inspection. Examples of such message headers are From:, To:, Message-ID:, Date:.

 

Message headers deleted by the cleanup(8) daemon will be examined before they are deleted. Examples are: Bcc:, Content-Length:, Return-Path:. "

cleanup程序所撰写的邮件标头(From:, To:, Message-ID:, Date:)不会被header_checks检查,cleanup程序所删除的邮件标头(Bcc:, Content-Length:, Return-Path:)仍然会被header_checks检查。

 

这也就是说,header_checks根本不可能检查到From: xxxx@nowhere.comTo: yyyy@everywhere.com这种header,你可能会奇怪为什么在mbox中明明可以看到这些headersheader_checks规则却死也找不到? well,因为这两个headers连同Date:,都是cleanup程序写的,而在cleanup接手前,header_checks已经完成了它的工作了。

 

Postfix而言,一封邮件在写进mbox档前,经过smtpdpickupcleanuptrivial-rewrite程序的处理,已经不是header_checks所看到的那样了,所以『按图(mbox)索骥(mail headers)』是很有可能失败的。

 

不知道什么是cleanup程序的人,请去翻O'ReillyPostfiix技术手册第三章。(不难,非常易懂)

 

所以呢,为什么简化版一会失败?

因为,Postfix收到邮件时检查,发现了有一行标头符合/To:.*test@mail\.domain/pattern,而这一行『不符合』/^From:.*valid_mailbox3/pattern,所以 !/^From:.*valid_mailbox3/ = TRUE/To:.*test@mail\.domain/ = TRUE,所以规则生效,DISCARD

posted on 2010-12-17 09:39 君子常当当 阅读(1932) 评论(0)  编辑 收藏 引用 所属分类: 邮件技术纪念记忆力衰退
只有注册用户登录后才能发表评论。