This site uses advanced css techniques
At the start of all SMTP transactions, the calling machine identifies itself, literally by saying "HELO" with its computer name. If cygnus.unix-girl.com connects to the Unixwiz.net mailserver and attempts to deliver mail:
»» 220 linux.unixwiz.net ESMTP Postfix we say... «« HELO cygnus.unix-girl.com she says... »» 250 linux.unixwiz.net we say... .... transaction continues
This HELO verb is used more for "logging" than for "authentication", but a substantial body of spamware identifies itself as the machine it's connecting to, either by name or by IP:
«« HELO linux.unixwiz.net Liar! That's our machine name! or «« HELO 64.170.162.98 Liar! That's our IP!
Even though it's "lying", it's not really forbidden by the SMTP protocol because it's not used for authentication. But because these lies are so easily detectable, we can ask the Postfix to turn away these spammer connections with very low risk of false positive.
We've never heard of a legitimate mailserver that lies in this way. Not even one.
NOTE - This technique has nothing to do with DNS lookups, forward or reverse, which has had a scattered history of effectiveness and false-positive rates. Instead, we rely strictly on what the sender says during the conversation, and only consider them "lying" if they use our own IP or system name.
There are other Postfix controls that do things like rejecting all HELO with an IP address, as well as other bogus HELO settings, but these are as likely to be a misconfiguration of the remote mailserver and are not the clear indication of spamming that using our name/IP is. That's a different problem that we're not addressing here.
Postfix has substantial access control mechanisms that allow us to reject these connections. We'll be using the smtpd_helo_required control mechanism found in the main.cf file, along with a few related controls.
... 1 smtpd_delay_reject = yes 2 smtpd_helo_required = yes 3 smtpd_helo_restrictions = 4 permit_mynetworks, 5 check_helo_access hash:/etc/postfix/helo_access, 6 permit ...
Considering each line number:
This rejects all inbound SMTP connections that try to omit HELO. Though mail transactions can work without this command, we require it in order to examine the credentials provided. We've been requiring HELO for years without any ill effects, as all legitimate mailservers send this.
Note that there's an extended version of this command - EHLO - and it's treated the same as HELO for the purposes of this (and the next) restrictions.
There are other restrictions that can be applied in this section, such as reject_invalid_hostname, but we've not used them.
The parameter to the check_helo_access can be any of the normal access databases. We typically use the hash with the name helo_access, but any filename can be used.
The content of the file lists the HELO string to be considered, along with a disposition. NOTE this is for Postfix 2.x.
64.170.162.98 REJECT Get lost - you're lying about who you are unixwiz.net REJECT Get lost - you're lying about who you are
Recall that these tests are not even considered if the connection is coming from a trusted client (which might legitimately use part of our domain name in the HELO identification), so these should never be used by legitimate outsiders.
Furthermore, the matches are done in a hierarchical manner: if the spamware identifies itself as linux.unixwiz.net, both that name, plus the short unixwiz.net are tested (and in this case, the latter would be the match).
When these changes have been made - to main.cf and to helo_access - Postfix must be told about them. The former changes take effect when the superuser runs the postfix reload command, while the latter require a postmap helo_access command.
The change to main.cf need only be made once (along with the associated postfix reload, but the helo_access file may be updated
These two SMTP transcripts show the effect of forging a name in the HELO command from an untrusted source, and we show both cases of smtpd_delay_reject. Our side is in bold
«« 220 linux.unixwiz.net ESMTP Postfix »» HELO linux.unixwiz.net «« 250 linux.unixwiz.net »» MAIL From:<steve@spammer.bad> «« 250 Ok »» RCPT To:<steve@unixwiz.net> «« 554 <linux.unixwiz.net> Helo command rejected: Get lost - you're lying about who you are
220 linux.unixwiz.net ESMTP Postfix HELO linux.unixwiz.net 554 <linux.unixwiz.net>: Helo command rejected: Get lost - you're lying about who you are
The previous version of Postfix didn't have the same format of the helo_access file: we can say no more than say "REJECT" (or "OK"), with Postfix supplying a generic failure message to a denied connection.
64.170.162.98 REJECT unixwiz.net REJECT
The result as seen by the remote is
»» 220 testmx.unixwiz.net ESMTP Postfix «« HELO testmx.unixwiz.net »» 554 <testmx.unixwiz.net> Helo command rejected: Access denied
In addition, the DISCARD action permitted by Postfix 2.x is not accepted by 1.x.
Our thanks to Bob Perkins for help on this section.
Postfix generally makes a note about all of rejections in the logfile, and, if smtpd_delay_reject is yes, will show the sender and recipient as well as the HELO string that provoked the rejection. These can be found by grep'ing the logfiles for the string Helo command rejected.
An example log entry (wrapped for display) is:
Mar 13 13:19:10 linux postfix/smtpd[30930]: BE1624295: reject: RCPT from unknown[61.55.20.110]: 554 <64.170.162.98>: Helo command rejected: Get lost - you're lying about who you are; from=<support@support.get-top-rankings.com> to=<steve@unixwiz.net> proto=SMTP helo=<64.170.162.98>
This connection, which originated from China, tried to identify itself as our mailserver, so was sent on its way.
The most obvious kind of mistake with this arrangement is rejecting mail from a trusted source that somehow didn't make it onto the mynetworks list. Since including a top-level domain name (say, example.com) will exclude that and all sub-domains (foo.example.com, etc.) from connecting. For larger or more diverse enterprises, it might be difficult to fully elaborate all the trusted networks.
In this case, the "wide-ranging" top-level domain entry may simply be too catch-all. But it's still possible to turn away a substantial portion of spam by using narrowly-tailored entries in the helo_access file.
By including the local machine's IP address and all the names as found in the MX records in the DNS, it will catch the bulk of spammers lying outright about a separated-at-birth relationship with your mailserver:
64.170.162.98 REJECT Get lost - you're lying about who you are linux.unixwiz.net REJECT Get lost - you're lying about who you are smtp.unixwiz.net REJECT Get lost - you're lying about who you are
As a side note, some have objected to the non-technical "Get lost" nature of this message, suggesting that we ought to instead provide a bit more information about why the traffic was rejected. This is a valid objection for everything but this: I have never seen even a single false positive, where a "real" mailserver sending "real" mail was wrongly blocked, so I believe that "Get lost" is going to hacked Trojan bots.
When I find a false positive, I'll regularize the message.
First published: 2003/03/13