Spam Filtering for Mail Exchangers:
Prev | Appendix A. Exim Implementation | Next

# A.13. Exempting Forwarded Mail

After adding all these checks in the SMTP transaction, we may find ourselves indirectly creating collateral spam as a result of rejecting mails forwarded from trusted sources, such as mailing lists and mail accounts on other sites (see the discussion on Forwarded Mail for details). We now need to whitelist these hosts in order to exempt them from SMTP rejections -- at least those rejections that are caused by our spam and/or virus filtering.

In this example, we will consult two files in response to each RCPT TO: command:

- A global whitelist in `/etc/mail/whitelist-hosts`, containing backup MX hosts and other whitelisted senders [1], and

- A user-specific list in `/home/`user`/.forwarders`, specifying hosts from which that particuar user will receive forwarded mail (e.g. mailing list servers, outgoing mail servers for accounts elsewhere...)

If your mail users do not have local user accounts and home directories, you may want to modify the file paths and/or lookup mechanisms to something more suitable for your system (e.g. database lookups or LDAP queries).

If the sender host is found in one of these whitelists, we save the word "accept" in `$acl_m0`, and clear the contents of `$acl_m1`, as described in the previous section on Selective Delays. This will indicate that we should not reject the mail in subsequent statements.

In the acl_rcpt_to, we insert the following statement after validating the recipient address, but before any `accept` statements pertaining to unauthenticated deliveries from remote hosts to local users (i.e. before any greylist checks, envelope signature checks, etc):

      # Accept the mail if the sending host is matched in the global
      # whitelist file.  Temporarily set $acl_m9 to point to this  file.
      # If the host is found, set a flag in $acl_m0 and clear $acl_m1 to
      # indicate that we should not reject this mail later.
      #
      accept
        set acl_m9  = /etc/mail/whitelist-hosts
        hosts       = ${if exists {$acl_m9}{$acl_m9}}
        set acl_m0  = accept
        set acl_m1  =

      # Accept the mail if the sending host is matched in the ".forwarders"
      # file in the recipient's home directory.  Temporarily set $acl_m9 to
      # point to this file.  If the host is found, set a flag in $acl_m0 and
      # clear $acl_m1 to indicate that we should not reject this mail later.
      #
      accept
        domains     = +local_domains
        set acl_m9  = /home/${extract{1}{=}{${lc:$local_part}}}/.forwarders
        hosts       = ${if exists {$acl_m9}{$acl_m9}}
        set acl_m0  = accept
        set acl_m1  =

In various statements in the acl_data ACL, we check the contents of `$acl_m0` to avoid rejecting the mail if this is set as per above. For instance, to avoid rejecting mail from whitelisted hosts due to a missing RFC2822 header:

      deny
        message     = Your message does not conform to RFC2822 standard
        log_message = missing header lines
        !hosts      = +relay_from_hosts
        !senders    = : postmaster@*
        condition   = ${if !eq {$acl_m0}{accept}{true}}
        condition   = ${if or {{!def:h_Message-ID:}\
                               {!def:h_Date:}\
                               {!def:h_Subject:}} {true}{false}}

The appropriate checks are embedded in the Final ACLs, next.

Prev | Home | Next
Accept Bounces Only for Real Users | Up | Final ACLs