/ 中存储网

邮件安全之Postfix服务器如何反垃圾邮件

2014-09-02 02:28:09 来源:中存储网

Postfix是一个非常优秀的MTA,她素以高效、安全的特点而著称。Postfix是作者在UNIX上所见过的MTA中在反垃圾邮件(Anti-Spam或Anti-UCE)方面做得最好的一个,甚至有很多公司在Postfix代码的基础上进行二次开发而推出反垃圾邮件网关产品。

MTA的反垃圾邮件功能,实际上就是在MTA处理过程中对会话进行过滤。这个过滤不但过滤了发往自身的垃圾邮件,而且还防止了自身被恶意利用发送垃圾邮件。Postfix实现了目前所有主要的MTA过滤技术。关于邮件过滤技术可以参阅本站的相关文章

MTA过滤分为两类:邮件数据发送前过滤和邮件数据发送后过滤。

一、数据前过滤

数据前过滤是指在SMTP会话中,DATA指令发送前进行的过滤。在这个阶段,有四种不同子阶段的过滤:SMTP连接时过滤、HELO/EHLO指令过滤、MAIL FROM指令过滤和RCPT TO指令过滤。根据这四个子阶段接收到的信息的不同,它们也分别称作SMTP客户端限制、HELO/EHLO主机名限制、发送者地址限制和接收者地址限制。

过滤默认是在RCPT TO指令后生效的,这是因为一些Windows上的邮件客户端不处理在RCPT TO指令前的过滤动作。可以通过将smtpd_delay_reject设置为no来使过滤动作立刻生效。这个参数还影响了在不同的指令上可以使用的过滤规则参数。

1、过滤规则

这四个子阶段的过滤是分别通过四个配置语句来指定过滤规则的。它们都接收一系列的规则参数列表,参数间可以用空格或逗号分隔开。在默认状态下smtpd_delay_reject的值是yes,它们可以接受所有支持的规则,不过需在RCPT TO指令后才能全部生效;如果把smtpd_delay_reject设置为no,它们只可以接受五个公共的规则参数、之前子阶段的过滤规则参数和该子阶段的规则参数。

它们接受的公共的规则参数如下:

permit
允许该连接进行。该规则通常置于规则列表的最后面使规则更清晰。

defer
通知客户端现在不能继续会话,稍后再进行SMTP连接请求。这常用于服务器需要进行一些DNS检查,但是(由于DNS查询超时)没有及时获得结果时,通知客户端稍后再进行连接。该规则通常置于规则列表的最后面使规则更清晰。

reject
拒绝该连接请求。在这个阶段就断开了连接,有效的节约了垃圾邮件造成的带宽和处理能力的浪费。该规则通常置于规则列表的最后面使规则更清晰。
拒绝动作默认不会在匹配了拒绝规则后就立刻断开连接,而是在rcpt to指令处理完之后再断开的,这是由于一些windows上有缺陷的邮件程序不处理在rcpt to指令前的发回的拒绝状态码。可以通过smtpd_delay_reject设置为no来立刻发送拒绝状态码断开连接。
reject_code指定了拒绝的返回状态码(默认是554)。

warn_if_reject
改变其后规则的拒绝动作为警告,即如果其后存在满足拒绝的条件,并不实际拒绝,而是发出一条警告信息(reject_warning)到日志文件中(通常是/var/log/maillog)。它常用于在实际运行的邮件服务器上测试邮件过滤规则。

reject_unauth_pipelining
拒绝在Postfix支持指令流水线前发送SMTP指令流水线的客户端连接。指令流水线是一些邮件客户端为了快速发送邮件所采用的技术。

以下就四个子阶段分别讲述过滤规则

A、SMTP连接时过滤(SMTP客户端限制)

Postfix可以在接受客户端的SMTP连接请求时进行过滤检查。

通过Postfix的smtpd_client_restrictions指令可以指定这个阶段的过滤规则。这个阶段可用的过滤规则除公共规则外还有:

reject_unknown_client
拒绝客户的地址没有对应的DNS的A记录或PTR记录的连接。通常有些机器,尤其是个人拨号用户的机器没有对应的A记录或PTR记录,所以要注意漫游用户的使用(漫游用户是指不在$mynetworks中,比如在别的ISP拨号上网的用户。通常用SMTP认证来解决这个问题)。
unknown_client_reject_code指定了拒绝的返回状态码(默认是450)。

permit_mynetworks
允许来自其IP地址属于$mynetworks所定义网络的客户端的连接。通常可用于ISP为自己的拨号用户提供SMTP服务时,通过$mynetworks参数指定自己的网络并允许自己的网络内的机器发送邮件。

reject_rbl_client domain.tld和reject_rhsbl_client domain.tld
拒绝来自属于RBL和RHSBL列表中的地址进行连接。通过检查一个IP地址或域名是否存在于domain.tld的RBL或RHSBL中,可以判断该客户端是否被列入了domain.tld的实时黑名单,从而决定是否接受连接。有关实时黑名单可以参考本站的【反垃圾邮件技术参考>>实时黑名单技术】。
maps_rbl_reject_code指定了拒绝的返回状态码(默认是554)。

check_client_access maptype:mapname
搜索名为mapname的maptype类型的访问数据库。可以根据客户端的主机名、父域、IP地址或部分IP地址来匹配。关于访问数据库请参阅下面的附录。

例子:

smtpd_client_restrictions = hash:/etc/postfix/access,
reject_rbl_client relays.ordb.org,
reject_rhsbl_client dsn.rfc-ignorant.org,
permit_mynetworks,
reject_unknown_client

其中relays.ordb.org和dsn.rfs-ignorant.org都是国外比较权威的免费RBL和RHSBL服务器。

B、HELO/EHLO指令过滤(HELO/EHLO主机名限制)

在接受了SMTP连接后,可以对HELO或EHLO指令所发送的信息进行过滤检查。

有些邮件客户端在通讯时并不发送HELO/EHLO指令,可以通过smtpd_helo_required设置为yes强制要求发送HELO/EHLO指令(默认Postfix不要求发送HELO/EHLO)。

通过Postfix的smtpd_helo_restrictions指令可以指定这个阶段的过滤规则。这个阶段可用的过滤规则除公共规则和smtpd_client_restrictions的规则外还有:

reject_invalid_hostname
拒绝无效格式的主机名的连接。
invalid_hostname_reject_code指定了拒绝的返回状态码(默认是501)。

reject_unknown_hostname
拒绝未知的主机名的连接。所谓未知的主机名是指该主机没有DNS的A记录或MX记录。由于很多拨号用户的机器并没有对应的A记录或MX记录,所以要注意漫游用户的使用。
unknown_hostname_reject_code指定了拒绝的返回状态码(默认是450)。

reject_non_fqdn_hostname
拒绝主机名不是FQDN格式(完全限定域名格式,即用点分隔开的包括域名和主机名的主机全名)的连接。
non_fqdn_reject_code指定了拒绝的返回状态码(默认时504)。

permit_naked_ip_address
允许直接使用IP地址的连接。通常在HELO/EHLO中使用主机名而不是IP地址。

check_client_access maptype:mapname
搜索名为mapname的maptype类型的访问数据库。可以根据HELO/EHLO发送的主机名、父域来匹配。关于访问数据库请参阅下面的附录。

C、MAIL FROM指令过滤(发送者地址限制)

在接受了SMTP连接,客户端发送了HELO/EHLO指令后(该指令可选),应该通过MAIL FROM指令声明发送者的身份。可以对发送者身份进行过滤检查。

按照RFC规范,在MAIL FROM指令和下面的RCPT TO指令中应该使用RFC 821格式的邮件地址(例如:<user@domain.tld>),但是由于有许多的邮件客户端的不规范,往往不使用标准的RFC 821格式。Postfix默认接受任何可以理解的邮件地址,如:丢失了地址里的一对尖括号、可以包含RFC 822格式的注释等。如果希望打开对RFC 821格式的限制,可以将strict_rfc821_envelopes设置为yes。

通过Postfix的smtpd_sender_restrictions指令可以指定这个阶段的过滤规则。这个阶段可用的过滤规则除了公共规则和smtpd_client_restrictions的规则和smtpd_helo_restrictions的规则外还有:

reject_unknown_sender_domain
拒绝发送者邮件的域没有DNS的A记录或MX记录的连接。
unknown_address_reject_code指定了拒绝的返回状态码(默认是450)。当进行DNS查询出现临时错误时(如查询超时)也总是返回450。

reject_rhsbl_sender domain.tld
拒绝发送者邮件的域属于RHSBL黑名单的连接。通过检查一个域名是否存在于domain.tld的RHSBL中,可以判断该客户端是否被列入了domain.tld的实时黑名单,从而决定是否接受连接。
maps_rbl_reject_code指定了拒绝的返回状态码(默认是554)。

check_sender_access maptype:mapname
搜索名为mapname的maptype类型的访问数据库。可以根据发送者邮件的邮件地址、名字、域和父域来匹配。关于访问数据库请参阅下面的附录。

reject_non_fqdn_sender
拒绝发送者邮件的域不是FQDN格式的连接。
non_fqdn_reject_code指定了拒绝的返回状态码(默认时504)。

reject_sender_login_mismatch
拒绝发送者在$smtpd_sender_owner_maps中所匹配的用户名和SASL登录名不一致的连接。

D、RCPT TO指令过滤(接收者地址限制)

在MAIL FROM指令后要通过RCPT TO指令指定邮件接收者。可以对接收者身份进行过滤检查。

通过Postfix的smtpd_recipient_restrictions指令可以指定这个阶段的过滤规则。同以上的检查指令不同,为了避免开放转发,这个指令有默认值:permit_mynetworks,reject_unauth_destination。这个阶段可用的过滤规则除了公共规则和smtpd_client_restrictions的规则和smtpd_helo_restrictions的规则和smtpd_sender_restrictions的规则外还有: