In the previous blogpost I have been discussing how SPF works and how it uses public DNS to validate the authenticity of the sending SMTP servers. When SPF is implemented correctly a receiving mail server can validate is the sending mail server is allowed to send email on behalf of the sender or his organization.
In this blogpost I will discuss DKIM signing as an additional (and more complicated, and more difficult to spoof) step in email validation.
As a quick reminder, here’s how my lab environment looks like:
There’s an Exchange 2016 CU2 Mailbox server hosting several Mailboxes, and there’s an Exchange 2016 CU2 Edge Transport server. An Edge synchronization will make sure that all inbound and outbound SMTP traffic is handled by the Edge Transport server.
In my previous blogpost an SPF record was created and implemented with the following value:
v=spf1 a:smtphost.exchangelabs.nl ~all
so receiving mail servers can validate that my Edge Transport server is allowed to send email on my behalf, and when mail is originating from another mail server it might well be a spoofed message.
But for now let’s continue with DKIM.
Domain Keys Identified Mail
DKIM, which stands for Domain Keys Identified Mail is another solution. It is not a true anti-spam solution, but more a legitimate validation solution. And when an email message is validated it is most likely not spam (that is, as long as the sender’s environment is not compromised or course).
DKIM is all about signing and verifying of email messages. As such you can compare it to the signing capabilities of S/MIME, where S/MIME is client based and DKIM is server based.
DKIM consists of two operations:
- Signing of the message. This can be achieved by the sending host itself, or can be done by a 3rd party application or service. When signing a message, the signing module inserts a DKIM-Signature header to the message with the appropriate information. This signing module uses a private key to create a signature, therefore ensuring that only this server (or organization) can sign messages.
- Verifying of the message. Just like signing this can be performed by the receiving host, or by a 3rd party application or service. The verification module reads the information in the DKM-Signature field and verifies the signature using the sending organization’s public key.
The private and public key form a key pair. The private key is only known at the sending mail servers, the public key is published in the sender’s public DNS server and as such available to everyone that needs to validate the signed message.
So, the DKIM-Signature header plays an important role in DKIM, and a typical DKM-Signature header can look like this:
DKIM-Signature: v=1; a=rsa-sha256; d=example.net; s=brisbane;
c=relaxed/simple; q=dns/txt; l=1234; t=1117574938; x=1118006938;
The following tags can be identified in a DKIM Signature header:
- v = version
- a = signing algorithm
- d = Domain
- s = Selector
- c = Canonicalization algorithm for body and header
- q = Query method
- l = length of canonicalization part of the body
- t = timestamp signature
- x = expiration time
- h = list of signed header fields
- b = hash of the selected message headers
- bh = hash of the message body
To sign a message, the signing module first creates a hash of the message body, stored with the bh tag. Next is that selected headers in the message are hashed, these are stored in the b tag. So, two hashes are being created. Both hashes are stored in the DKIM header of the message. Both are clearly visible in the DKIM-Signature header example above.
To sign a message, you need a key pair. The private key is used by the mail server to sign the message, the public key is stored in DNS and can be retrieved by the receiving server to decrypt the signature. How do you get a key pair?
You can use the http://dkimcore.org site to generate a key pair. This should be used for testing purposes only since the key pair is generated and stored (ok, maybe temporarily) on this website.
The generated private key should be entered in the signing module on the sending mail server, this looks something like this:
—–BEGIN RSA PRIVATE KEY—–
—–END RSA PRIVATE KEY—–
The generated public key (in BIND 9 DNS format) looks something like this:
1471253148.exchangelabs._domainkey.exchangelabs.nl. IN TXT (
The selector in this example is “1471253148.exchangelabs” and the selector is the DNS record where the public key is stored.
Note. In this example the actual public key (Base64 encoded) is
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmutszXoY6C8/xlzy/Hrz954Gy5zf0O8q/+brIO9o+WyYeoMkNjs2NEy9z20Ur7t1lP 64KH7dx/BKK6hlwRKxTw70D MU5HC5ZJtvLYuiiUz3KGuEMDSwsBpY4aAtDhVG7CjYheSoIQ5kD2EcvnZJaQTPTatKLxEwImU2tYwPmqyQIDAQAB
Onced added to DNS you can use the http://dkimcore.org/tools site to test the public DKIM Core key. You can enter the selector and domain name, or you can enter the record that was found in the previous step. Entering the selector and domain name makes the most sense I guess:
Click Check to check the DKIM records in DNS and you’ll see something like this:
You can also use the http://mxtoolbox.com/dkim.aspx site to test your DKIM record, just enter the domainname and the selector:
Note. You can use the key pair as created by DKIMCORE.ORG for testing purposes, and if you delete the key pair from this site you should be able to use it in production as well. However, this can impose a security risk. Since the key pair was created on the Internet you never now what happens with the key pair. A better solution is to generate a keypair using a tool like OPENSSL or PUTTYGEN.
So, at this point everything is in place. There’s a private key for signing messages, there’s a public key stored in DNS and you’re ready to go. Messages are sent your (sending) server, the receiving server will read the header of the message, and based on the selector key the server can retrieve the public key to validate the signature.
Exchange Server and DKIM
There’s one more important thing though…. You might have noticed I haven’t used the name “Exchange server” in the previous section, and that’s because Exchange does not support DKIM signing and verifying out of the box. You need to use 3rd software for this, but on GitHub you can download some DKIM signing software as well.
When downloaded, extracted and installed (on the Exchange 2016 Edge Transport Server) you can configure the DKIM signing module (which is basically a transport rule). The most important tab is the Domain Settings where you can configure domain specific settings:
When a message is sen, the DKIM signer will process the message, sign the message and add the DKIM Information header. Send out an email message to another external Mailbox (I used a Mailbox in Office 365 because Office 365 can verify signed DKIM messages), and you’ll see the following similar information in the message header:
DKIM-Signature: v=1; a=rsa-sha256; d=Exchangelabs.nl;
s=1471253148.exchangelabs; c=simple/simple; t=1471374160;
The DKIM-Signature looks legitimate, and there’s more information in the message header, information regarding the authentication itself:
Authentication-Results: spf=pass (sender IP is 18.104.22.168)
smtp.mailfrom=Exchangelabs.nl; wesselius.info; dkim=pass (signature was
verified) header.d=Exchangelabs.nl;wesselius.info; dmarc=bestguesspass
action=none header.from=Exchangelabs.nl;wesselius.info; dkim=pass (signature
was verified) header.d=Exchangelabs.nl;
Received-SPF: Pass (protection.outlook.com: domain of Exchangelabs.nl
designates 22.214.171.124 as permitted sender)
At this point both SPF and DKIM are working correctly for my Exchange 2016 environment, and the Edge Transport server is properly signing email messages using DKIM.
Unfortunately at this moment I only have a DKIM signing module on my Exchange server and I wasn’t able to find a DKIM verifying module.
DKIM is all about signing and verifying header information in SMTP messages. Since siging happens with a private key that is only available to your mail server a receiving mail server can be sure the the message really originates from your organization, and that it is not a spoofed message.
DKIM is using a key pair, where the private key is used by the sending mail server, and where the public key is stored in a DNS record in public DNS. It looks a bit complex, and most Exchange admins think it is complex, but when you play around with DKIM in a lab environment you quickly learn that it isn’t that bad.
This blog post was about installing and configuring DKIM on an Exchange 2016 server, and the software that I downloaded from GitHub is also available for Exchange 2013 and Exchange 2010. If you don’t want the hassle of installing and configuring you can also opt for using a 3rd party device or service like IronPort, Exchange Online Protection (EOP) or MessageLabs which offer DKIM services as well.
In my next blog I’ll discuss DMARC, since DMARC is built on top of SPF and DKIM.
- DomainKeys Identified Mail – https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
- DomainKeys Identified Mail (DKIM) Development, Deployment and Operations – http://dkim.org/specs/draft-ietf-dkim-deployment-11.html
- Exchange Online is rolling out default DKIM-signing to everyone – https://blogs.msdn.microsoft.com/tzink/2015/12/16/exchange-online-is-rolling-out-default-dkim-signing-to-everyone/
- Enable explicit DKIM signing in Office 365 – https://supertekboy.com/2016/06/27/enable-dkim-signing-office-365/
- EmailArchitect Support Forum – https://www.emailarchitect.net/forum/yaf_postst357_Set-up-DKIM-in–Exchange-2007-2010-2013.aspx
- DKIM Signing Agent for Microsoft Exchange Server – https://github.com/Pro/dkim-exchange
- Enhanced email protection with DKIM and DMARC in Office 365 – https://blogs.office.com/2015/01/20/enhanced-email-protection-dkim-dmarc-office-365/
- Manually hooking up DKIM signing in Office 365 – https://blogs.msdn.microsoft.com/tzink/2015/10/08/manually-hooking-up-dkim-signing-in-office-365/
- DomainKeys Identified Mail (DKIM.ORG) – http://dkim.org/`