DKIM/SPF/DMARC Verification and Authentication in Exchange Server - Tutorial

DKIM, SPF and DMARC mechanisms are used to validate a domain name identity that is associated with an email message. Verifying DKIM, SPF and DMARC records of inbound email is very helpful to stop spam or spoofing email message.

In this tutorial, I will introduce how to verify and authenticate DKIM signature, SPF record and DMARC record of inbound email messages in Exchange Server 2007/2010/2013/2016 by transport agent.

How DKIM works?

DKIM combines of a public key cryptography and a DNS to provide credible domain-level authentication for email.

When an email claims to originate from a certain domain, DKIM provides a mechanism by which the recipient system can credibly determine that the email did in fact originate from a person or system authorized to send email for that domain.

How DKIM works?

How SPF works?

Sender Policy Framework (SPF) is a simple email-validation system designed to detect email spoofing by providing a mechanism to allow receiving email servers to check that incoming mail from a domain comes from a host authorized by that domain’s administrators based on sender IP address.

How SPF works?

How DMARC works?

Domain-based Message Authentication, Reporting and Conformance or DMARC is a method of email authentication, which is a way to mitigate email abuse. It expands on two existing mechanisms, the well-known Sender Policy Framework (SPF) and DomainKeys Identified Mail (DKIM), coordinating their results on the alignment of the domain in the From: header field, which is often visible to end users.

How DMARC works

Enable DKIM/SPF/DMARC for Outbound email

In this tutorial, we only focus on DKIM/SPF/DMARC verification and authentication.

To enable DKIM/SPF/DMARC for outbound email message in Exchange Server, please refer to the following tutorial:

Install DKIM Plugin in Exchange Server 2007/2010/2013/2016

To enable DKIM/SPF/DMARC verification in Exchange 2007/2010/2013/2016, you should download the DKIM Installer and install it on your server at first.

Note

Exchange Server Role

If you installed Exchange Server 2007/2010/2013/2016 on multiple servers, you don’t have to install DKIM plugin on every server.

  • If there is Exchange Edge Transport Server Role installed, you just need to install DKIM plugin on this server.
  • If there is no Exchange Edge Transport Server Role installed, you just need to install DKIM plugin on every Exchange Hub Transport Server Role.

Double click installer file and the installation will be executed automatically. Installer requires Exchange server to be installed. If no Exchange server detected in your operation system, Setup will be aborted.

Important

After the installation is complete, I strongly suggest that you go to Control Panel -> Administrative Tools -> Services, and check if “Microsoft Exchange Transport Service” and “Microsoft Exchange Mail Submission Service” are running, if those service are not running, please start it.

Enable Inbound Transport Agent

By default, DKIM plugin only enables outbound DKIM agent after installation is completed, so you need to enable DKIM inbound transport agent manually.

Open Exchange Management Shell and input:

enable-transportagent "EA Dkim Inbound Agent"
get-transportagent
Enable DKIM/SPF/DMARC inbound agent in Exchange Server.

You can see EA Dkim Inbound Agent is enabled now, you need to restart “Microsoft Exchange Transport Service” in Control Panel -> Administrative Tools -> Services to take effect.

Or you can restart “Microsoft Exchange Transport Service” in Exchange Management Shell directly:

Restart-Service "MSExchangeTransport"

Important

Every time after you executed installation or upgrade, you need to enable inbound transport agent and restart “Microsoft Transport Service” again.

Disable Inbound Transport Agent

You can disable this agent temporally in case you don’t want to use it anymore.

disable-transportagent "EA Dkim Inbound Agent"

Configuration File and First Test

You can find the configuration file in installation path\DkimInboundAgent.dll.config, the default installation path is C:\Program Files (x86)\EAExchDomainKeys. It is in XML format, you can use notepad or other text editor to edit it.

Enable DKIM/SPF/DMARC inbound agent in Exchange Server.

Note

Every time after you changed configuration file, you don’t have to restart “Microsoft Transport Service” again

Here is the default content of configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
    <section name="spfResultToReject"  type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="dkimResultToReject" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="trustedIPAddresses" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>

<spfResultToReject>
    <!--
    <add key="fail" value="550 5.7.1 your message from [%source_ip%] is against our SPF policy (fail)" />
    <add key="softfail" value="550 5.7.1 your message from [%source_ip%] is against our SPF policy (softfail)" />
    <add key="none" value="550 5.7.1 your message from [%source_ip%] is against our SPF policy (none)" />
    <add key="neutral" value="550 5.7.1 your message from [%source_ip%] is against our SPF policy (neutral)" />
    <add key="temperror" value="451 4.4.3 your message from [%source_ip%] encountered a temporal error with SPF verification (temperror)" />
    <add key="permerror" value="550 5.7.1 your message from [%source_ip%] encountered a permanent error with SPF verification (permerror)" />
    -->
</spfResultToReject>

<dkimResultToReject>
    <!--
    <add key="fail" value="550 5.7.1 your message from [%header_from%] is against our DKIM policy (fail)" />
    <add key="none" value="550 5.7.1 your message from [%header_from%] is against our DKIM policy (none)" />
    <add key="neutral" value="550 5.7.1 your message from [%header_from%] is against our DKIM policy (neutral)" />
    <add key="temperror" value="451 4.4.3 your message from [%header_from%] encountered a temporal error with DKIM verification (temperror)" />
    <add key="permerror" value="550 5.7.1 your message from [%header_from%] encountered a permanent error with SPF verification (permerror)" />
    -->
</dkimResultToReject>

<trustedIPAddresses>
    <add key="127.0.0.1" value="pass"/>
    <!--
        <add key="192.168.0.0/24" value="pass"/>
    -->
</trustedIPAddresses>

<appSettings>
    <add key ="logLevel" value="OnlyError"/>
    <!-- <add key ="LogLevel" value="FullDebug"/> -->
    <add key ="trackingSender" value="*"/>
    <add key ="trackingSourceIP" value="*"/>
    <add key ="useLastExternalIPAddress" value="false"/>
</appSettings>
</configuration>

Simple Inbound DKIM/SPF/DMARC Test

To verify if inbound transport agent is working, change

<add key ="logLevel" value="OnlyError"/>

to:

<add key ="logLevel" value="FullDebug"/>

and then send a test email from outside domain. Do not send test email from Outlook/WebAccess, because those messages are internal message, it won’t trigger transport agent.

You will find the full debug log in installation path\log\YYYYDDMM.inbound.txt:

Here is a sample of full debug log:

#Name: DkimInboundAgent, ManagedThreadId=3
#Version: xxx
#Date: 2017-09-11 10:46:45.659

LogLevel: FullDebug
Static Counter: 1
IsUseLastExternalIPAddress: False
trackingSender: *
trackingSourceIP: *

.....

Bypass check with AntispamBypass and AuthenticationSource.

IP check with trusted-IP addresses.

[Message Source] ...


Start to test message for Authentication-Results (SPF/DKIM/DMARC).
10:46:45.690 smtpMailFromOrHeloDomain support@emailarchitect.net
10:46:45.690 senderIPAddress 104.214.112.138
10:46:45.690 query SPF text for emailarchitect.net
10:46:45.737 result: v=spf1 ip4:104.214.112.138 a mx ~all
....

10:46:45.737 104.214.112.138 is in 104.214.112.138/32
10:46:45.847 SPF Result: pass

10:46:45.690 parse email content with 1095 bytes
10:46:45.722 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed;
s=s1024; d=emailarchitect.net;
h=message-id:from:to:subject:date:mime-version:content-type;
bh=8/5Y08pxf9kkHiNTMruAMt8ECrk=;
b=t2lEnuZvmkEpX5ulJMqtvN5O/fkfe4iw5vYPEtbWASgMU66Wp5roaJHONieQSX5F4UyKm95s
    kPc/lP2i8pvE85lSLqCsE+Zhcyi6zLIyWMQldbjXSuO5yjCaYfzHBPZGI8djIaVDWbTr/yMG
    W5X6rtNqu7g4COy5n2/0ELY7Q2o=

....

10:46:45.925 signature verified
10:46:45.925 DKIM Result: pass

10:46:45.925 SmtpMailFromOrHeloDomain support@emailarchitect.net
10:46:45.925 HeaderMailFrom support@emailarchitect.net
10:46:45.940 query dmarc text from _dmarc.emailarchitect.net
10:46:45.972 v=DMARC1; p=none
10:46:45.972 SPF Result: pass
10:46:45.972 DKIM Result: pass
10:46:45.972 evaluate alignment by v=DMARC1; p=none
10:46:45.972 SPF Alignment Result: pass
10:46:45.972 DKIM Alignment Result: pass
10:46:45.972 DMARC Result: pass

Detect if message should be rejected by SPF result.
Detect if message should be rejected by DKIM result.

Write Authentication-Results back to message stream:

Received-SPF: pass (localhost: domain of transitioning support@emailarchitect.net designates 104.214.112.138 as permitted sender) client-ip=104.214.112.138
Authentication-Results: exch2007.exch27.server;
    dkim=pass header.d=emailarchitect.net;
    spf=pass (localhost: domain of transitioning support@emailarchitect.net designates 104.214.112.138 as permitted sender) client-ip=104.214.112.138;
    dmarc=pass (adkim=r aspf=r p=none) header.from=emailarchitect.net;

Important

Because DKIM/SPF/DMARC agent doesn’t check the email from authenticated user in your organization, so you should send test email from outside domain to get the full process in the log.

Using Gmail, Hotmail account to do test is highly recommended, because those providers fully implemented SPF, DKIM and DMARC.

Filter Spam or Spoofing Email to Junk Folder based on DKIM/SPF Result

Now you can use the SPF or DKIM result to filter spam or spoofing email to junk folder. For example, if you want to filter emails with SPF fail or SPF softfail result to junk folder:

Create Transport Rule in Exchange 2007/2010

Edit Exchange Server Transport Rule.
  • Open Exchange Management Console -> Organization Configuration -> Hub Transport -> Transport Rule -> New Transport Rule;
  • Create a rule named “SPFRule”, select Condition to: when a message header contains specific words;
  • Set value in message header to Authentication-Results, and input “spf=fail” and “spf=softfail” two words in specific words.
  • Then set Actions to set the spam confidence leval value to, set value to 9.

After creating above rule, any emails from outside domain with SPF softfail and fail result will be filtered to junk folder in Exchange Server 2007/2010.

Create Transport Rule in Exchange 2013/2016

Edit Exchange Server 2013/2016 Transport Rule.
  • Open Exchange Admin Center (https://localhost/ecp) -> mail flow -> rules. Please change “localhost” to your server address if you access server remotely.
  • new rule -> Bypass spam filtering -> input “SPFRule” in rule name -> Apply this rule if A message header includes
  • Set header to Authentication-Results, and input “spf=fail” and “spf=softfail” two words in specific words.
  • In Do the following -> Modify the message properties -> Set spam confidence level (SCL) to.
  • Click Bypass spam filtering -> specify SCL -> Set value to 9 -> Click Save.

After creating above rule, any emails from outside domain with SPF softfail and fail result will be filtered to junk folder in Exchange Server 2013/2016.

Reject Spam or Spoofing Email based on DKIM/SPF Result in SMTP Service

Although you can use authenticate-results to filter email to junk folder, but it consumes server storage and resources. Moreover, if the email is filtered to junk folder, the sender doesn’t know the email is against your spam policy.

So the better way is rejecting email in SMTP service directly based on authenticate-results. If the email is rejected, the sender will receive non-delivery report from his SMTP server.

To reject the email against SPF policy, you can change spfResultToReject section. To reject the email against DKIM policy, you can change dkimResultToReject section.

Trusted IP Addresses

You can add IP addresses to Trusted IP Addresses section, Inbound DKIM/SPF agent won’t check the email from those IP addresses. It supports single IP address or CIDR syntax.

Here is an example:

<trustedIPAddresses>
    <add key="127.0.0.1" value="pass"/>
    <add key="192.168.0.0/24" value="pass"/>
</trustedIPAddresses>

Troubleshooting and Journal

After you finished the test, you should change logLevel back to OnlyError, otherwise the log file will be very large. If you only want to track the message from specific IP address or sender, you can change logLevel to FullDebug, and add specific IP address or sender email address in trackingSourceIP or trackingSender.

FullDebug log only enables for sender “support@emailarchitect.net”.

<appSettings>
    <add key ="LogLevel" value="FullDebug"/>
    <add key ="trackingSender" value="support@emailarchitect.net"/>
    <add key ="trackingSourceIP" value="*"/>
    <add key ="useLastExternalIPAddress" value="false"/>
</appSettings>

FullDebug log only enables for source IP “127.0.0.1”.

<appSettings>
    <add key ="LogLevel" value="FullDebug"/>
    <add key ="trackingSender" value="*"/>
    <add key ="trackingSourceIP" value="127.0.0.1"/>
    <add key ="useLastExternalIPAddress" value="false"/>
</appSettings>

FullDebug log enables for both of source IP “127.0.0.1” and “support@emailarchitect.net

<appSettings>
    <add key ="LogLevel" value="FullDebug"/>
    <add key ="trackingSender" value="support@emailarchitect.net"/>
    <add key ="trackingSourceIP" value="127.0.0.1"/>
    <add key ="useLastExternalIPAddress" value="false"/>
</appSettings>

Note

You will find the full debug log in installation path\log\YYYYDDMM.inbound.txt:

This configuration item is reserved for future use, do not change it.

<add key ="useLastExternalIPAddress" value="false"/>

DMARC Authentication

DMARC combines SPF and DKIM result, and it also specifies how to report the DKIM/SPF statistic report to domain owner.

Note

Because DKIM inbound agent doesn’t support to send report back to domain owner, so after DKIM is verified, only the DMARC result is written into Authentication-Results header.

Free Email Support

Not enough? Please contact our technical support team.

Support@EmailArchitect.NET

Remarks

We usually reply emails in 24hours. The reason for getting no response is likely that your smtp server bounced our reply. In this case, please try to use another email address to contact us. Your Gmail, Hotmail or Office 365 email account is recommended.