3

While trying to setup postfix to allow a website to sent password reset emails I've noticed that when sending emails form the command line using

echo "body" | mail -s "subject" test@example.com

the emails arrive just fine and are not marked as spam. However, when sending from withing the sites server, the header is set as being received from localhost and thus is marked as spam.

Received: from example.com (localhost [127.0.0.1])
by example.com (Postfix) with ESMTPS id CE1299C435
for <my_email@gmail.com>; Tue,  2 Aug 2016 05:28:41 +0000 (UTC)

As a note, dkim, spf and dmarc test all list as passed, so they are not the problem.

I have also tried sending an email with the same content using the above echo method and had it arrive fine (although plaintext as I used it as above and didn't add the content type headers).

Initially this was sent using smtp.SendMail

err := smtp.SendMail(hostname + ":25", nil, sender, recipients, []byte(msgstr))

which provides no way to set sending host, so in an attempt to correct this I switched to using a manual dial, sending a HELO message, then starting tls (attempting to start tls before the HELO resulted in a panic saying the HELO had to be the first call)

c, err := smtp.Dial(host + ":25")
if err != nil {
    log.Panic(err)
}

if err = c.Hello(host); err != nil {
  log.Panic(err)
}

if err = c.StartTLS(config.TLS()); err != nil {
  log.Panic(err)
}

This still sends the email successfully, but as before the received header still shows localhost as the origin, I feel I've misunderstood something as I believed that HELO served to identify where the call was coming from.

Your advice and help is appreciated, this is the first time I've tried to configure an MTA and use it like this, there has been a bit of a learning curve that I'm evidently not over yet.

ain
  • 22,394
  • 3
  • 54
  • 74
Scott Owens
  • 61
  • 1
  • 4
  • I would check /etc/hosts and make sure hostname (from smtp.SendMail) points to the external ip address of the server, not 127.0.0.1. – Juergen Gmeiner Aug 02 '16 at 07:16
  • hostname is equal to the fqdn of the server for both calls. hosts file is correct by my understanding of the syntax used, but I'm new to setting this up so the relevent line is 127.0.0.1 localhost example.com – Scott Owens Aug 02 '16 at 11:37
  • I think that is the problem. If example.com resolves to 127.0.0.1 and you send mail to example.com via smtp, the reverse lookup of the sending ip address will be 127.0.0.1 localhost. I would try pointing example.com at 10.77.88.99 (substitute the real externally reachable ip address). The first name for that address will then show up in your via-line – Juergen Gmeiner Aug 02 '16 at 13:44
  • changing the order was sufficient, changing it to 127.0.0.1 example.com localhost, resulted in everything still working and the received header being set correctly, still showing up in spam for some reason though, not sure why, but the problem I asked about is solved, Thank you Juergen. – Scott Owens Aug 03 '16 at 02:26
  • I think now the problem is that a gmail.com address uses example.com as mail relay. Usually the smtp server has to be the official (as of dns mx record) smtp server for the sending email address. Why don't you do your 'echo "body" | mail -s "subject" test@example.com' trick from go? https://golang.org/pkg/os/exec/#example_Cmd_StdoutPipe except pipe into StdinPipe – Juergen Gmeiner Aug 03 '16 at 06:26
  • I'm not actually using example.com, I changed the references in all the provided sources to make it more generic and easier for other people with the same problem to mentally substitute their own domain. Running the echo equivalent within go wouldn't have produced a desirable outcome either as it would make adding other headers very difficult. Changing the entries in /etc/hosts as Juergen suggested worked in the end, so Ill be marking this question closed shortly. – Scott Owens Aug 03 '16 at 10:46

1 Answers1

2

As Juergen Gmeiner suggested in the comments, my problem ended up being caused by a poorly configured /etc/hosts file, such that it wasn't effecting other services.

The existing entry was:

127.0.0.1 localhost example.com

Changing this to:

127.0.0.1 example.com localhost

solved the problem while not breaking the existing services that needed localhost to evaluate properly.

This solution worked for my locally hosted server process, if the same problem occurs with a remote server, and equivalent like would need to be created with the ip and hostname of the remote. i.e.

<remote ip> <hostname>

note: while I tested that this last part by calling from my local development build to our production server and it worked, its not a 100% tested solution.

Thank you all for your help, and I hope that this mistake on my part helps anyone else who makes a similar error in the future.

Scott Owens
  • 61
  • 1
  • 4