net/smtp has hardcoded "localhost" for HELO/EHLO greeting

996 views
Skip to first unread message

Dusty Wilson

unread,
Jan 15, 2012, 6:40:19 AM1/15/12
to golan...@googlegroups.com
In net/smtp, smtp.Client's helo() and ehlo() has "HELO localhost" and
"EHLO localhost" hardcoded. Using "localhost" as the value causes
some spam filters to give it a high spam score.

I've written a few changes to introduce smtp.Options{} which includes
a field called "LocalHostname" which replaces "localhost" when it is
non-empty. *smtp.Options is passed into smtp.Dial(),
smtp.NewClient(), and smtp.SendMail(), which means that their
signatures would change for this purpose. It treats options==nil as
being the default case.

It might not be a big deal for the common case, but I'm using this as
part of my MX server test suite to test my fleet of mail servers, so I
have a personal itch to scratch on this one. I've already written the
code for it for my own use and I'm happy with it as-is. I did _not_
add any new tests for this nor did I need to modify the existing
tests.

Modified net/smtp.go: http://pastebin.com/aQTMthGU
Diff: http://pastebin.com/XrwZvZxf

If you would prefer those files to be provided in a different way, let
me know so I can at least do so in the future. I assume we should
chat here about it before I would submit to the codereview site.

Thanks,
Dusty

Evan Shaw

unread,
Jan 15, 2012, 2:12:53 PM1/15/12
to Dusty Wilson, golan...@googlegroups.com

I was under the impression that servers didn't use this value for
anything, which is why I hardcoded it in the package. Do servers do
anything with it besides scoring for spam? If not, is there another,
better value we could use? Maybe os.Hostname?

I'd prefer to find a more sensible default since most people won't
know what to do with the extra option. And if we can do without the
option altogether, that's better yet.

- Evan

ps

unread,
Jan 15, 2012, 2:48:05 PM1/15/12
to golang-nuts
Speaking generally, I'd assume user-specified values would be among
the least trusted and therefore ignored (unless spammers just aren't
that sophisticated).
Message has been deleted

Graham Anderson

unread,
Jan 15, 2012, 6:02:41 PM1/15/12
to golan...@googlegroups.com
On Sunday 15 Jan 2012 12:33:58 D Smithson wrote:
> The application should be allowed to specify the host name to avoid getting
> dinged on a spam score.

Sure, as long as the host name is valid e.g. appears in a lookup of
getaddrinfo(). Otherwise forget it.

Message has been deleted

Devon H. O'Dell

unread,
Jan 15, 2012, 6:38:35 PM1/15/12
to golan...@googlegroups.com
2012/1/15 D Smithson <d_smi...@rocketmail.com>:

>> Sure, as long as the host name is valid e.g. appears in a lookup of
>> getaddrinfo().
>
> Yes, that's the goal of allowing the application to specify the host.  If
> the application is not going to provide a valid host name, then the
> application might as well use an arbitrary string like "localhost".
>
> In the general case, it's not possible for the Go code to automatically
> discover a correct host name. An example where the application is on a host
> behind a NAT.

Or a system with multiple addresses. There are plenty of cases where
the hostname of the system will *not* be the same as the reverse
address lookup for the connecting IP (which is generally how people
define policy around the (EH|HE)LO string). It's not just a spam ding;
some mail servers will 421 you if you don't provide a name that is the
reverse of the connecting IP.

The user of the API should be able to specify whatever string they'd
like, there's no reason to do additional DNS validation on the
supplied string. It's also useful to be able to specify arbitrary
strings to test server policies (though most people are likely to just
use telnet for this, not write code in Go).

--dho

Dusty Wilson

unread,
Jan 15, 2012, 8:13:40 PM1/15/12
to Evan Shaw, golan...@googlegroups.com
On Sun, Jan 15, 2012 at 3:45 PM, Dusty Wilson <du...@linux.com> wrote:

> On Sun, Jan 15, 2012 at 11:12 AM, Evan Shaw <eds...@gmail.com> wrote:
>> On Mon, Jan 16, 2012 at 12:40 AM, Dusty Wilson <du...@linux.com> wrote:
>>> In net/smtp, smtp.Client's helo() and ehlo() has "HELO localhost" and
>>> "EHLO localhost" hardcoded.  Using "localhost" as the value causes
>>> some spam filters to give it a high spam score.
>>
>> I was under the impression that servers didn't use this value for
>> anything, which is why I hardcoded it in the package. Do servers do
>> anything with it besides scoring for spam? If not, is there another,
>> better value we could use? Maybe os.Hostname?
>>
>> I'd prefer to find a more sensible default since most people won't
>> know what to do with the extra option. And if we can do without the
>> option altogether, that's better yet.
>
> I'll try out os.Hostname as the value and see how it runs.  I'm
> concerned that some spam filters may test the hostname to see if it
> maps to something reasonable.  I do know that the spam filters in my
> particular environment add points for not looking like a FQDN, so if
> os.Hostname doesn't provide something that looks FQDN-esque, it'll be
> a problem for some cases.

SpamAssassin reports these errors for my laptop (which has a non-FQDN
system hostname) while using os.Hostname() as the source of hostname
value:

1.8 FSL_HELO_NON_FQDN_1
1.0 HELO_NO_DOMAIN

Can we just use a static bit of text that isn't "localhost" that looks
like a FQDN and it be passable?

I understand the goodness of not having to provide more knobs and
dials than necessary, but there are just some times that I think it is
necessary to set a value that is not the default. Keep in mind that
this code might be used on a Windows computer and it might not have an
FQDN either, so it's not as simple as saying "set your hostname
correctly".

Maybe we could hide the options altogether and pay attention to an
environment variable as a way to override the default value?

Thanks,
Dusty

Dusty Wilson

unread,
Jan 15, 2012, 8:35:12 PM1/15/12
to Evan Shaw, golan...@googlegroups.com
On Sun, Jan 15, 2012 at 5:13 PM, Dusty Wilson <du...@linux.com> wrote:
> Can we just use a static bit of text that isn't "localhost" that looks
> like a FQDN and it be passable?

I noticed that Exchange server (at least old versions) check the
HELO/EHLO hostname and will complain with "550 Forged hostname
detected in HELO/EHLO", though I'm not sure under what circumstances.
Also, I'm aware of various knobs in exim that test the hostname passed
in HELO/EHLO and can be found at
http://www.exim.org/exim-html-current/doc/html/spec_html/ch14.html
(search for "helo_" to find the variables). I'm sure there are other
SMTP servers out there that are similar.

It's my opinion that we should provide some manner to set the hostname
being sent in the HELO/EHLO greeting. Even if the local hostname
looks good, it might not be in global DNS or might not route back to
the public IP of this host or its network. This is important if
receiving server is testing the hostname value and expects that it
will map back to the sender's apparent IP.

Dusty Wilson

unread,
Jan 15, 2012, 8:48:24 PM1/15/12
to Evan Shaw, golan...@googlegroups.com
On Sun, Jan 15, 2012 at 5:35 PM, Dusty Wilson <du...@linux.com> wrote:
>> Can we just use a static bit of text that isn't "localhost" that looks
>> like a FQDN and it be passable?

Risking sending too many messages about this... sorry.

The Perl module Net::SMTP uses "localhost.localdomain" as the default
hostname but allows it to be overridden.
http://cpansearch.perl.org/src/GBARR/libnet-1.22/Net/SMTP.pm

Postfix can be configured to interpret the hostname value and take
action based on it:
http://www.postfix.org/postconf.5.html#smtpd_helo_restrictions

I think the question now is not if it should be possible to manually
set this value, but how.

Dusty Wilson

unread,
Jan 15, 2012, 6:45:30 PM1/15/12
to Evan Shaw, golan...@googlegroups.com
On Sun, Jan 15, 2012 at 11:12 AM, Evan Shaw <eds...@gmail.com> wrote:
> On Mon, Jan 16, 2012 at 12:40 AM, Dusty Wilson <du...@linux.com> wrote:
>> In net/smtp, smtp.Client's helo() and ehlo() has "HELO localhost" and
>> "EHLO localhost" hardcoded.  Using "localhost" as the value causes
>> some spam filters to give it a high spam score.
>
> I was under the impression that servers didn't use this value for
> anything, which is why I hardcoded it in the package. Do servers do
> anything with it besides scoring for spam? If not, is there another,
> better value we could use? Maybe os.Hostname?
>
> I'd prefer to find a more sensible default since most people won't
> know what to do with the extra option. And if we can do without the
> option altogether, that's better yet.

I'll try out os.Hostname as the value and see how it runs. I'm

Devon H. O'Dell

unread,
Jan 15, 2012, 9:44:46 PM1/15/12
to Dusty Wilson, Evan Shaw, golan...@googlegroups.com
2012/1/15 Dusty Wilson <du...@linux.com>:

> On Sun, Jan 15, 2012 at 5:35 PM, Dusty Wilson <du...@linux.com> wrote:
>>> Can we just use a static bit of text that isn't "localhost" that looks
>>> like a FQDN and it be passable?
>
> Risking sending too many messages about this... sorry.
>
> The Perl module Net::SMTP uses "localhost.localdomain" as the default
> hostname but allows it to be overridden.
> http://cpansearch.perl.org/src/GBARR/libnet-1.22/Net/SMTP.pm
>
> Postfix can be configured to interpret the hostname value and take
> action based on it:
> http://www.postfix.org/postconf.5.html#smtpd_helo_restrictions

Basically every MTA on the planet (even the crappiest ones) can be
configured to take action based on it, which is why I mentioned that
some places will 421 you after (EH|HE)LO with a name that doesn't
resolve to the IP (or a connecting IP that doesn't resolve to that
name). This isn't just something that affects spam policies.

> I think the question now is not if it should be possible to manually
> set this value, but how.

Indeed.

--dho

Dusty Wilson

unread,
Jan 17, 2012, 7:50:16 AM1/17/12
to Devon H. O'Dell, Evan Shaw, golan...@googlegroups.com
On Sun, Jan 15, 2012 at 6:44 PM, Devon H. O'Dell <devon...@gmail.com> wrote:
> Basically every MTA on the planet (even the crappiest ones) can be
> configured to take action based on it, which is why I mentioned that
> some places will 421 you after (EH|HE)LO with a name that doesn't
> resolve to the IP (or a connecting IP that doesn't resolve to that
> name). This isn't just something that affects spam policies.

I never did receive your first email on this where you mentioned 421.
I only found it because I went to the Google Group. Just wanted to
let you know I didn't ignore your words; I simply didn't receive them.
Oddly, I did get this one. Thanks.

>> I think the question now is not if it should be possible to manually
>> set this value, but how.
>
> Indeed.

I'd like to move forward. I'll post the patch to code review and I
guess we'll go from there.

Reply all
Reply to author
Forward
0 new messages