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
[9], and
A user-specific list in
/home/
,
specifying hosts from which that particuar user will receive
forwarded mail (e.g. mailing list servers, outgoing mail
servers for accounts elsewhere...)
user
/.forwarders
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.