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/2019 by transport agent.
Sections:
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.
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.
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.
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:
To enable DKIM/SPF/DMARC verification in Exchange 2007/2010/2013/2016/2019, 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/2019 on multiple servers, you don’t have to install DKIM plugin on every server.
Note
Exchange 2019 on Server Core
If you need to install DKIM for Exchange 2019, Desktop Experience (GUI) for Windows 2019 is required.
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.
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
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.
You can disable this agent temporally in case you don’t want to use it anymore.
disable-transportagent "EA Dkim Inbound Agent"
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.
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="ignoredGatewayIPAddressesForSpfCheck" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="ignoredGatewayNameForSpfCheck" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="ignoreSpfResultDomains" 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="ignoreBodyHashErrorDomains" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="ignoreDkimResultDomains" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="dmarcResultToReject" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="ignoreDmarcResultDomains" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="blockedIPAddresses" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="blockedSenderOrHeloDomain" 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" />
<section name="trustedSenderOrDomain" 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>
<!--
ignoredGatewayIPAddressesForSpfCheck:
If your Exchange server is behind of a gateway/MTA,
the SPF check will be incorrect due to original IP address is hidden by gateway or MTA.
You can add your gateway/MTA IP address to skip the gateway IP/domain to detect original IP address/helo domain from message headers.
CIDR syntax is supported in IP address.
-->
<ignoredGatewayIPAddressesForSpfCheck>
<!--
<add key="192.168.0.8" value="ignore"/>
-->
</ignoredGatewayIPAddressesForSpfCheck>
<!--
ignoredGatewayNameForSpfCheck:
If your Exchange server is behind of a gateway/MTA,
the SPF check will be incorrect due to original IP address/helo domain is hidden by gateway or MTA.
You can add your gateway/MTA name to skip the gateway IP/domain to detect original IP address/helo domain from message headers.
You can use regular expression like this "/^emailarchitect\.(net|com)$/"
"/^emailarchitect\.(net|com)$/" matches "emailarchitect.net" and "emailarchitect.com"
"/.?emailarchitect\.net$/" matches "*.emailarchitect.net" and "emailarchitect.net"
-->
<ignoredGatewayNameForSpfCheck>
<!--
<add key="dispatch.gateway.net" value="ignore"/>
-->
</ignoredGatewayNameForSpfCheck>
<!--
ignoreSpfResultDomains does not take effect to the following domains even the result matches spfResultToReject
You can use regular expression like this "/^emailarchitect\.(net|com)$/"
"/^emailarchitect\.(net|com)$/" matches "emailarchitect.net" and "emailarchitect.com"
"/.?emailarchitect\.net$/" matches "*.emailarchitect.net" and "emailarchitect.net"
-->
<ignoreSpfResultDomains>
<!--
<add key="emailarchitect.net" value="ignore"/>
-->
</ignoreSpfResultDomains>
<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 DKIM verification (permerror)" />
-->
</dkimResultToReject>
<!--
ignoreBodyHashErrorDomains:
If the sender or signer domain is in the ignoreBodyHashErrorDomains list, body hash error with DKIM verification is ignored, only the signature is verified.
you can use regular expression like this "/^emailarchitect\.(net|com)$/"
"/^emailarchitect\.(net|com)$/" matches "emailarchitect.net" and "emailarchitect.com"
"/.?emailarchitect\.net$/" matches "*.emailarchitect.net" and "emailarchitect.net"
-->
<ignoreBodyHashErrorDomains>
<!--
<add key="/.?onmicrosoft.com$/" value="ignore"/>
-->
</ignoreBodyHashErrorDomains>
<!--
ignoreDkimResultDomains does not take effect to the following domains even the result matches dkimResultToReject
You can use regular expression like this "/^emailarchitect\.(net|com)$/"
"/^emailarchitect\.(net|com)$/" matches "emailarchitect.net" and "emailarchitect.com"
"/.?emailarchitect\.net$/" matches "*.emailarchitect.net" and "emailarchitect.net"
-->
<ignoreDkimResultDomains>
<!--
<add key="emailarchitect.net" value="ignore"/>
-->
</ignoreDkimResultDomains>
<dmarcResultToReject>
<!--
<add key="fail" value="550 5.7.1 your message from [%header_from%] is against our DMARC policy (fail)" />
<add key="none" value="550 5.7.1 your message from [%header_from%] is against our DMARC policy (none)" />
<add key="temperror" value="451 4.4.3 your message from [%header_from%] encountered a temporal error with DMARC verification (temperror)" />
<add key="permerror" value="550 5.7.1 your message from [%header_from%] encountered a permanent error with DMARC verification (permerror)" />
-->
</dmarcResultToReject>
<!--
ignoreDmarcResultDomains does not take effect to the following domains even the result matches dmarcResultToReject
you can use regular expression like this "/^emailarchitect\.(net|com)$/"
"/^emailarchitect\.(net|com)$/" matches "emailarchitect.net" and "emailarchitect.com"
"/.?emailarchitect\.net$/" matches "*.emailarchitect.net" and "emailarchitect.net"
-->
<ignoreDmarcResultDomains>
<!--
<add key="emailarchitect.net" value="ignore"/>
-->
</ignoreDmarcResultDomains>
<!--
blockedIPAddresses:
The email from the following IP address(es) will be rejected directly regardless of SPF/DKIM result.
CIDR syntax is supported in IP address.
-->
<blockedIPAddresses>
<!--
<add key="127.0.0.2" value="550 5.7.1 your message from [%source_ip%] is in our black list." />
<add key="192.168.0.0/24" value="550 5.7.1 your message from [%source_ip%] is in our black list." />
-->
</blockedIPAddresses>
<!--
blockedSenderOrHeloDomain
The email from (SMTP MAIL FROM or HELO DOMAIN) the following address(es)/domain(s) will be rejected directly regardless of SPF/DKIM result.
-->
<blockedSenderOrHeloDomain>
<!--
You can use regular expression like this: "/^(support|sales)@emailarchitect\.net$/"
"/^(support|sales)@emailarchitect\.net$/" matches "support@emailarchitect.net" and "sales@emailarchitect.net".
"/^[^@]+@emailarchitect\.net$/" matches "*@emailarchitect.net"
-->
<!--
<add key="faked-emailarchitect.net" value="550 5.7.1 your message from [%blocked_domainOrAddress%] is in our black list." />
<add key="spoof@faked-emailarchitect.net" value="550 5.7.1 your message from [%blocked_domainOrAddress%] is in our black list." />
-->
</blockedSenderOrHeloDomain>
<!--
trustedIPAddresses:
The email from the following IP address(es) will be accepted directly regardless of SPF/DKIM result.
CIDR syntax is supported in IP address.
-->
<trustedIPAddresses>
<add key="127.0.0.1" value="pass"/>
<add key="::1" value="pass"/>
<!--
<add key="192.168.0.0/24" value="pass"/>
-->
</trustedIPAddresses>
<!--
trustedSenderOrDomain:
The email from (rfc822.header.from) the following address(es)/domain(s) will be accepted directly regardless of SPF/DKIM result.
-->
<trustedSenderOrDomain>
<!--
You can use regular expression like this: "/^(support|sales)@emailarchitect\.net$/"
"/^(support|sales)@emailarchitect\.net$/" matches "support@emailarchitect.net" and "sales@emailarchitect.net".
"/^[^@]+@emailarchitect\.net$/" matches "*@emailarchitect.net"
-->
<!--
<add key="support@emailarchitect.net" value="pass"/>
<add key="emailarchitect.net" value="pass"/>
-->
</trustedSenderOrDomain>
<appSettings>
<add key ="logLevel" value="OnlyError"/>
<!-- <add key ="LogLevel" value="FullDebug"/> -->
<add key ="trackingSender" value="*"/>
<add key ="trackingSourceIP" value="*"/>
<add key ="useLastExternalIPAddress" value="false"/>
<!-- System default DNS server is used by default, you don't have to set this value manually
If you want to use specified DNS server address, you must input DNS server IP address.
For example, you can use 8.8.8.8 (Google Public DNS Server) as the DNS server address.
-->
<add key ="dnsServerAddress" value=""/>
</appSettings>
</configuration>
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.
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:
Organization Configuration
-> Hub Transport
-> Transport Rule
-> New Transport Rule
;Condition
to: when a message header contains specific words
;message header
to Authentication-Results
, and input “spf=fail” and “spf=softfail” two words in specific words
.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.
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
Authentication-Results
, and input “spf=fail” and “spf=softfail” two words in specific words
.Do the following
-> Modify the message properties
-> Set spam confidence level (SCL) to
.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/2019.
Here is the recommended settings for low level:
Apply rule to message:
when a "Authentication-Results" Contains "spf=softfail or spf=fail or dkim=fail"
set set the spam confidence leval value to 9
Here is the recommended settings for middle level, because SPF record is widely applied, this setting is recommended.
Apply rule to message:
when a "Authentication-Results" Contains "spf=softfail or spf=fail or spf=none or spf=neutral or spf=permerror or dkim=fail"
set set the spam confidence leval value to 9
Here is the recommended settings for highest level, because many SMTP servers don’t deploy DKIM signature, this setting is not recommended, it filters all emails without “spf=pass” and “dkim=pass” to junk folder.
Apply rule to message:
when a "Authentication-Results" Contains "spf=softfail or spf=fail or spf=none or spf=neutral or spf=permerror or dkim=fail or dkim=none or dkim=neutral or dkim=permerror"
set set the spam confidence leval value to 9
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.
spfResultToReject
section.dkimResultToReject
section.dmarcResultToReject
section.Here is the recommended settings for low level:
<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)" />
</spfResultToReject>
<dkimResultToReject>
<add key="fail" value="550 5.7.1 your message from [%header_from%] is against our DKIM policy (fail)" />
</dkimResultToReject>
<dmarcResultToReject>
<add key="fail" value="550 5.7.1 your message from [%header_from%] is against our DMARC policy (fail)" />
</dmarcResultToReject>
Here is the recommended settings for middle level, because SPF record is widely applied, this setting is recommended.
<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)" />
</dkimResultToReject>
<dmarcResultToReject>
<add key="fail" value="550 5.7.1 your message from [%header_from%] is against our DMARC policy (fail)" />
</dmarcResultToReject>
Here is the recommended settings for highest level, because there are many SMTP servers don’t deploy DKIM signature or DMARC record, this setting is not recommended, it rejects all emails without “spf=pass” and “dkim=pass” in SMTP service.
<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>
<dmarcResultToReject>
<add key="fail" value="550 5.7.1 your message from [%header_from%] is against our DMARC policy (fail)" />
<add key="none" value="550 5.7.1 your message from [%header_from%] is against our DMARC policy (none)" />
<add key="temperror" value="451 4.4.3 your message from [%header_from%] encountered a temporal error with DMARC verification (temperror)" />
<add key="permerror" value="550 5.7.1 your message from [%header_from%] encountered a permanent error with DMARC verification (permerror)" />
</dmarcResultToReject>
Important
You can change the response message (your message ….), but do not change the 5xx
, 4xx
response codes.
You can add IP addresses to trustedIPAddresses
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>
You can add sender addresses or domains to trustedSenderOrDomain
section, Inbound DKIM/SPF agent won’t check the email from those sender or domain.
Here is an example:
<trustedSenderOrDomain>
<!--
You can use regular expression like this: "/^(support|sales)@emailarchitect\.net$/"
"/^(support|sales)@emailarchitect\.net$/" matches "support@emailarchitect.net" and "sales@emailarchitect.net".
"/^[^@]+@emailarchitect\.net$/" matches "*@emailarchitect.net"
-->
<add key="support@emailarchitect.net" value="pass"/>
<add key="emailarchitect.net" value="pass"/>
</trustedSenderOrDomain>
You can add IP addresses to blockedIPAddresses
section, Inbound DKIM/SPF agent will reject the email from those addresses directly regardless of SPF/DKIM result.
It supports single IP address or CIDR syntax.
<blockedIPAddresses>
<add key="127.0.0.2" value="550 5.7.1 your message from [%source_ip%] is in our black list." />
</blockedIPAddresses>
You can add sender addresses or domains to blockedSenderOrHeloDomain
section, Inbound DKIM/SPF agent will reject
the email from those sender or domain, or helo-domain (if sender address is null, helo-domain is checked).
<blockedSenderOrHeloDomain>
<!--
You can use regular expression like this: "/^(support|sales)@emailarchitect\.net$/"
"/^(support|sales)@emailarchitect\.net$/" matches "support@emailarchitect.net" and "sales@emailarchitect.net".
"/^[^@]+@emailarchitect\.net$/" matches "*@emailarchitect.net"
-->
<add key="faked-emailarchitect.net" value="550 5.7.1 your message from [%blocked_domainOrAddress%] is in our black list." />
<add key="spoof@faked-emailarchitect.net" value="550 5.7.1 your message from [%blocked_domainOrAddress%] is in our black list." />
</blockedSenderOrHeloDomain>
By default, inbound SPF check uses current remote connection IP address.
But if your current Exchange Server is behind of an edge server, Edge server IP address
will override real remote IP address, so SPF check won’t return correct result. In this case, you should change
useLastExternalIPAddress
to true.
<add key ="useLastExternalIPAddress" value="true"/>
If hasGateway
is false, spf check uses current remote IP address to check spf policy;
If hasGateway
is true, spf check uses all possible IP addresses in email headers to check spf policy.
If your server is behind of a gateway/firewall, please set this value to true.
<add key="hasGateway" value="true"/>
Important
ignoredGatewayIPAddressesForSpfCheck
and ignoredGatewayNameForSpfCheck
were obsoleted by hasGateway
.
By default, all emails from AuthenticationSource: Organization or Partner will not be checked. But if you want to check emails from those servers, please add those server IP addresses to the following list like this:
<excludedOrganizationIPAddresses>
<add key="192.168.0.16" value="check"/>
<add key="192.168.0.0/24" value="check"/>
</excludedOrganizationIPAddresses>
Important
This item is obsolete, Instead, use hasGateway
in SPF Check Behind a Gateway/Firewall section.
If your Exchange Server is protected by anti-spam/anti-virus gateway, the gateway IP address also overrides real remote server IP address, that also caused SPF check returns incorrect result.
For example, if remote sender server IP address is 192.168.0.12, but your server MX record is set to
an anti-spam gateway (IP 192.168.0.2), anti-spam gateway forwards the email to Exchange Server, by default, inbound SPF check uses current connection IP
(anti-spam gateway [192.168.0.2]) to verify sender SPF policy, that is incorrect, SPF check should use sender server address (192.168.0.12)
to verify SPF policy. To get the correct result, we should add 192.168.0.2 (gateway IP address) to ignoredGatewayIPAddressesForSpfCheck
like this:
<!--
single IP or CIDR syntax is supported in IP address.
-->
<ignoredGatewayIPAddressesForSpfCheck>
<add key="192.168.0.2" value="ignore"/>
</ignoredGatewayIPAddressesForSpfCheck>
If you set ignoredGatewayIPAddressesForSpfCheck
items, inbound SPF agent will parse IP addresses from message Received headers
, by default
Exchange SMTP service also adds a header with local server name and IP address, you should also add your local IP address to ignoredGatewayIPAddressesForSpfCheck
.
I suggest that you enable Full Debug
log level, and you will see how SPF guess the real remote IP address in log file, then you can add local/gateway IP addresses
to ignoredGatewayIPAddressesForSpfCheck
.
For example, if the headers in full debug log is like this:
Received: from my-exchange-server ([192.168.0.16]) by my-exchange-server ([192.168.0.16])
Received: from gateway1 ([192.168.0.2]) by my-exchange-server ([192.168.0.16]) ...
Received: from real-sender-server ([192.168.0.13]) by gateway1 ([192.168.0.2]) ...
To get correct result of SPF check, you can change ignoredGatewayIPAddressesForSpfCheck
like this:
<ignoredGatewayIPAddressesForSpfCheck>
<add key="192.168.0.16" value="ignore"/>
<add key="192.168.0.2" value="ignore"/>
</ignoredGatewayIPAddressesForSpfCheck>
With above options, inbound SPF agent will parse real sender IP address to 192.168.0.13.
Important
This item is obsolete, Instead, use hasGateway
in SPF Check Behind a Gateway/Firewall section.
If your gateway uses variable IP addresses, you can use gateway name to skip gateway IP addresses.
For example, if the headers in full debug log is like this:
Received: from my-exchange-server ([192.168.0.16]) by my-exchange-server ([192.168.0.16])
Received: from gateway1 ([192.168.0.2]) by my-exchange-server ([192.168.0.16]) ...
Received: from real-sender-server ([192.168.0.13]) by gateway1 ([192.168.0.2]) ...
To get correct result of SPF check, you can change ignoredGatewayNameForSpfCheck
like this:
<ignoredGatewayNameForSpfCheck>
<add key="my-exchange-server" value="ignore"/>
<add key="gateway1" value="ignore"/>
</ignoredGatewayNameForSpfCheck>
With gateway name options, no matter IP addresses used by gateway, inbound SPF agent can always parse real sender IP address to 192.168.0.13.
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
:
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.
Not enough? Please contact our technical support team.
Remarks
We usually reply emails within 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.