Chinaunix首页 | 论坛 | 博客
  • 博客访问: 469685
  • 博文数量: 144
  • 博客积分: 5675
  • 博客等级: 大校
  • 技术积分: 1512
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-20 10:46
文章分类

全部博文(144)

文章存档

2014年(1)

2013年(1)

2012年(12)

2011年(39)

2010年(48)

2009年(29)

2008年(14)

我的朋友

分类: LINUX

2008-10-25 09:32:04

简介

Procmail 是一个邮件过滤工具,可以根据邮件的发信人、主题、长度以及关键字等对邮件进行排序、分类、整理等工作,特别是在你订阅了邮件列表的时候显得非常有用。

配置

基本配置

Procmail 的配置文件是 ~/.procmailrc 。配置非常简单,首先是一些选项,后面则是一些过滤规则:

# -*- Conf -*-

MAILDIR=$HOME/Maildir/

ORGMAIL=/var/mail/$USER

LOGFILE=$HOME/.maillog

SHELL=/bin/zsh

LOCKFILE=$HOME/.lockmail

VERBOSE=no

 

# webmaster always sends junk mail~~

:0

* ^From: webmaster@st\.zju\.edu\.cn

/dev/null

 

# all other mail goes to inbox

:0:

inbox/

值得注意的是,邮箱末尾的 / 告诉 Procmail 使用 maildir 邮箱格式,而不是 mbox 格式。

关于 recipe

Procmail 使用 recipe 来决定处理哪些邮件以及如何处理他们。一个 recipe 有这种格式:

:0 [flags] [ : [locallockfile] ]

flags 具体可以参见 man procmailrc ,后面如果加上冒号则表示对文件进行锁定,这样可以避免同时运行几个 Procmail 操纵相同的文件的时候造成混乱。

conditions * 开头,当然处理使用正则表达式进行匹配,还有其他可用的命令,例如以 < 开头可以检查邮件的长度是否小于给定的值。其他具体可以参见 man procmailrc

接下来是 action line 。如果以 ! 开头,则对邮件进行 forward 到指定的地址;如果是以 | 开头则是启动相应的程序;以 { 开头则可以指定嵌套的 recipe ;其他情况则被视为本地邮箱,如果是一个目录,则表示 maildir 格式,否则是 mbox 格式。

一个例子

最近 MSTC 内部组建了一个邮件列表,凡是发送到 的邮件都会被自动投递给 MSTC 的每一个成员,可是萝卜时常在外网,不方便使用内网邮箱,正好我这里有 VPN 连接,可以同时连接到内网和外网,所以我决定对邮件进行 forward

首先是要把我受到的 allmstc 的邮件列表 forward 到萝卜的外网邮箱,观察 allmstc 的邮件列表的邮件头可以找出一个合适的匹配的正则表达式:

:0:

* ^X-MDMailing-List: allmstc@mstczju.org

{

     :0 c

     ! yujiazi@gmail.com

 

     :0:

     mstc/

}

可以看到,所有匹配到的邮件进入嵌套的下一轮匹配,首先是 forward 到萝卜的外网邮箱,这里使用了 c 这个标志,表示对邮件进行拷贝,这样可以保证接下来的 recipe 能够继续处理这个邮件,否则我自己就收不到邮件了,于是下一个 recipe 我让 Procmail 把邮件放到我的 mstc 这个本地邮箱里面。

同时,为了让萝卜能够参与邮件列表的讨论,他把邮件发送到我的外网邮箱,并保证在主题里面有 [allmstc] 的字样,那么我就把这封邮件转发到 里面去:

:0

* ^To: pluskid.zju@gmail.com

* ^Subject.*\[allmstc\].*

! allmstc@mstczju.org

运行

要让发送给自己的邮件都经过 Procmail 过滤, 上讲了一个方法,只需要在主目录下面建立一个 .forward 文件,内容为:

"|IFS=' ' && exec /usr/bin/procmail || exit 75 #kid"

其中路径替换成自己 procmail 真正的路径,并把 kid 替换成自己真正的用户名即可。注意主目录的属性,如果不小心打开了组或者其他人的写属性,那么邮件服务器将会拒绝处理 .forward 文件。

这个应该是针对 Sendmail 的语法,我使用 ,试验了一下并不能正常运行,而且从 的日志可以看出有错误。我在 上对日志里面的出错信息进行了一番搜索以后得到了答案。

那怪异的语法是针对 Sendmail 的各种功能以及安全漏洞的,许多文档都给出那样的例子,以至于那甚至被认为是所有 MTA 正常行为了。对于 Sendmail ,如果两个用户的 .forward 文件的内容是一样的,就会出现问题。因为 Sendmail 会对邮件的 forward 进行优化,如果一个邮件同时发送到这两个用户,并且他们的 forward 地址都是一样的,就删除一个重复的。这样的行为对于 .forward 内容为电子邮件地址的情况是好的,但是对于用管道输出到程序的情况就不行了。因此人们总是在命令末尾加上一些垃圾信息”(例如自己的用户名) 来避免重复。

而其他的 MTA 总是能够区分不同用户的管道命令,因为除了对命令行进行比较以外,他们还对程序运行的 UID 进行比较。

Sendmail 调用一个 shell 来执行管道命令,这有可能出现安全漏洞,所以大家添加 IFS=' ' 一类的东西,试图控制局面。 自己进行命令行解析,所以不需要这个。

因此,在使用 的时候, .forward 里面的内容很简单:

|/usr/bin/procmail

阅读(1435) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~