postfix增加spf过滤

说明:
公司的邮件服务器经常收到垃圾邮件,通过查看/var/log/maillog日志看到有很多来源为bsoibsfs.com这种不规则,ping也ping不到的域名。如
Jul 28 07:40:37 FD10 postfix/qmgr[20316]: 5470414C83D6: from=, size=14177, nrcpt=3 (queue active)
这主要是因为网路上有人通过搭建邮件服务器,任意伪造发件人地址,从而发送垃圾邮件。
要解决这个,可以通过配置邮件服务器支持 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'可以!

发表评论

邮箱地址不会被公开。 必填项已用*标注