Updated: 10th Feb to include a postfix answer as well as a Ruby on Rails answer.

After successfully migrating our ruby on rails applications from our old three servers to one AWS EC2 instance, with fail-over. Clients started calling up with orders in their database, but no confirmation email in their emails.

So when a customer buys something off their site, it gets added to the CMS of the eCommerce site, and an email goes out to both the customers email address, and the eCommerce sites designated sales rep email. These were the emails that were not being received. (To trever@oursite.com for example)

So I set out diving into a very old postfix and (relatively new ~2007) amavis-new setup.

The Error:

Jul 11 10:40:41 mail.oursite.com.au /usr/local/sbin/amavisd30138:
(30138-04) SPAM, <imacustomer@hotmail.com> -> <trever@oursite.com>,
Yes, score=6.223 tag=2 tag2=5.5 kill=5.5 tests=[FH_HELO_EQ_D_D_D_D=0.498,
FORGED_HOTMAIL_RCVD2=1.117, HELO_DYNAMIC_IPADDR=2.935, HTML_MESSAGE=0.001,
MIME_HTML_ONLY=1.672], autolearn=no, quarantine XXXXXXXXXX (spam-quarantine)

As we are spoofing the “customer’s email” so that it will appear as “from iamacustomer@hotmail.com” in the inbox of the receiver, we get tagged a little. But what takes us over the edge is, HELO_DYNAMIC_IPADDR=2.935 Nearly 3 points for a helo dynamic ipaddress.

But Why?

With ec2 instances the reverse dns on the ipaddress is

ec2-01-234-56-78.ap-southwest-2.compute.amazonaws.com

Thus as we cannot request the remote dns to be pointing to that IP, as we cannot reserve IP’s (as far as I know) amavis flags this as a Dynamic IPAddress and thus gives it a score of 3. Now this is not enough by itself to cause amavis to have a fit and quarantine it to the folder of no returns cough /dev/null, but most spammers will proxy through open proxies which don’t usually have a fixed IP address thus, causing it to be flagged as dynamic and get flagged on the spam portion as well. It’s a great system. Now the the hell do I break fix it?

Side Note: If you have setup ActionMailer in your apps correctly you wont get these issues.

How to fix for all mail sent out:

It is actually very simple. Just tell postfix what hostname to use. Of course you must use a hostname that will resolve to the correct IP.

vi /etc/postfix/main.cf

Search for “myhostname” and add your hostname:

myhostname = mymailserver.aws.rdns.com

Now just restart postfix via init.d or upstart, and you should be seeing your hostname that you defined as your default.

If you are still having problems, I would suggest looking at your application and how it sends email. For some reason I must have missed the postfix myhostname variable when reading the man page, so I went on and dived into our ruby application.

How to patch your ruby application:

After rigorously attacking postfix and amavis for a couple hours I finally stopped putting off opening the ruby application to see how it ticks. FYI I’m not a ruby developer and in the end I just asked our ruby dev, wtf do i do? The key is in the ActionMailer gem. ActionMailer which comes by default in ruby gem installs. Simply add the :domain flag in your smtp_settings block in (production.rb & staging.rb for a multi stage environment) or in environment.rb.

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
  :domain 	=> "mymailserver.aws.rdns.com"
}

This domain flag should be set to the same cname you setup to point to the web server. It sets the HELO address which the server should identify itself as. The full text on the smtp_settings block:

Allows detailed configuration for :smtp delivery method: 
  :address – Allows you to use a remote mail server. Just change it from its default “localhost” setting. 
  :port – On the off chance that your mail server doesn’t run on port 25, you can change it. 
  :domain – If you need to specify a HELO domain, you can do it here. 
  :user_name – If your mail server requires authentication, set the username in this setting.
  :password – If your mail server requires authentication, set the password in this setting. 
  :authentication – If your mail server requires authentication, you must specify the authentication type here.
 This is a symbol and one of :plain, :login, :cram_md5.

Source: Action Mailer Basics on Guides @ Rubyonrails.org

So cap deploy to your staging/production environment and test it out. Should now fix all your errors with beautiful CLEAN messages in amavis.

Also, please post your ideas in the comments, or if you are hosting your mail in aws. Any issues you have received and or overcome.