说明:
公司的邮件服务器经常收到垃圾邮件,通过查看/var/log/maillog日志看到有很多来源为bsoibsfs.com这种不规则,ping也ping不到的域名。如
Jul 28 07:40:37 FD10 postfix/qmgr[20316]: 5470414C83D6: from=
这主要是因为网路上有人通过搭建邮件服务器,任意伪造发件人地址,从而发送垃圾邮件。
要解决这个,可以通过配置邮件服务器支持 SPF,对每封进入的邮件进行SPF验证,过滤这些这种乱七八糟的域名。
SPF通过在域名中添加txt记录,向支持SPF功能的邮件服务器提供验证信息,心使别人能验证自己;另一方面也可以验证别人。配置spf需要会进行大量dns查询,因此邮件服务器的dns请选择离自己最近的dns。
解决:有两个兼容的策略模块给postfix使用,一个是用Python编写,另一种是用Perl编写的。Perl包满足最基本的要求,Python包配置复杂一点。
第一种方式:
1. 安装SPF模块(Perl)
# wget https://launchpad.net/postfix-policyd-spf-perl/trunk/release2.010/+download/postfix-policyd-spf-perl-2.010.tar.gz # perl -MCPAN -e 'install version' # perl -MCPAN -e 'install NetAddr::IP' # perl -MCPAN -e 'install Mail::SPF' # perl -MCPAN -e 'install Sys::Hostname::Long' # tar zxvf postfix-policyd-spf-perl-2.010.tar.gz # cd postfix-policyd-spf-perl-2.010 # cp postfix-policyd-spf-perl /usr/libexec/postfix/policyd-spf-perl
2. 配置Postfix支持SPF检查
# vi /etc/postfix/master.cf //添加以下内容: ## spf check policy-spf unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/libexec/postfix/policyd-spf-perl
# vi /etc/postfix/main.cf //添加以下内容: smtpd_recipient_restrictions = ......, check_policy_service unix:private/policy-spf
3. 重新载入postfix服务
# service postfix reload
4. 域名增加SPF记录:
给自己的域名添加TXT记录,含义:
*@dspam.org.cn账户只能在116.254.202.94的IP发送邮件,否则SPF验证不通过。
# dig -t txt dspam.org.cn dspam.org.cn. 600 IN TXT "v=spf1 ip4:116.254.202.94 ~all"
下面这条,是查找我自己的域名
# nslookup -query=txt gaingreat.com ;; Got SERVFAIL reply from 218.85.157.99, trying next server Server: 114.114.114.114 Address: 114.114.114.114#53 Non-authoritative answer: gaingreat.com text = "v=spf1 a mx ~all" Authoritative answers can be found from:
5. 配置成功后,Postfix的SPF检查日志如下:
# tail -10f /var/log/maillog postfix/policy-spf[15857]: Policy action=PREPEND Received-SPF: softfail (www.haiyun.me: Sender is not authorized by default //错误,可以看到softfail postfix/policy-spf[15726]: Policy action=PREPEND Received-SPF: pass (qq.com: Sender is authorized to use 'qq@qq.com' //#正确,pass
6. Policy-spy默认不阻止验证失败的发件人邮件,会在邮件头部添加Received-SPF: softfail标签,如果要对其处理可使用Postfix过滤规则header_checks进行匹配操作
# cat /etc/postfix/header_checks //添加header_checks匹配规则,拒绝未添加txt的域名,及txt认证不通过的 /Received-SPF: none/ REJECT /Received-SPF: softfail/ REJECT
7. 编辑主Postfix主配置文件应用此规则:
# cat main.cf header_checks = pcre:/etc/postfix/header_checks
8. 再次测试效果,这时再查看/var/log/maillog就可以看到以下这条记录,已经reject掉了
Jul 28 16:47:31 FD10 postfix/cleanup[9605]: 7408314C86BC: reject: header Received-SPF: none (smartech.com.tw: No applicable sender policy available) receiver=unknown; identity=mailfrom; envelope-from="qtaqw@smartech.com.tw"; helo=smartech.com.tw; client-ip=101.71.37.109 from unknown[101.71.37.109]; from=to= proto=ESMTP helo= : 5.7.1 message content rejected
第二种方式,这种方式我还没有尝试,有兴趣的可以去试下。
1. 安装SPF模块(python)
# wget https://launchpad.net/pypolicyd-spf/1.1/1.1/+download/pypolicyd-spf-1.1.tar.gz # tar zxvf pypolicyd-spf-1.1.tar.gz # cd pypolicyd-spf-1.1 # python setup.py build # python setup.py install
2. 配置Postfix支持SPF检查
# vi /etc/postfix/master.cf //添加以下内容: ## spf check policy-spf unix - n n - - spawn user=nobody argv=/usr/bin/python /usr/bin/policyd-spf
# vi /etc/postfix/main.cf //添加以下内容: smtpd_recipient_restrictions = ......, check_policy_service unix:private/policy-spf
3. 重新载入postfix服务
# service postfix reload
附录:
附录1:使用最新版的pypolicyd-spf,需要python-2.6以上版本支持
附录2:spf只能针对那些伪造的域名进行认证
如果来信地址为lalal@qq.com这种合法的且经过认证的,比如lalal@qq.com邮箱被盗,被拿来发垃圾邮件这种,则只能通过邮件内容过滤来过滤垃圾邮件。知道的spamlock这个插件,可以实现内容过滤,目前还没尝试!!!
附录3:spf会屏蔽没有做txt域名解析记录的域名,如果我们又需要接收他们的邮件怎么办。
这时就需要使用postfix的白名单黑名单。具体详见:postfix白名单黑名单
附录4:安装perl -MCPAN -e ‘install Mail::SPF’安装时,一直出现。导出Mail::SPF模块无法安装上
This package fails to build on current sid: t/00.00-class-misc.t .......... ok t/00.01-class-util.t .......... ok t/00.02-class-request.t ....... ok t/00.03-class-result.t ........ ok Unknown error on DNS 'A' lookup of 'example.com' (EDNSError) at /tmp/buildd/mail-spf-perl-2.9.0/blib/lib/Mail/SPF/Server.pm line 573. # Looks like you planned 23 tests but ran 19. # Looks like your test exited with 255 just after 19. t/00.04-class-server.t ........ Dubious, test returned 255 (wstat 65280, 0xff00) Failed 4/23 subtests [...] Test Summary Report ------------------- t/00.04-class-server.t (Wstat: 65280 Tests: 19 Failed: 0) Non-zero exit status: 255 Parse errors: Bad plan. You planned 23 tests but ran 19.
这可能是因为Mail::SPF需要调用的Net::DNS(版本>=0.75)跟libnet-dns-perl不太兼容。具体可以看 libnet-dns-resolver-programmable-perl: broken with newer Net::DNS
可以通过给Net::DNS打补丁,补丁在https://rt.cpan.org/Public/Bug/Display.html?id=95901,但我这补丁一直打不进去 – -,直接下载Net-DNS-0.72.tar.gz,旧版的Net::DNS直接编译安装,ok
# wget http://www.net-dns.org/download/Net-DNS-0.72.tar.gz # tar zxvf Net-DNS-0.72.tar.gz # cd Net-DNS-0.72 # less README # perl Makefile.PL # make # make install # perl -MCPAN -e 'install Mail::SPF'可以!