netqmail以及其open relay问题
很久很久以前,有个qmail版本叫做1.3,据说有非常严重的漏洞,叫做open relay,我也听说过好多次了,也看到过无数次这个问题的解决办法,但是一直没有在意这个问题,因为我没有来摆弄这个东东。
2天前,实习公司的老板听说他们的服务器有个open relay的问题,而且导致了邮件的延时,于是老板要求他们的网管立马解决这个问题。而我,则协助他解决这个问题。
在网上google了一把qmail,open relay这样的关键字,清一色的redhat6.x或者redhat7.x加上qmail 1.3,三种方法,限制ip,利用vpopmail的功能,打patch。
第一种方法不可行,第二种方法搞不清楚是怎么回事,不知道vpopmail怎么和smtpd扯上关系,于是采用第三种办法。
说说当时邮件服务器的环境:当时告诉我运行环境是redhat7.x,但是我现在发现运行环境是redhat9,ft,用的邮件服务器是netqmail1.0.5,当时告诉我是qmail。当时已经很冒失的打了qmail1.3的patch,所以说当时简直就是乱来的。
无奈之下只好慢慢阅读源码来查找问题所在,发现netqmail实际上已经添加了qmail1.3的那几种验证方式,然后调试到cmd5ckpw的源文件,发现这个代码根本不是为netmail而写的,这个程序读取了/etc/vpasswd,但是事实上netqmail+vpopmail的用户文件根本就不在这个目录,而且vpasswd的格式也完全不对。所以这个验证程序和补丁根本就不能在这里使用。
于是慢慢分析qmail-smtpd.c的源码,加上google,发现是否relay是在smtp_mail这个函数里面判断的,对应到命令的话就是调用处理mail from: a@b.c这样的命令,主要是判断了2个问题,一个是relayclient这个变量是不是1,这个是在auth命令里面处理的,如果成功就设定为1,另外一个问题是测试环境变量RELAYCLIENT这个环境变量有没有被设置,这个是google到的tcpserver处理的事情。再下来就是判断rcpthosts文件,这个文件包括了允许relay的服务器,这样可以防止别人无法发送邮件到你的服务器。
事情到这里有很清晰了,首先,在rcpthosts里面加入自己主机的名字,然后用tcpserver启动qmail-smtpd,这样可以让本地的机器可以不用验证来发送邮件(也就是预先设置RELAYCLIENT这个变量),对于其他的用户,那就验证吧。
下面的问题是怎么验证?事实上这个问题花了我最多的时间,因为刚开始就误入歧途,调试了半天cmd5ckpw。后来解决的办法就是,用vpopmail的vckpw来验证,用的密码文件就是用户的那个密码文件。写成命令就是一句话:/usr/local/bin/tcpserver -H -R -l 0 -t 1 -v -p - /home/vpopma
il/tcp.smtp.cdb -u qmaild -g nofiles 0 smtp /var/qmail/bin/qmail-smptd /bin/vchkpw /bin/true
有些文章说在qmail-smtpd后面写了4个参数的,那是乱写误人子弟啊。qmail-smtpd里面调用的是execvp(*childargs, childargs),如果返回0就成功。
最后附一个刚才我分析的smtpd的relay结构吧,
smtpd->helo---->auth(用vchkpw,relayclient=1?)->mail--if relayclient==1-->go ahead
smtpd->helo---->mail---->环境变量RELAYCLIENT是否设置(tcpserver)->go ahead
smtpd->helo---->mail----->in rcpthosts? ----->go ahead
差不多就这样吧,有错误还请指出来。