转自: http://www.thismail.org/bbs/thread-2672-1-2.html
 
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地址来匹配。关于访问数据库请参阅下面的附录

  例子:
smtd_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格式的邮件地址(例如:< [email protected]>),但是由于有许多的邮件客户端的不规范,往往不使用标准的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的规则外还有:

permit_auth_destination
允许发往默认转发和默认接收的连接。
Postfix默认转发以下的邮件:
来自$mynetworks中地址发送的邮件
发往$relay_domains中的域或其子域的邮件。但是不能包含邮件路由(如user@ [email protected])。

Postfix默认接收最终投递目标符合如下条件的邮件:

目标在$inet_interfaces
目标在$mydestinations
目标在$virtual_alias_domains
目标在$virtual_mailbox_domains
reject_unauth_destination
拒绝不是发往默认转发和默认接收的连接。
relay_domain_reject_code指定了拒绝的返回状态码(默认是554)。
permit_mx_backup
允许接收本地主机是邮件投递目标的MX地址的邮件。但是不能包含邮件路由(如user@ [email protected])。
check_recipient_access maptype:mapname
搜索名为mapname的maptype类型的数据库。可以根据接收者邮件的邮件地址、名字、域和父域来匹配。 关于访问数据库请参阅下面的附录。
check_recipient_maps
拒绝接收者不匹配如下列表的连接:

$local_recipient_maps($mydestinations和$inet_interfaces)
$virtual_alias_maps($virtual_alias_domains)
$virtual_mailbox_maps($virtual_mailbox_domains)
$relay_recipient_maps($relay_domains)
空的$local_recipient_maps和$local_recipient_maps表示不对接收者地址进行过滤检查。
Postfix默认在接收者检查列表的最后做check_recipient_maps检查

reject_unknown_recipient_domain
拒绝接收者邮件的域没有DNS的A记录或MX记录的连接。
unknown_address_reject_code指定了拒绝的返回状态码(默认是450)。当进行DNS查询出现临时错误时(如查询超时)也总是返回450。
reject_rhsbl_recipient domain.tld
拒绝接收者邮件的域属于RHSBL黑名单的连接。通过检查一个域名是否存在于domain.tld的RHSBL中,可以判断该客户端是否被列入了domain.tld的实时黑名单,从而决定是否接受连接。
maps_rbl_reject_code指定了拒绝的返回状态码(默认是554)。
reject_non_fqdn_recipient
拒绝接收者邮件的域不是FQDN格式的连接。
non_fqdn_reject_code指定了拒绝的返回状态码(默认时504)。
permit_sasl_authenticated
允许通过了SASL认证的用户发送邮件。通过SASL协议(包括SASL1和SASL2)实现的SMTP认证功能需要在编译Postfix时编译进SASL支持,并在main.cf中将smtpd_sasl_auth_enable设置为yes。有关SASL及如何在Postfix中实现SASL认证请参阅下面的附录。通过SASL认证可以对漫游用户提供发信支持,是关闭Open-Relay的重要手段