Kurt Seifried

Fedora 16 and Red Hat on EC2 with Sendmail using SMART_HOST with authentication

So I have a bunch of servers hosted on Amazon EC2 running Red Hat Linux / Fedora. Most of them are web front ends, so they need to be able to send email (alerts, status reports, etc.) but I don’t want to have to request that the email limit be increased on each server (as they come up and down a lot as demand requires).

So my obvious thought was to run an EC2 instance that would act as an email relay for all these servers. Easy enough, install a host with Sendmail, and allowing relaying. The trick here is that I don’t want to have to edit the access file every time a new host comes up or leaves as the level of IP address churn is quite high. So we enable email authentication, and pre-load EC2 images with the credentials to relay email through the server and we’re done.

So, foolishly, I thought I’d skip SMTP, and go straight to TLS encrypted SMTP (port 465), and require authentication. This way all the communications, email, authentication credentials and so on are well protected.I setup the Sendmail server, and tested it using Thunderbird, TLS+auth worked perfectly. However on the Sendmail client server side it did not work well, in fact I was unable to get it working at all, so if anyone knows how I’d love to hear from you.

Setting up the Sendmail Server with encryption and authentication

You’ll need to install sendmail and sasl:

yum install sendmail-cf cyrus-sasl-plain cyrus-sasl-md5 
cyrus-sasl-gssapi cyrus-sasl-lib cyrus-sasl-devel cyrus-sasl

and enable / start it:

systemctl enable saslauthd.service
systemctl enable sendmail.service
systemctl start saslauthd.service
systemctl start sendmail.service

Then you’ll need to edit /etc/mail/sendmail.mc, make sure these two lines are not commented out (they are by default):

TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl

and then enable submission:

DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea')dnl

Then you’ll need to enable encryption certificates:

define(`confCACERT_PATH', `/etc/pki/tls/certs')dnl
define(`confCACERT', `/etc/pki/tls/certs/CA_bundle.pem')dnl
define(`confSERVER_CERT', `/etc/pki/tls/certs/server.crt')dnl
define(`confSERVER_KEY', `/etc/pki/tls/private/server.key')dnl

and you’re basically done. Simply rebuild the sendmail configuration and restart it:

/etc/mail/make
systemctl restart sendmail.service

You’ll then need to ensure port 587 is not firewalled (either on the local system or in your EC2 security groups), and you’ll have to create local accounts with passwords so the clients can authenticate against them (e.g. create a user called “mail-relay” with a password and lock the account down).

You can easily test the server using an email client such as Thunderbird.

Setting up the Sendmail Client Server with encryption and authentication

First you’re going to need Sendmail and the syrus-sasl-plain rpms installed. The really annoying part is if you don’t install the cyrus-sasl-plain package email connections will fail, but the log files are less than helpful when this occurs:

May 20 23:22:48 ip-10-242-49-173 sendmail[9890]: q4L3MmFP009890: 
client.example.org [10.1.2.3] (may be forged) did not issue 
MAIL/EXPN/VRFY/ETRN during connection to MSA

To install the rpms simply:

yum install sendmail-cf cyrus-sasl-plain

So now to setup the client. This is woefully documented and there is a ton of conflicting information. To start with install the same sendmail and sasl packages as above. Then you’ll need a standard SMART_HOST entry line, but with the added options of telling it to use port 587 (submission) and a link to the file with the authentication information:

define(`SMART_HOST', `smarthost.example.org')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 587')
define(`ESMTP_MAILER_ARGS', `TCP $h 587')
FEATURE(`authinfo',`Hash -o /etc/mail/authinfo.db')dnl

You’ll also need to create an /etc/mail/authinfo file with contents such as:

AuthInfo:smarthost.example.org "U:user_name" "P:password_here" "M:PLAIN"

and build it using the makemap program:

makemap hash /etc/mail/authinfo < /etc/mail/authinfo

You can then restart sendmail and it should work, the log file from the client sendmail server:

May 14 02:51:01 ip-10-10-10-10 sendmail[3188]: q4E6p1aq005188: from=ec2-user, 
size=297,, nrcpts=1, msgid=<201205140651.q4E6p1aq003188@ip-10-10-10-10.ec2.internal>, 
relay=root@localhost

May 14 02:51:01 ip-10-10-10-10 sendmail[3189]: q4E6p12W003189: 
from=<ec2-user@ip-10-10-10-10.ec2.internal>, size=577,, nrcpts=1, 
msgid=<201205140651.q4E6p1aq003188@ip-10-10-10-10.ec2.internal>, 
proto=ESMTP, daemon=MTA, relay=localhost.localdomain [127.0.0.1]

May 14 02:51:01 ip-10-10-10-10 sendmail[3188]: q4E6p1aq003188: 
to=kurt@seifried.org, ctladdr=ec2-user (1000/1000), delay=00:00:00, 
xdelay=00:00:00, mailer=relay, pri=30297, relay=[127.0.0.1] [127.0.0.1], 
dsn=2.0.0, stat=Sent (q4E6p12W003189 Message accepted for delivery)

May 14 02:51:01 ip-10-10-10-10 sendmail[3191]: STARTTLS=client, 
relay=smarthost.example.org., version=TLSv1/SSLv3, verify=FAIL, 
cipher=DHE-RSA-AES256-SHA, bits=256/256

May 14 02:51:02 ip-10-10-10-10 sendmail[3191]: q4E6p52W003189: 
to=<kurt@seifried.org>, ctladdr=<ec2-user@ip-10-10-10-10.ec2.internal> 
(1000/1000), delay=00:00:01, xdelay=00:00:01, mailer=relay, pri=120577, 
relay=smarthost.example.org. [1.2.3.4], dsn=2.0.0, stat=Sent 
(q4E6p1ZE001355 Message accepted for delivery)

And on the server:

May 14 02:49:48 ip-1-2-3-4 sendmail[1349]: STARTTLS=server, 
relay=ec2-1-2-3-4.compute-1.amazonaws.com [1.2.3.4] (may be forged), 
version=TLSv1/SSLv3, verify=NO, cipher=DHE-RSA-AES256-SHA, bits=256/256

May 14 02:49:48 ip-1-2-3-4 sendmail[1349]: AUTH=server, 
relay=ec2-1-2-3-4.compute-1.amazonaws.com [1.2.3.4] (may be forged), 
authid=email-client, mech=PLAIN, bits=0

May 14 02:49:48 ip-1-2-3-4 sendmail[1349]: q4E6nmgg001349: 
from=<ec2-user@ip-10-10-10-10.ec2.internal>, size=795,, nrcpts=1, 
msgid=<201205140649.q4E6nmdE003182@ip-10-10-10-10.ec2.internal>, 
proto=ESMTP, daemon=MSA, relay=ec2-1-2-3-4.compute-1.amazonaws.com 
[1.2.3.4] (may be forged)

May 14 02:49:49 ip-1-2-3-4 sendmail[1354]: STARTTLS=client, 
relay=aspmx.l.google.com., version=TLSv1/SSLv3, verify=FAIL, 
cipher=RC4-SHA, bits=128/128

May 14 02:49:49 ip-1-2-3-4 sendmail[1354]: q4E6nmgg001349: 
to=<kurt@seifried.org>, delay=00:00:01, xdelay=00:00:01, mailer=esmtp, 
pri=120795, relay=aspmx.l.google.com. [173.194.68.26], dsn=2.0.0, 
stat=Sent (OK 1336912345 gs11si19555555aaa.999)

As you can see the email comes in, and is then handed off to gmail.