As in the post about initial DNS setup, I will call “new.example” the new domain name, and “old.dyn.example” the former free domain name. When it comes to DNS configuration, I will always show the expected input (web form), and then the result using the DNS syntax.

Before going deeper into email-specific DNS configuration, let me start by putting into the DNS the record that will make it so, that any email to an address of the form “someone@new.example” is directed to my “new.example” server. This is accomplished by a MX record:

Name     : new.example
Priority : 10
Hostname : new.example
TTL : 86400

new.example. 86400 IN MX 10 new.example.

The initial problem

Electronic mail suffers from an important quantity of SPAM, all too often malicious. As a counter-strike, many techniques have been put to work over the part years. For the sake of interoperability, these techniques are rarely blocking by themselves. Instead, each email server chooses several techniques, runs them, and computes a global score based on the result from running each technique; thus it is that each message is classified as either SPAM or HAM.

Having a free domain name, running from a residential IP address, that may change over time, makes a total of three bad points when it comes to evaluate messages from my server. Problems linked to the IP address can be mitigated by configuring the server to send emails through a “smarthost”. In my case, since SFR is my Internet service provider, I use one of SFR’s SMTP servers as a “smarthost”: targeting Exim, I ensure that the following line is part of the /etc/exim4/update-exim4.conf.conf file:

dc_smarthost='mail.club-internet.fr'

Then I restart Exim, after the configuration has been updated using the update-exim4.conf command.

Sure, the above line is a bit old… Club-Internet was bought by Neuf, which was bought by SFR… But it still works, so I will not change it. Anyway, such a configuration results in all my emails being sent through SFR, and thus appearing to be sent from an IP address of SFR’s, instead on mine.

This trick is not fail-safe, though, because one anti-spam technique consists of looking for information about the sender’s domain (the part after the @ sign); then there is no escaping the fact that the IP address associated to my domain name is my own residential IP address.

The aim of using my own domain name is in part to loose the “dynamic domain name” tag, and also to satisfy as well as possible the curiosity of other servers that inquire about the senders from my domain.

Sender Policy Framework (SPF)

The easiest technique to set up is SPF. Its purpose is to broadcast the knowledge of which servers are allowed to send emails, when the sender pretends to be from my domain. Take great care: misconfiguration of SPF can result in loosing all emails sent from the server! The SPF rules can be tested with an on-line tool before they get committed to DNS.

The SPF syntax provides many possible ways to define the rules. I chose to list the servers by name, which is to say the domain names that I use; and I also include the SPF rules associated with email addresses of the form “someone@sfr.fr”, because I configured Exim in “smarthost” mode, which results in my emails appearing to be sent from SFR’s SMTP servers. As a consequence, here is the DNS rule that I use; it is a record of type SPF:

Name     : new.example
SPF data : v=spf1 a:new.example a:old.dyn.example include:sfr.fr -all
TTL : 86400

new.example. 86400 IN SPF "v=spf1 a:new.example a:old.dyn.example include:sfr.fr -all"

This SPF expression means that:

  1. if the message comes from the IP address associated with “new.example”, then the SPF test succeeds, else step 2 is evaluated;
  2. if the message comes from the IP address associated with “old.dyn.example” (this IP should be the same, but there is no harm in being cautious), then the SPF test succeeds, else step 3 is evaluated;
  3. if the SPF evaluation of the rules coming from the DNS for the sfr.fr domain is successful, then the SPF test succeeds, else step 4 is evaluated;
  4. in all other cases, the SPF test fails.

It might be better to replace “-all” with “~all” in this rule (in order to avoid rejected emails), because of a SPF flaw that might keep your relatives from forwarding emails they received from you… I am not sure…

In the former days of SPF, the DNS SPF record type was not available, which led people to use a TXT record instead. As a precaution, I prefer to also create this record:

Name      : new.example
Text data : v=spf1 a:new.example a:old.dyn.example include:sfr.fr -all
TTL : 86400

new.example. 86400 IN TXT "v=spf1 a:new.example a:old.dyn.example include:sfr.fr -all"

Once these DNS records have been committed, it is highly advisable to test them as soon as possible, and make sure they don’t block legitimate emails; this is easily achieved by sending an email to check-auth@verifier.port25.com, which triggers an automatic answer containing a complete diagnosis. Tip: at first, il may be a good idea to create DNS records with a small TTL (5 minutes for example); the TTL can be augmented after the rules have been validated.

Although configuring SPF cannot be a bad thing, it should be noted that it did not gain me anything on the SpamAssassin score computed by port25.com

DomainKeys Identified Mail (DKIM)

Things are getting more interesting here, and more complicated too. DKIM works by making the server digitally sign all emails with a private key; third-party servers then check that the signatures found in the emails are valid, using the public key that can be retrieved from the DNS.

The following explanations are written with Exim on Debian Linux in mind. The biapy.com web site has a very good explanation of each step to go through. For other email servers, the part about the cryptographic keys should be mostly applicable as it is; the rest is bound to need adaptations.

First step is to generate a private key:

mkdir /etc/exim4/dkim
openssl genrsa -out /etc/exim4/dkim/new.example_dkim.privk.pem 1024
chown root:Debian-exim /etc/exim4/dkim/new.example_dkim.privk.pem
chmod 440 /etc/exim4/dkim/new.example_dkim.privk.pem

(Extra spaces are meaningless; their only purpose is to enhance readability)

I chose to create a 1024-bit key because it seems that keys made of less bits are insufficient these days. Then I have to generate the public key, with the right format:

openssl rsa -in /etc/exim4/dkim/new.example_dkim.privk.pem -out /etc/exim4/dkim/new.example_dkim.pubk.der -pubout -outform DER
base64 -w 0 >/etc/exim4/dkim/new.example_dkim.pubk.der.b64 </etc/exim4/dkim/new.example_dkim.pubk.der
echo >>/etc/exim4/dkim/new.example_dkim.pubk.der.b64

(Extra spaces are meaningless; their only purpose is to enhance readability)

Next comes the configuration of Exim, which is done by creating a /etc/exim4/conf.d/main/00_myconfig configuration file, the contents of which is:

# The signing method for DKIM
DKIM_CANON = relaxed

# Domain for which DKIM signing is used.
DKIM_DOMAIN = new.example

# private key used for DKIM.
DKIM_PRIVATE_KEY = /etc/exim4/dkim/new.example_dkim.privk.pem

# DKIM selector
DKIM_SELECTOR = myselector

myselector” being the host name for my server. This is a personal choice, considering the rule: there should be a unique “selector” for each host that is allowed to send emails for my domain name; in the present situation, there is only one server anyway…

I differ slightly from the fore-mentioned article: since I only manage the DNS for one domain name, and thus enable DKIM on this single domain only, I choose to set the value of the DKIM_DOMAIN variable (see above), thus I do not need to execute the sed command that is listed in the article.

At this point, Exim can be restarted, after I have updated the configuration, using the update-exim4.conf command. Now comes the DNS configuration, namely the addition of four TXT records:

Name      : myselector._domainkey.new.example
Text data : v=DKIM1; k=rsa; p=EXACT_CONTENTS_OF_/etc/exim4/dkim/new.example_dkim.pubk.der.b64
TTL : 86400

myselector._domainkey.new.example. 86400 IN TXT "v=DKIM1; k=rsa; p=EXACT_CONTENTS_OF_/etc/exim4/dkim/new.example_dkim.pubk.der.b64"
Name : _adsp._domainkey.new.example
Text data : dkim=all
TTL : 86400

_adsp._domainkey.new.example. 86400 IN TXT "dkim=all"
Name : _asp._domainkey.new.example
Text data : dkim=all
TTL : 86400

_asp._domainkey.new.example. 86400 IN TXT "dkim=all"
Name : _domainkey.new.example
Text data : o=-;
TTL : 86400

_domainkey.new.example. 86400 IN TXT "o=-\;"

The first DNS record provides the public DKIM key for my domain, for those times when my server sends an email (the “selector” is read from the email that the third-party server is wishing to verify). The next three records inform that DKIM is used on all emails, the sender of which pretends to be part of my domain; thus a non-signed message can safely be considered a fraud.

Once again, DKIM can be tested by sending an email to check-auth@verifier.port25.com, which triggers an automatic answer containing a complete diagnosis. Tip: at first, il may be a good idea to create DNS records with a small TTL (5 minutes for example); the TTL can be augmented after the rules have been validated.

Enabling DKIM on my server allows me to gain 0.1 point on the SpamAssassin score, that is computed by port25.com. My final score thus becomes −2.0 instead of −1.9, with lower scores being better, and 5.0 being the limit that port25.com accepts before considering the email as a SPAM. In contrast, sending emails directly from my residential IP address, without going through the “smarthost”, makes me loose 3.3 points, thus making my overall score 1.3 instead of −2.0! Obviously, I choose to go through the “smarthost”…

I wish to thank Tonitrus on ##English @ freenode.net (IRC), for his help in translating one particularly tricky line of French text.