使用过qmail的人一定会被qmail如此之多的patches所烦恼,现在终于有了解决的方法, Dr. Erwin Hoffmann 最近推出了一个叫 SPAMCONTROL Version 2.2 的新版本补丁,包含了众多qmail.org推荐和常用的补丁。所以现在只要打 SPAMCONTROL 就可以实现以下功能。
Features of SPAMCONTROL:
- 邮件转发 | Relaying:
- Relaymailfrom support ("MAIL from:")
- 统一标准的 Bad* 过滤器 | Unified Bad* Filters:
- Wildcard HELO/EHLO Greeting filter
- Wildcard SENDER filter
- Wildcard RECIPIENT filter
- MIME 类型过滤 | MIME Type Filter:
- Signaturs of Base 64 encoded MIME types can be added on-the-fly in a cdb using qmail-newbmt
- The filter is triggered my means of the environment variabel $BADMIMETYPE
- DNS MX 记录检查 | DNS MX Lookups:
- DNS Lookup for SMTP SENDER envelope address (MFDNSCHECK)
Includes option to remove trailing blanks - DNS Lookup for hostname in SMTP HELO/EHLO Greeting (HELODNSCHECK)
- Nasty stuff:
- SMTP session may be closed in case of a filter condition!
- BLACKHOLED Sender for the notorious
- (E)SMTP 扩展 | (E)SMTP Extensions:
- SMTP SIZE extension [RFC 1870]
- E(SMTP) Authentication [RFC 2554] 改进了的(E)SMTP 认证!
- Recipient Whitelising Extension:
- Accept E-Mails on a (case-insensitive) per-user bases , instead per-domain
- Multiple User data-bases in cdb format
- User data-base fastforward compatible or to be constructed on-the-fly via qmail-recipients
- Controlling:
- Limitation for the number of "RCPT To:'s" per SMTP session
- Split Horizon evaluation of badhelo and badmailfrom filters (depending on $RELAYCLIENT)
- Tarpitting 限制本地认证用户一次性发送邮件数量的补丁
- Reverse Split Horizon mechanism:
Anti-spoofing for "MAIL from:" addresses for $RELAYCLIENTs (in particular if SMTP Authenticated) Very useful to identify backdoor/trojan infected hosts! - Enforcement for SMTP Authentication for particular senders!
- Enforcement of brackets for SMTP addresses
- 反弹邮件控制 | Controlling Bounces:
- NULLSENDER single RECIPIENT enforcement
- Limit size of bounces
- Russel Nelson's double bounce trim
- Extensible logging (via splogger or multilog ):
- Accepted and Rejected SMTP sessions
- Accepted and Rejected SMTP authentication attempts
- Performance enhancements (experimental):
- Bruce Guenter's Bigtodo patch
- Andre Oppermann's Runonce patch
- Larger input buffer for reading control files
- 一些常用的补丁 | Recommended patches:
- MOREIPME patch. 即 0.0.0.0 的patch
- gcc 3.2 / glibc <errno.h> macro
- qmail-local tab patch
- Bruce Guenter's QUEUE_EXTRA patch. 即 QMAILQUEUE patch
- sendmail patches
- qmail-smtpd giant Received-Header vulnerability patch
|
以上众多功能是不是很让人心动?按照作者的描述,这个补丁将大范围地修改qmail,所以建议大家务必在读完了作者的 ◆ detailed README 和 ◆ INSTALL instructions 以后再开始安装配置,这样你在你的参数设置(conf-spamcontrol)里面就知道哪些你要设置为 yes,哪些你要设置为 no 了。以下的安装过程仅仅是对 qmail-1.03进行补丁并编译。使得qmail完全地运行起来还要有很多诸如 ucspi-tcp , daemontools 之类的插件,在这里就不赘述了。
安装过程
包的下载地址:
路径:
• qmail-1.03 解压路径: /usr/local/src/qmail-1.03/ • SPAMCONTROL 解压路径:/usr/local/src/patches/spamcontrol-2212/ |
安装过程: ( "#"号开始的是命令,没有"#"的行为正常安装后输出的最后的内容)
# cd /usr/local/src/qmail-1.03 # cp /usr/local/src/patches/spamcontrol-2212/* \ /usr/local/src/qmail/qmail-1.03/ # vi conf-spamcontrol ( 进行修改配置 >> ) # ./spamcontrol.sh Installation of SPAMCONTROL 2212 (Build 2004126103914) finished at Fri Jun 11 16:36:30 CST 2004 <<< # qmailctl stop # make setup check ./install ./instcheck |
修改配置 conf-spamcontrol (这里指摘几个比较重要的地方)
locals=yes # 确定 RECIPEIENTS是对所有邮件进行地址检查,还是 queue_extra=yes # 是否安装 Bruce Guenter 的 qmail queue 补丁,如果你使用的是qmailscanner,这个补丁一定要打 |
我的qmail的qmail-smtpd的run文件
#!/bin/sh export PATH QMAILQUEUE TH=$PATH:/usr/local/bin:/var/qmail/bin QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" export PATH QMAILQUEUE export MFDNSCHECK="" export BADMIMETYPE="" #QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` QMAILDUID=`id -u vpopmail` QMAILDGID=`id -g vpopmail` MAXSMTPD=`cat /var/qmail/control/concurrencyincoming` LOCAL=`head -1 /var/qmail/control/me` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" -o -z "$LOCAL" ]; then echo QMAILDUID, NOFILESGID, MAXSMTPD, or LOCAL is unset in echo /var/qmail/supervise/qmail-smtpd/run exit 1 fi if [ ! -f /var/qmail/control/rcpthosts ]; then echo "No /var/qmail/control/rcpthosts!" echo "Refusing to start SMTP listener because it'll create an open relay" exit 1 fi ##### Add the rblsmtpd by using the BLS: sbl | sbl-xbl.spamhaus.org ##### by using uid and gid of vpopmail exec /usr/local/bin/softlimit -m 15000000 \ /usr/local/bin/tcpserver -H -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \ -u $QMAILDUID -g $QMAILDGID 0 smtp /usr/local/bin/rblsmtpd \ -r sbl.spamhaus.org /var/qmail/bin/qmail-smtpd \ /home/vpopmail/bin/vchkpw /bin/true 2>&1
|
我的一些control文件内容
我的 badmailfrom 文件 ( 要从特殊到一般排列 )
# Wildmat evaluates from least specific to most specific # 你的主机ip,为了防止仿造你的主机ip用 @12.34.56.78 # 你的主机的反向解析 *78.56.34.12.in-addr.arpa** *12.34.56.78* #这一行是 感叹号加一个空格,表示非空。 ! # 对不完整的mail from:地址的一些rules !*@*.* *%* *\ @* *@\ * |
我的 badhelo 文件
12.34.56.78 mydomain.com mail.mydomain.com localhost localhost* 192.168.* *12.34.56.78* *mydomain.com* |
我的 badrcptto 文件 (加一个 "!" 表示 whitelist )
# Wildmat evaluates from least specifc to most specific badaddress@mydomain.com *%* *\ *@* *@*\ * !*@*.* !*@mywhitelist.com |
或者使用以下方法可以做到拒绝本地和虚拟域名中不存在的邮件用户。
首先使用我的 vpopmail-alias2recipients 和 vpopmail-users2recipients 脚本列出所有的本地和虚拟用户名,然后在每个用户名前加上 "!" 号。在你的 badrcptto 文件里面按照以下方法填写即可。
# Wildmat evaluates from least specifc to most specific * !user1@yourdomain.com !user2@yourdomain.com !user2@yourdomain.com |
以上可以解决在虚拟域名中实现类似于 RECIPIENTS Extension 的功能,即:阻挡不存在的邮件地址。但是千万不要忘记在新建一个邮件地址的时候,更新你的 badrcptto。
我的 badmimetypes 文件
如果文件里面带有诸如 .pif .src 的文件,立刻被认定为非法邮件而阻止传送。 比如 病毒文件附件中有 .src 文件(其邮件的.src文件部分的前 9 个 base64 字符为 TVqQAAMAA ) 就阻止 。 这里我没有阻止掉.zip文件。
TVqQAAMAA TVqQAAMAA TVpQAAIAA TVpAALQAc TVpyAXkAX TVrmAU4AA TVrhARwAk TVoFAQUAA TVoAAAQAA TVoIARMAA TVouARsAA TVrQAT8AA VFZxUUFBT VkZaeFVVR # *.zip # UEsDBAkAA |
然后运行 qmail-newbmt 命令即可更新它的cdb。
这里要注意的是,不是说你拥有了这些文件,这些功能就可以起作用,而是要在linux的环境变量中设置相应的变量(就像设置开关一样,if <变量存在> then <运行>),设置的方法在 shell 中用 export 命令,或者添加在 qmail 的 qmail-smtpd/run 命令中即可。
注意看 README的 3.1, 检查使用每个过滤条件所必须具备的条件,
1. the environment variable $BADMIMETYPE="" is set 2. and the control file badmimetypes.cdb is populated and readable by qmail-smtpd . 3. the formerly possible definition of a particular badmimetype via $BADMIMETYPE="abcdefghi" has been removed. |
那么要使用 badmimetypes 就必须设置变量 $BADMIMETYPE="" ,设置变量的方法和 $MFDNSCHECK 一样。在 qmail-smtpd/run 添加以下一行,并重启qmail。
我的 RECIPIENTS Extension
所谓 RECIPIENTS Extension 就是在对 本地 (control/locals 内的域名)用户发送邮件的时候自动测试本地是否有这个用户,如果没有,就立刻阻止发送 ( 产生 SMTP 错误信息 ). 此脚本只对你的 /var/qmail/control/locals 里的域名 (例如 mydomain.com) 起作用。
使用这个补丁前需要列出你所有用户的完整邮件地址。可以使用 Spamcontrol 自带的脚本列出这个list。( 在 Spamcontrol 的解压目录下。)
建立你的 local RECIPIENTS (完整邮件地址)。 # qmail-pwd2recipients// 建立 local system users 列表。 # qmail-alias2recipients// 建立 qmail alias users 列表。(例如: postmaster, root). # qmail-users2recipients// 建立 qmail users 列表。(as per users/assign).
|
接着用命令 qmail-recipients 生成数据库。
# qmail-recipients 运行结果是将 /var/qmail/users/recipients 生成 /var/qmail/users/recipients.cdb |
编辑 /var/qmail/control/recipients 的内容,指定recipients数据库位置
(以上测试成功……但是由于我全是 Virtual Domain, 只能撤掉 locals 里面的内容。)
解释:如果你和我一样是使用 vpopmail,并且把所有的、即使是 mydomain.com 也设置为了虚拟域名的话,这个补丁可能对你没有什么用途。因为此 patch 缺乏在 vpopmail 下的运用。
The lookup is done for recipients whose domain part match an entry in control/locals and is not applied for virtual domains. |
但是如果结合使用 badrcptt ,使用以下脚本列出你在 vpopmail 的 domains 下面的所有用户的完整地址的话,可以实现这个功能。我对于在这个补丁目录下面的两个获得所有本地用户的脚本进行了修改。以下是脚本。 查看我的方法 >>
vpopmail-alias2recipients
vpopmail-users2recipients
:::::::::::::: vpopmail-alias2recipients :::::::::::::: #!/bin/sh QMAIL=/var/qmail VPOPMAIL=/home/vpopmail/domains for i in `ls -l $VPOPMAIL | grep ^d | awk '{print $9}'` do cd $VPOPMAIL/$i ls -l .qmail-*| grep -v .qmail-default | tr -s " " | awk '{print $9}' | awk -F- '{print 2"@localhost"}' | sed -e 's/localhost/'$i'/' | sort -u >> $QMAIL/users/recipients done :::::::::::::: vpopmail-users2recipients :::::::::::::: #!/bin/sh LANG=C QMAIL=/var/qmail VPOPMAIL=/home/vpopmail/domains for i in `ls -l $VPOPMAIL | grep ^d | awk '{print $9}'` do cd $VPOPMAIL/$i ls -l | grep ^d | awk '{print $9"@localhost"}' | sed -e 's/localhost/'$i'/' | sort -u >> $QMAIL/users/recipients done |
我的 tarpitcount 和 tarpitdelay 文件
这个补丁是 Chris Johnson写的 tarpit.patch. 该补丁统计 RCPT TO 的个数并根据 tarpitcount 里面设定的数字适当延迟响应超过这个数字的 SMTP 连接 'tarpitdelay' 秒。因此可以通过该补丁达到限制一次性发送电子邮件的数量 (地址栏里面有n个地址)的功效。
试想,如果你的用户贪图方便,在地址栏写了许多地址,一旦被SBL认定为 Spam 发信源的话,后果就会很严重。tarpitdelay里面给出来这个计数的上限,一旦达到上限就抛出错误。我自己测试了一下,tarpitcount 里面写 ” 3 ” 封, tarpitdelay 写 “ 100 ” 秒,在延迟100秒后发送成功!(文件内仅写数字,修改后运行 # qmailctl reload 立即生效。)
在 conf-spamcontrol 文件里面的默认设置为
tarpitting=yes # does it help? |
我的 DNS MX Checks
添加以下内容到 qmail-smtpd/run 文件中
或者 /etc/tcp.smtp 中 (这里我使用了qmail-scanner,大家的情况可能不一样。)
:allow, MFDNSCHECK="" ,QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" |
我的 8.1 Enforcing Particular "Mail From:" Envelope SENDER for $RELAYCLIENTs
这个限制规则是:对于你的信任区域,即同意 relay 的网段 ( 往往在你的 /etc/tcp.smtp 文件里面 有诸如以下的一行 ) , 如果用户以非 "mydomain.com" 的 sender ( 或者说 Reply to < 非mydomain.com > 时 ) 发信时,发出错误回应,使其发信失败。作者的介绍是可以防止木马服务器(我也不太懂...)等。
12.34.56.78:allow,RELAYCLIENT="",LOCALMFCHECK="mydomain.com", QMAILQUEUE="/var/qmail/bin/qmail-queue" |
注意,这个不是强制你的用户使用 SMTP 认证,而只是对同意 relay 的区域内,对这些受信用者的限制。 (设置方法有三种,都可以起到同样效果,详见README的8.1部分。)
看看成果吧~嘿嘿!
测试一 220 mydomain.com ESMTP helo mail.mydomain.com 250 mydomain.com mail from: myname@mydomain.com 250 ok rcpt to: myname@mydomain.com 550 sorry, your HELO/EHLO greeting is in my badhelo list (#5.7.1) quit 221 mydomain.com 失去了跟主机的连接。 测试二 220 mydomain.com ESMTP helo sina.com 250 mydomain.com mail from: myuser@12.34.56.78 250 ok rcpt to: myname@mydomain.com 553 sorry, your envelope sender is in my badmailfrom list (#5.7.1) quit 221 mydomain.com 失去了跟主机的连接。 测试三 220 mydomain.com ESMTP helo sina.com 250 mydomain.com mail from: myname@mydomain.com 250 ok rcpt to: others@sina.com 553 sorry, that domain isn't allowed to be relayed thru this MTA (#5.7.1) quit 221 mydomain.com 失去了跟主机的连接。 测试四 220 mydomain.com ESMTP helo sina.com 250 mydomain.com mail from: myname@mydomain.com 250 ok rcpt to: myname@mydomain.com 553 sorry, your envelope recipient is in my badrcptto list (#5.7.1) quit 221 mydomain.com 失去了跟主机的连接。 测试五 220 mydomain.com ESMTP helo sina.com 250 mydomain.com mail from: myname@mydomain.com 250 ok rcpt to: nouser@mydomain.com 553 sorry, no mailbox by that name (#5.7.1) quit 221 mydomain.com 失去了跟主机的连接。
测试六 在 /etc/tcp.smtp 里面添加了一条,即同意我的 IP relay ,即不需要 SMTP AUTH 。 12.34.56.78: allow, RELAYCLIENT="", LOCALMFCHECK="mydomain.com", QMAILQUEUE="/var/qmail/bin/qmail-queue" 这时我伪造我的 mail from 发邮件,服务器就显示错误 sender address. 220 mydomain.com ESMTP helo sina.com 250 mydomain.com mail from: myname@sina.com 250 ok rcpt to: myname@mydomain.com 550 sorry, invalid sender address specified (#5.7.1) quit 221 mydomain.com 失去了跟主机的连接。 测试七 我发了一封带有 pif 文件的邮件 ,以下是错误信息。 '552 sorry, the attachment is in my badmimetypes list (#5.6.0)' |
来看看战果吧
我统计了一下这几天被reject的垃圾或病毒邮件 reject_mail.txt,你也可以下载以下脚本去测试一下你的服务器reject了多少讨厌的垃圾病毒邮件。
###### List the rejected E-mails ###### # reject_mail_stat.sh v 0.1 Kreny 06/15/2004 3:05 FILE_PATH='/home/user/public_html/log' REJECT='reject_mail.txt'
printf "Statistics for rejected mails \n" printf "Last Update: $TODAY\n\nRejected by Spamcontrol:\n\n" > $FILE_PATH/$REJECT awk '/Reject/ {print $2 }' /var/log/qmail/smtpd/*| sort | uniq -c | sort -nr | awk -F: '{print $1": "$3" "$5}' >> $FILE_PATH/$REJECT printf "\n" >> $FILE_PATH/$REJECT awk '/Reject/ {print $2 }' /var/log/qmail/smtpd/* | awk -F: '{print "Totally "$1""}' | sort | uniq -c | sort -nr >> $FILE_PATH/$REJECT printf "\nRejected by SBL www.spamhaus.org:\n\n" >> $FILE_PATH/$REJECT awk '/rblsmtpd/ {print $2 }' /var/log/qmail/smtpd/*| sort | uniq -c | sort -nr >> $FILE_PATH/$REJECT printf "Done! \n"
|
如果对以上脚本感兴趣的话,看看我的 NULL.IDA 扫描者IP地址的统计脚本 也许会对你有些帮助。
总结:
网上在传的公安部4号令里面有许多关于邮件服务器的设置要求,推荐大家看一下何智强(He zhiqiang)的公安部4 号令达标之不完全手册 。这里对其中的要求和本文的对应 关系作一个罗列。
公安部4 号令中关于电子邮件服务器具备清理垃圾邮件的若干要求如下: (一)具备对发送垃圾电子邮件的特定网络地址、电子邮箱进行屏蔽的功能; (二)具备限制来自相同客户端网络地址的并发连接数量超过最大限制值的功能; (三)具备限制来自相同客户端网络地址的连接频率超过最大限制值的功能; (四)具备限制本地电子邮件用户一次性发送同一电子邮件发送数量的功能; (五)具备判别电子邮件虚假路由,对伪造虚假路由的电子邮件限制发送的功能; (六)具备关闭电子邮件服务器匿名转发或采取用户身份认证、电子邮件转发授权控制措施 的功能; (七)具备对大量群发、连发同样特征的已知垃圾电子邮件进行拦截的功能,其中特征指电 子邮件长度、信头字段、信体符合特定条件。
|
这里以何智强先生的解决办法为基础,结合本文做了小小的修改。我没有用其中的ACL/Policy Service 补丁,但是这个补丁是一个相当不错的patch,第一次在README里面看到中文,感觉很亲切的噢~~ ;-P
Qmail (一)具备对发送垃圾电子邮件的特定网络地址、电子邮箱进行屏蔽的功能; 通过设置 badfrom 可以达到对域及电子邮箱的屏蔽,通过 tcpserver 则可以屏蔽特定的网络地 址(ip 地址);
(二)具备限制来自相同客户端网络地址的并发连接数量超过最大限制值的功能; 如果是Linux,可以使用iptable 来限制并发数,具体请参考iptables 的手册及邮件列表。简 单的做法是编写一个简单的iptables 封/解封ip 脚本,定期(如每隔30 秒或1 分钟)检查网 络连接情况,将超过并发限制的ip 交由该脚本处理,限制该ip。 • 这里我曾经写了一个脚本,阅读病毒邮件或者垃圾邮件的IP地址,每1分钟更新Iptables,具体请看:应用:自动统计病毒邮件发信者IP并添加相应规则至iptables
(三)具备限制来自相同客户端网络地址的连接频率超过最大限制值的功能; 我个人认为在qmail的 control/concurrencyincoming 文件设置 最大并行 SMTP 连接数可以解决问题。 但是hzqbbc 在CU上面的意见是: 注意: 相同客户ip地址的并发数,和某个程序/端口的并发数限制是不同的。 qmail那个concurrencyincoming 的限制是后者。现在要求的是前者。
(四)具备限制本地电子邮件用户一次性发送同一电子邮件发送数量的功能; 该功能可使用 tarpit patch for qmail, 该补丁已经包含在 SPAMCONTROL Version 2.2.12 中。
(五)具备判别电子邮件虚假路由,对伪造虚假路由的电子邮件限制发送的功能; 使用qmail-acl_policy 补丁,通过补丁调用ACL/Policy Service 的相应模块组,限制了伪造路由、伪造来信人及其他伪造信息的电子邮件发送。 这里我不太懂~还需要学习基础知识,是不是DNS MA Check的另外一种解释?
(六)具备关闭电子邮件服务器匿名转发或采取用户身份认证、电子邮件转发授权控制措施的功能; 使用Spamcontrol 含有的 SMTP-AUTH补丁,为qmail 增加认证补丁可达到该效果。 注:Spamcontrol带的SMTP AUTH补丁是qmail-smtpd-auth-0.4.3 - 一个Krysztof Dabrowski's SMTP-Auth patch的改进版本 。 详见SMTP Authentication [Tutorial] 。
(七)具备对大量群发、连发同样特征的已知垃圾电子邮件进行拦截的功能,其中特征指电子邮件长度、信头字段、信体符合特定条件。 使用Spamassassin + maildrop 或 procmail 等可以达到该目的。 检查 信体 可以使用 Spamcontrol 的 badmimetypes; 检查 信件长度 可以使用 Spamcontrol 对 bounce 邮件的size控制:Limit size of bounces; 检查信头 (如果没有理解错误的话) 可以使用 Spamcontrol 的 bad* 类文件、 "Mail From:"控制等。
|
一些小提醒:
参考文档:
SMTP认证相关
• SMTP Authentication Tutorial 最新关于SMTP认证的整理
relay 测试网站
• http://members.iinet.net.au./~remmie/relay/ Open Relay Test
• http://www.abuse.net/relay.html
• The MAPS relay test is wrong
http://homepages.tesco.net./~J.deBoynePollard/FGA/maps-relay-test-is-wrong.html