Badhelo

From The Network People, Inc. - Wiki
Jump to navigation Jump to search

Recent versions of Mail::Toaster have the possibility to reject connections based on the HELO or EHLO string they present to it during the SMTP phase.

From the qmail-smtpd man page:

badhelo
Unacceptable  HELO/EHLO host names.  qmail-smtpd will reject every
recipient address for a message if the host name is listed in,  or
matches a POSIX regular expression pattern listed in, badhelo.  If
the NOBADHELO environment variable is set, then  the  contents  of
badhelo will be ignored.  For more information, please have a look
at doc/README.qregex.

So we see that the rejection happens later than outright connection blocking vith rblsmtpd. In fact, the rejection doesn't happen until the first message recipient (RCPT TO) is given by the sender, but of course only if their HELO matches something in /var/qmail/control/badhelo. Using badhelo will not generate backscatter.

Since badhelo can contain POSIX regular expressions, there is quite a few possibilities for rejecting mail from hosts using a "generic" hostname. Regular expressions (regex) can be very confusing at first, especially since most system administrators get by on a daily basis using only '?' and '*'.

badhelo entry suggestions

The following entry will reject any HELO that starts with adsl, dsl, dhcp, dyn or dynamic, followed by a dash and a sequence of numbers:

^(a?dsl|dhcp|dyn(amic)?|ppp)([.-][0-9]{1,3}){4}

The next one will reject HELOs with no dot in them, i.e. no Fully Qualified Domain Name (FQDN) and is considered slightly controversial:

!\.

mps note: I had problems with Outlook/OE users being able to send email when I required valid FQDN. A possible solution is found here. This is because Outlook clients generally send their NetBIOS (local) host name rather than a domain name.

Other suggestions:

hsd1\.(nj|md|ct|ga|tx|tn|ca|wv|pa|or)\.comcast\.net
dsl\.club\-internet\.fr
.dynamic.ttnet\.net\.tr
red\.bezeqint\.net
bb\.netvision\.net\.il
abo\.wanadoo\.fr
localhost
localhost\.localdomain
<The toaster's public IP-address>
<The toaster's fully qualified domain name>
<All of the MX record hostnames which points to the toaster>

The regex's in the latter should be fairly simple to understand, but the long and short of it is that any HELOs matching partially will be denied.

To find a hosts HELO/EHLO string in the SMTP log, follow /var/log/mail/YEAR/MON/DAY/smtplog and look for the text in bold:

2007-09-05 11:25:01.373587500 CHKUSER accepted rcpt: from <from.adddress@host.example.com::> remote
<mail.example.com:unknown:10.10.10.254> rcpt <user@thisdomain.com> : found existing recipient

Notes

Be very careful with what you put in badhelo. If you enter just "mail" on a single line while at the same time allowing hosts without FQDN, it will match any HELO containing the string 'mail', e.g. "mail.somebigcompany.com". Very bad.

The badhelo control file can be empty or non-existing, which means HELO/EHLO checking will not be done.

Rejected hosts will get this error message:

553 sorry, your HELO host name has been denied (#5.7.1)

Rejecting non-FQDNs

One commonly conceived idea is to block mail from clients which do not HELO with a FQDN that has a reverse DNS associated with it. This has been discouraged for a number of reasons. However, if one wishes to engage in some blocking of highly unusual or clearly incorrect HELO commands, qregex can do so quite easily.

Examples of badhelo RE's:

local$
lan$
host$

If you have already blocked any HELO without a dot in it, then the 3 regular expressions above will effectively block HELOs from domains which do not resolve on the global Internet, such as ".lan", ".localhost" and ".local". Use the script below to examine which TLDs you are seeing in your HELO. You might be surprised to see the numbers of HELOs from bogus top-level domains!

A similar scheme might be used to block real Internet top-level domains.

iq$

This would block mail sent from a client that uses a domain name of the country of Iraq in its HELO. If you are completely sure your users will not need to receive mail from Iraq, this is a powerful way to block access.

To block mail that appears to come from poorly-configured servers or clients, you may wish to restrict the characters you will accept in HELO:

[~!@#$%^&*()_+`={}|\;':"<>?,/]

If any of the characters listed above are sent by the client, minus the [square brackets], qmail will reject the HELO. Some quite popular email clients use some of these characters, notable the underscore. If you wish to also block the square brackets, you should do so with the knowledge that a correct implementation of an SMTP client should use square brackets to wrap its IP address. The below badhelo RE may result in blocking legitimate clients.

\[

This would block HELOs from a client using the [192.168.0.24] style domain literal. You will quite possibly reject mail from good clients, so you might consider letting Spamassassin or DNSrbl do their jobs on this type of HELO, both of which are far more capable of preventing even the occasional false positive. This may work on a secondary MX which expects no clients to connect to it for relaying.

Who is HELOing you?

The following rather quick and dirty script will give you a sorted list of HELO strings presented to your toaster today, yesterday, this past year, or since the year 2000.

#!/bin/sh
# Sorted list of HELOS presented to qmail-smtpd
# 2009/04/13-uruiamme
# Suggested usage:
# tophelos <-yesterday> | head -15
# tophelos -year (Current year)
# tophelos -all (Since 2000)
# Today is default
YEAR=`date "+%Y"`
MONTH=`date "+%m"`
# Today is default
DAY=`date "+%d"`
LOG=smtplog
TMP=`mktemp -t tophelos`
if [ "$1" = "-all" ] ; then
 LOG=smtplog.gz
 zgrep "remote <" /var/log/mail/20*/*/*/$LOG | cut -f 8 -d " " | tr -d " <>" | cut -f 1 -d : > $TMP
 cat $TMP | sort | uniq -c | sort -r
 rm $TMP
 exit 0
fi
if [ "$1" = "-year" ] ; then
 LOG=smtplog.gz
 zgrep "remote <" /var/log/mail/$YEAR/*/*/$LOG | cut -f 8 -d " " | tr -d " <>" | cut -f 1 -d : > $TMP
 cat $TMP | sort | uniq -c | sort -r
 rm $TMP
 exit 0
fi
if [ "$1" = "-yesterday" ] ; then
       DAY=`date -v-1d "+%d"`
       LOG=smtplog.gz
fi
zgrep "remote <" /var/log/mail/$YEAR/$MONTH/$DAY/$LOG | cut -f 8 -d " " | tr -d " <>" | cut -f 1 -d : > $TMP
cat $TMP | sort | uniq -c | sort -r
rm $TMP

The Aftermath: Who is getting the badhelo message?

First things first (optional): enable logging of the badhelo by using the following addition to your tcp.smtp file. Suppose you had the following line in your /usr/local/vpopmail/etc/tcp.smtp file.

Before:

:allow,QMAILQUEUE="/var/qmail/bin/simscan"

After:

:allow,QMAILQUEUE="/var/qmail/bin/simscan",LOGREGEX=""

Adding the LOGREGEX="" will tell you which regular expression caught your HELO bandits. Also, if you wish to prevent this badhelo checking for some clients or for the submission port, see the Avoid rejecting users authenticating on port 587 article which describes the NOBADHELO="" option.

Here is a one-line quickie way to know who has been getting the badhelo response. Remove the "cut" and "uniq" pipes at the end if you want to see more information. Be careful on large servers if you do not wish to look back at an entire year of logs on a busy mail server!

zgrep -hr badhelo /var/log/mail/2009/* | tai64nlocal | cut -d " " -f 1,5,7 | uniq

Or you could potentially cut out everything except the IP address of the badhelo clients and send this list to a reverse lookup tool, such as host.

zgrep -hr badhelo /var/log/mail/* | tai64nlocal | cut -d " " -f 7 | uniq

And it is left as an exercise to the student how to look up these IP addresses to verify you are blocking the sorts of clients you intended to block.