The biggest four email providers Gmail, AOL, Hotmail and Yahoo (in this order according to Comscore) all implement some form of anti-spam techniques.
The main technologies are reverse DNS checking, SPF, SenderID, Domainkeys and DKIM. I will discuss all of these here and provide my tips on setting up SPF, SenderID and DKIM. Please keep in mind that I am not an expert on email servers – but I hope this helps someone! It took me about half a day to figure this all out, so it is probably worth doing to improve your email delivery rates.
This blog entry from Dave Zohrom provides a nice discussion of sending email to a general audience (part 2 of a 3-post series).
SPF or Sender Policy Framework
SPF is easy to setup. It uses DNS TXT records to allow the email providers to check which servers are authorized to send email for a particular domain. The SPF project has done a great job at making this simple to setup. Just go to their homepage and use the setup wizard to generate the appropriate TXT records (the text field underneath “Deploying SPF”). Then change the values in your DNS records.
One thing to note is that if you have multiple servers and send email from a server with a different hostname (e.g. “mail.example.com”), you need to setup a record for that server as well. See the common mistakes page on the SPF site. Also, if you have hostnames that are not supposed to send mail, you ought to indicate this as well.
Another thing is that if you are using Google Apps for Your Domain to send email, then you will need to have to add “include:aspmx.googlemail.com” to also allow mail from Google to validate. See this answer for more.
SenderID from Microsoft
SenderID is a variant of SPF, which for most practical cases is the same as SPF. Just setup SPF and this should produce a validation pass for SenderID as well. The semantics of the validation are a bit different, but this does not seem to be a major practical problem. See testing tips below to make sure that this is also true in your case.
DomainKeys is an older version of DKIM (DomainKeys Identified Mail) developed by Yahoo. Despite having very similar names, these ARE NOT the same!
Both DomainKeys and DKIM store public key information in DNS records and sign the message headers of every email sent. The recipient can then verify the signature.
DomainKeys was deprecated in 2007, but some email providers may still be using it. However, these are a shrinking minority and Yahoo does support the newer DKIM. Because of this I did not add DomainKeys support but opted only to use DKIM.
You can add it to sendmail or Postfix using the dk-milter project code, but the unofficial RPM release is not maintained anymore, which means you will need to install it from source (available via SourceForge).
DKIM, or DomainKeys Identified Mail
DKIM on the other hand seems to be gaining momentum. It is used by Gmail, Yahoo and AOL and many others, and also works by publishing public keys via DNS TXT records and by signing the emails at the email server.
To setup DKIM, you need an additional filter which takes the completed email and adds the DKIM signature to the email prior to sending it out.
Postfix and sendmail support “milters“, which is apparently short for “mail filter”. There is a DKIM-milter package available for Centos at the EPEL repositories (see Centos page for 3rd party repos).
Setting up DKIM-milter with sendmail
Updated: Linked tutorial is DEAD. Here are the steps:
Step 1. Generate a private key
openssl genrsa -out default.private 1024
A “default.private” key file will be generated. It will be moved to a specific location later.
Step 2. Generate a public key for this private key
openssl rsa -in default.private -pubout -out default.public -outform PEM
A file with filename “default.public” will be generated with content like
—–BEGIN PUBLIC KEY—–
—–END PUBLIC KEY—-
It will be used to create a DNS TXT record. See next step.
Step 3. Create a DNS record of type TXT
Modify DNS records and add a record of type TXT:
TXT record name
TXT record value
v=DKIM1; g=*; k=rsa; p=<content of default.public>
Note that the prefix “—–BEGIN PUBLIC KEY—–” and suffix “—–END PUBLIC KEY—-” should not be put in the TXT record value.
This DNS record will be retrieved by mail receivers who want to verify emails with DKIM signatures. The record name “default._domainkey” tells verifier that the “selector” of this signature is “default”, therefore if you are changing selector name to something else, make sure you change all of them consistently.
Step 4. Install dkim-milter in Fedora
Run the following as root to install the dkim-milter pacakge.
yum install dkim-milter
Step 5. Enable dkim-milter to run on start-up
Make sure dkim-milter service will run on start-up by running this command:
chkconfig –level 3 dkim-milter on
Note that your server may use a different “runlevel”. You can check “/etc/inittab” to see which run level you are on.
Step 6. Move private key to appropriate location
As root, copy the private key to the location specified by the “keylist” (refer to next step) and make sure it is readable by dkim-milter:
mv default.private /etc/dkim-milter/default
chown dkim-milter.dkim-milter /etc/dkim-milter/default
Make sure the filename of private key file matches the “selector” name specified in the DNS record.
Step 7. Add an entry to the keylist for dkim-milter to read
Add the following line to /etc/mail/dkim-milter/keys/keylist. Replace <domain.com> with your domain name.
Step 8. Configure dkim-milter
Open configuration file /etc/mail/dkim-milter/dkim-filter.conf and use the following configuration:
Canonicalization simple Domain example.com KeyFile /some/path/to/whatever-your-keyfile-was Selector name-of-the-selector SignatureAlgorithm rsa-sha256 Socket inet:8891@localhost Syslog Yes Userid dkim-milter
NOTE: you will be configuring dkim-milter to use the loopback interface instead of a socket file. I was unable to get dkim-milter to work via the socket file with sendmail. If you get it working, let me know.
You may also want to setup the following:
SubDomains Yes SyslogSuccess Yes X-Header Yes
The X-Header and Syslog options are useful for debugging. See the config file, each option should be documented there.
Step 9. Change the default init.d script to use the loopback interface
The default init script uses a socket, this needs to be changed. Open /etc/init.d/dkim-milter and change/comment the line:
Step 10. Configure sendmail to use dkim-milter
First a few reminders about sendmail configuration, remember that:
1. Sendmail comments DO NOT USE # as the comment, instead “dnl” (delete through newline) at beginning of the line is used to comment lines out.
2. Sendmail configuration is built from the *.mc script files using the M4 macro processor.
3. You need to install the sendmail-cf package for dependencies and install the m4 macro processor separately.
4. In the configuration, the opening quote is a grave accent ` and the closing quote is a straight quote ‘.
To configure sendmail, open the “/etc/mail/submit.mc” file (which contains the settings for message sending; in older sendmail versions this config was in sendmail.mc).
10.1 Edit submit.mc by adding the following entry to it:
(for example just before “FEATURE(`msp’, `[127.0.0.1]‘)dnl”). Make sure that there are no define(`confINPUT_MAIL_FILTERS’, `…’)dnl lines after this; if there are, you will need to add dkim-milter manually to the INPUT_MAIL_FILTERS list.
10.2 Build and install a new submit.cf:
m4 /etc/mail/submit.mc > submit.cf
Tip: use m4 -d /etc/mail/submit.mc to debug first.
10.3 Restart sendmail
service sendmail restart
Some possible errors:
- Errors getting the sendmail configuration generated: Check whether the dependencies (m4 and sendmail-cf) are installed and paths are correct.
- Errors starting sendmail: Make sure you replaced the correct files (submit.mc to submit.cf and sendmail.mc to sendmail.cf) and if you modified sendmail.mc in addition to submit.mc, make sure you have regenerated both.
- Errors starting dkim-milter: check the permissions on the key file
- Sendmail seems to ignore the dkim-milter, no X-dkim-milter header is in the mail even after you enabled the X-Header option in dkim-filter.conf:
- Check /var/log/maillog.
- Sendmail seems to default to ignoring the milter if it cannot connect to it. This was the problem I ran into when using sockets; after switching to the loopback interface everything started working.
- Also, check whether your mail is sent from a recipient for whom mail is supposed to be signed! If you haven’t setup your hostname, then this may lead to email not being signed (eg. hostname -F hostname plus /etc/hosts plus /etc/sysconfig/network). See, for example this tutorial for configuring sendmail.
- Also, check if you need to configure masquerading for Sendmail, see http://www.sendmail.org/m4/masquerading_relaying.html
Sending email from the console using only sendmail
Create a file with the following content:
To: "Recipient name" <email@example.com> From: "Sender name" <firstname.lastname@example.org> Reply-To: email@example.com Subject: Hello world This is the content of the message, end it with a line containing only a period as sendmail expects this. .
Then cat the file and pipe to sendmail -t:
cat message.txt |sendmail -t
Checking all of the technologies mentioned above
Port25.com offers a free service which check SPF, SenderID, DomainKeys and DKIM: http://port25.com/domainkeys/
- If you wish to receive the results at the address in the “mail_from,” the sample message should be sent to firstname.lastname@example.org.
- If you wish to receive the results at the address in the “from” header, the sample message should be sent to email@example.com.
A reply email will be sent back to you with an analysis of the message’s authentication status. The report will perform the following checks: SPF, SenderID, DomainKeys, DKIM and SpamAssassin.