https://github.com/smtpd/qpsmtpd/pull/29
I've been running it on my server for a week in RFC policy mode. I knew from
hours of watching logs that it would be effective, but measuring it was still
surprising and delightful. Of the 10% of connections that make it past the
dnsbl and karma tests, another 50% are rejected by these HELO tests. Of those
50%, more than 95% are connections from Windows (most Win 7) hosts where the
DNS bears no resemblance to the HELO hostname offered.
Since expanding the no_matching_dns test (earlier today), I have yet to see a
single false positive from that test. While I'm still not using that as a
condition for rejection, it may now be good enough to enforce.
Matt
NAME
helo - validate the HELO message presented by a connecting host.
DESCRIPTION
Validate the HELO hostname. This plugin includes a suite of optional
tests, selectable by the *policy* setting. The policy section details
which tests are enforced by each policy option.
This plugin adds an X-HELO header with the HELO hostname to the message.
Using *policy rfc* will reject a very large portion of the spam from
hosts that have yet to get blacklisted.
WHY IT WORKS
The reverse DNS of the zombie PCs is out of the spam operators control.
Their only way to get past these tests is to limit themselves to hosts
with matching forward and reverse DNS, and then use the proper HELO
hostname when spamming. At present, this presents a very high hurdle.
HELO VALIDATION TESTS
is_in_badhelo
Matches in the *badhelo* config file, including yahoo.com and
aol.com, which neither the real Yahoo or the real AOL use, but which
spammers use a lot.
Like qmail with the qregex patch, the badhelo file can also contain
perl regular expressions. In addition to normal regexp processing, a
pattern can start with a ! character, and get a negated (!~) match.
invalid_localhost
Assure that if a sender uses the 'localhost' hostname, they are
coming from the localhost IP.
is_plain_ip
Disallow plain IP addresses. They are neither a FQDN nor an address
literal.
is_address_literal [N.N.N.N]
An address literal (an IP enclosed in brackets) is legal but rarely,
if ever, encountered from legit senders.
is_forged_literal
If a literal is presented, make sure it matches the senders IP.
is_not_fqdn
Makes sure the HELO hostname contains at least one dot and has only
those characters specifically allowed in domain names (RFC 1035).
no_forward_dns
Make sure the HELO hostname resolves.
no_reverse_dns
Make sure the senders IP address resolves to a hostname.
no_matching_dns
Make sure the HELO hostname has an A or AAAA record that matches the
senders IP address, and make sure that the senders IP has a PTR that
resolves to the HELO hostname.
Since the dawn of SMTP, having matching DNS has been a minimum
standard expected and oft required of mail servers. While requiring
matching DNS is prudent, requiring an exact match will reject valid
email. While testing this plugin with rejection disabled, I noticed
that mx0.slc.paypal.com sends email from an IP that reverses to
mx1.slc.paypal.com. While that's technically an error, I believe
it's an error to reject mail based on it. Especially since SLD and
TLD match.
To avoid snagging false positives, matches are extended to the first
3 octets of the IP and the last two labels of the FQDN. The
following are considered a match:
192.0.1.2, 192.0.1.3
foo.example.com, bar.example.com
This allows *no_matching_dns* to be used without rejecting mail from
orgs with pools of servers where the HELO name and IP don't exactly
match. This list includes Yahoo, Gmail, PayPal, cheaptickets.com,
exchange.microsoft.com, and likely many more.
CONFIGURATION
policy [ lenient | rfc | strict ]
Default: lenient
lenient
Reject failures of the following tests: is_in_badhelo,
invalid_localhost, and is_forged_literal.
This setting is lenient enough not to cause problems for your Windows
users. It is comparable to running check_spamhelo, but with the addition
of regexp support and the prevention of forged localhost and forged IP
literals.
rfc
Per RFC 2821, the HELO hostname must be the FQDN of the sending server
or an address literal. When *policy rfc* is selected, all the lenient
checks and the following are enforced: is_plain_ip, is_not_fqdn,
no_forward_dns, and no_reverse_dns.
If you have Windows users that send mail via your server, do not choose
*policy rfc* without *reject naughty* and the naughty plugin. Windows
users often send unqualified HELO names and will have trouble sending
mail. <Naughty> can defer the rejection, and if the user subsequently
authenticates, the rejection will be cancelled.
strict
Strict includes all the RFC tests and the following: no_matching_dns,
and is_address_literal.
I have yet to see an address literal being used by a hammy sender. But I
am not certain that blocking them all is prudent.
It is recommended that *policy strict* be used with <reject 0> and that
you monitor your logs for false positives before enabling rejection.
badhelo
Add domains, hostnames, or perl regexp patterns to the badhelo config
file; one per line.
timeout [seconds]
Default: 5
The number of seconds before DNS queries timeout.
reject [ 0 | 1 | naughty ]
Default: 1
0: do not reject
1: reject
naughty: naughty plugin handles rejection
reject_type [ temp | perm | disconnect ]
Default: disconnect
What type of rejection should be sent? See docs/config.pod
loglevel
Adjust the quantity of logging for this plugin. See docs/logging.pod
RFC 2821
4.1.1.1
The HELO hostname "...contains the fully-qualified domain name of the
SMTP client if one is available. In situations in which the SMTP client
system does not have a meaningful domain name (e.g., when its address is
dynamically allocated and no reverse mapping record is available), the
client SHOULD send an address literal (see section 4.1.3), optionally
followed by information that will help to identify the client system."
2.3.5
The domain name, as described in this document and in [22], is the
entire, fully-qualified name (often referred to as an "FQDN"). A domain
name that is not in FQDN form is no more than a local alias. Local
aliases MUST NOT appear in any SMTP transaction.
AUTHOR
2012 - Matt Simerson
ACKNOWLEDGEMENTS
badhelo processing from check_badhelo plugin
badhelo regex processing idea from qregex patch
additional check ideas from Hakura helo plugin
`````````````````````````````````````````````````````````````````````````
Matt Simerson http://matt.simerson.net/
Systems Engineer http://www.tnpi.net/
Mail::Toaster - http://mail-toaster.org/
NicTool - http://www.nictool.com/
`````````````````````````````````````````````````````````````````````````