One of the most effective anti-spam measures one can implement is to enforce
valid use of SMTP and other standards. Spam clients are interested in
sending messages as quickly as possible, and so usually don't bother with
actually implementing standards correctly. In this post I shall describe the
various checks which can be used, show how to implement these checks in
Postfix, and describe how to ensure that your mail server passes these
checks when sending mail.
Reverse DNS Entries
RFC 1912 states that "every Internet-reachable host should have a name"
and "make sure your PTR and A records match". This can be checked by performing
a Forward Confirmed reverse DNS lookup1. This check can be done
before even accepting the TCP connection, which means the mail server's
existence isn't even revealed to rejected clients.
Passing: Ensure that your mail server has matching
RFC 2821 states that "a client SHOULD start an SMTP session by issuing
the EHLO command". Almost all SMTP client implementations do do this, and so we
can require the use of
smtpd_helo_required = yes.
RFC 2821 states that "the argument field [of the HELO/EHLO command]
contains the fully-qualified domain name of the SMTP client if one is
available". Since external mail servers have to be Internet reachable this is a
requirement, and can be checked by looking up the name in DNS2.
Passing: Ensure that your mail server is configured to send a fully
qualified hostname which exists in DNS.
If there is only one mail server (and possibly even if there are multiple
servers), SMTP clients should not be using the server's hostname as the
HELO hostname. Clients which do so can therefore be rejected.
check_helo_access hash:/etc/postfix/helo_access to
smtpd_helo_restrictions. Use helo_access as a template for
/etc/postfix/helo_access, and run
The originator (
MAIL FROM) address is where error reports will be sent, and
therefore should be a valid address. The only thing which can be checked though
is that the address is fully qualified and that the domain exists.
Passing: Ensure that your mail server only emits fully qualified addresses.
This should happen by default, except possibly for mail submitted with
Unless the mail server is a relay or backup MX, it should already only be
accepting addresses for which it is the destination. If it is a relay or backup
MX the same checks as above can be done.
One other check has to do with multiple recipients for bounced mail. Error
reports for bounced mail uses a null originator address, and should only have
Unless the client explicitly requests pipelining (as described in RFC
1854), the SMTP conversation must occur in lock step (i.e. the client
must wait for a response from the server before sending the next command). Since
spam clients are trying to send messages as quickly as possible it is likely
that they do not adhere to this requirement.
RFC 2821 specifies that the server must send the first message after the
connection is established. A neat trick is to delay this initial message to
catch out clients which don't wait for it.
sleep 1, reject_unauth_pipelining to
smtpd_client_restrictions. This also requires
smtpd_delay_reject = no
Since these measures will reject valid mail from misconfigured mail servers, I
like to keep an eye on rejections via logcheck. However, some of these
measures by their very nature reject the client before it's even sent the
originator and recipient addresses, which makes identification of valid mail
difficult. Postfix therefore has a feature which delays rejection until after
the recipient addresses have been sent. This is enabled by default, but can be
disabled by setting
smtpd_delay_reject = no.