Use DKIM signature for outgoing emails

Email spoofing is the creation of email messages with a forged sender address. There are many services that provide protection from spoofing.

To be short it is possible to send email from any domain (including tech-notes.net) using the approach from this article

Today the most effective way to ensure the safety of the emails that originate under your domain is to use the combination of DKIM and SPF DNS records.

SPF - is a DNS record of the TXT type with the list of IP addresses or the domain names which are allowed to send outgoing emails form your domain

DKIM is using a way more fancy flow what includes encryption of your emails with the private key that is located on your relay server and decription of that emails by the target mails server using the public RSA certificate from the corresponding DNS record:

  • Public key for your domain is located in DNS
  • Private RSA key is located on the mail server

How does it work DKIM?

As you know every letter has a set of headers. The origin mail daemon (sender) hashes these headers and signs them using a private RSA key for every email that is being sent. The destination mail server (receiver) checks whether the signature hash matches the hash of the public key in the DNS zone. Next receiver either accepts the email ot acts according to the configured settings (reject, drop, mark as spam).

Why you should not ignore DKIM/SPF?

Email delivery is very important for online shops. If order confirmation emails are not delivered to customers then people may simply refuse to purchase from your store. Also continious greylisting affects the delivery of promo newsletters that reduces the amount of sales.

What should I do?

DKIM configuration includes the following steps:

  1. Create a pair of RSA keys that will be used to sign and validate outgoing mail.
  2. Create a DNS record containing the public key
  3. Configure the email daemon to use a private key to sign outgoing mail

1. Create a pair of RSA keys

Use openssl in linux:

openssl genrsa -out /etc/ssl/private/**example.com**-private.pem 1024 -outform PEM  
openssl rsa -in /etc/ssl/private/**example.com**-private.pem -out /etc/ssl/certs/**example.com**-public.pem -pubout -outform PEM

Alternatively you can use any online generator.

You’ll end up with two files:

  1. /etc/ssl/private/example.com-private.pem - private key
  2. /etc/ssl/certs/example.com-public.pem - public key

2. Create a DNS record

Read the public key

cat /etc/ssl/certs/example.com-public.pem

It looks like the following:

--BEGIN PUBLIC KEY--  
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD6MA3nwnUY9xdxftjSezCw0qgF  
8D2dwroEwc5fB/eI3JPdN3c9vAW37e6WpWEao9MEczGzMOj78SLQSKlXyQEtM4N2  
/Fld/fRve+iZJzT481jK9U34vZGYTUxWe2wHlUQHV8Vc1yDASF/1zpZg1ePMOCc7  
N+ocXzhSTQxo0c8jqwIDAQAB  
--END PUBLIC KEY--

We need tha part between the tags:

--BEGIN PUBLIC KEY--  
...
--END PUBLIC KEY--

This will be used as a value for the TXT DNS record Next create the DNS record with it

  1. emailrelay: key1.domainkey.example.com
    You can use anything as a value for _key1
    . Possible options are the following:
    • name of the server
    • current date
    • your pet name
  2. Type: TXT
  3. Value:"k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD6MA3nwnUY9xdxftjSezCw0qgF8D2dwroEwc5fB/eI3JPdN3c9vAW37e6WpWEao9MEczGzMOj78SLQSKlXyQEtM4N2/Fld/fRve+iZJzT481jK9U34vZGYTUxWe2wHlUQHV8Vc1yDASF/1zpZg1ePMOCc7N+ocXzhSTQxo0c8jqwIDAQAB"

You’ll need to give it a while for changes to propagate across the world. THe following website can be used to check the DNS propagation: https://www.whatsmydns.net/#TXT/

3. Configure the email daemon to use a private key to sign outgoing mail.

Exim
Create file `/etc/exim4/conf.d/main/00_local_macros` with the following contexts:
    DKIM_CANON = relaxed
    DKIM_SELECTOR = key1
    DKIM_DOMAIN = example.com
    DKIM_FILE = /etc/ssl/private/example.com-private.pem
Pay attention to `DKIM_SELECTOR`. Run the following to apply the changes:
    update-exim4.conf
    service exim4 restart
  
Postfix
Install `opendkim`
    apt-get install opendkim opendkim-tools
  
Edit config file `/etc/opendkim.conf`:
    Domain example.com
    KeyFile /etc/ssl/private/example.com-private.pem
    Selector key1
    SOCKET inet:8891@localhost
  
If your server sends mail on behalf of several domains then they must be described in the same file otherwise `opendkim` will ignore them. It is not a problem to use one key for all domains on your server Edit `/etc/default/opendkim` file. You need to change the default socket. Add the following at the end of the line:
    SOCKET=`inet:8891@localhost`
  
Edit Postfix config file (`/etc/postfix/main.cf`):
    # DKIM
    milter_default_action = accept
    milter_protocol = 2
    smtpd_milters = inet:localhost:8891
    non_smtpd_milters = inet:localhost:8891
  
    chmod 600 /etc/ssl/private/example.com-private.pem
  
Next restart `postfix` and `opendkim` to apply the changes.
    service opendkim restart
    service postfix restart
  
There is a good article at [HoToForge how to install OpenDkim from the source code](https://www.howtoforge.com/set-up-dkim-domainkeys-identified-mail-working-with-postfix-on-centos-using-opendkim).

At the end the email headers look like the following: Screenshot from 2016-03-01 11:48:15

External links:

  1. debian-administration.org/DKIM-signing_outgoing_mail_with_exim4
  2. a href="http://mikepultz.com/2010/02/using-dkim-in-exim/">mikepultz.com/using-dkim-in-exim</a>
  3. easyengine.ios/dkim-postfix-ubuntu