This document describes how Email Security.cloud handles SPF, DKIM and DMARC, coupled with the respective override options within the portal, which can alter an active result into a different outcome.
Breakdown of SPF, DKIM and DMARC:
SPF (Sender Policy Framework)
What it is: SPF is an email authentication protocol that allows the owner of a domain to specify which mail servers they use to send mail from that domain.
How it works: Sender publish SPF records in the Domain Name System (DNS). These records list which IP addresses are authorized to send email on behalf of their domains.
During an SPF check, email providers verify the SPF record by looking up the domain name listed in the “envelope from” address in the DNS. If the IP address sending email on behalf of the “envelope from” domain isn’t listed in that SPF record, the message fails SPF authentication.
Note: Absence of SPF record will result in SPF related actions as defined in the ESS service to not be followed through, since these only apply against an active record with a fail action "-all" flag. For the means of alignment as it relates to DMARC, absence of SPF will result in SPF alignment to be treated as fail.
DKIM (DomainKeys Identified Mail)
What it is: DomainKeys Identified Mail (DKIM) is a protocol that allows an organization to take responsibility for transmitting a message in a way that can be verified by mailbox providers. This verification is made possible through cryptographic authentication.
How it works: DKIM is quite complicated.
Note: Absence of DKIM record as it relates to DMARC for the means of record alignment, will result in DKIM alignment to be treated as a fail.
Step 1: Identifying what message elements to sign with DKIM
First, a sender decides which elements of the email they want to include in the signing process. They can decide to include the whole message (header and body) or just focus on one or more fields of the email header. The elements they decide to include in their DKIM signing process must remain unchanged in transit, or the DKIM signature will fail authentication.
The elements included in the DKIM signing process must remain unchanged in transit.
For example, if an email is forwarded from Yahoo to Gmail, Yahoo may add a line of text at the top of the email (e.g. “forwarded by Yahoo mail”). At that point, the body of the email has been changed and, if the body was included in the DKIM signing process, the DKIM authentication will fail for the forwarded email.
However, if only an element of the header, such as the “from” field was included in the DKIM signature, and the message was forwarded from Yahoo to Gmail, the DKIM authentication would pass, since the part of the message that was changed was not signed by DKIM.
Step 2: The encryption process
So what does this signing process look like? Cryptography is at the center of it. The sender will configure their email platform to automatically create a hash of the parts of the email they want signed. The hashing process converts readable text into a unique textual string. Here’s what that looks like (using the MD5 hashing process):
From: John Doe <[email protected]>
Subject: Demo Email
Maps to the following unique hash string: 233970af6624f7287720282fbabf92b6
Before sending the email, that hash string is encrypted using a private key. The private key is assigned to a unique combination of domain and selector, allowing you to have multiple legitimate private keys for the same domain (which is important for email governance and security purposes). Only the sender has access to the private key. That results in a header being added to the email, example below.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=demokey; t=0000000000;
[email protected];
bh=XYZABC123456abcXYZABC123456abcXYZABC123456abc=;
h=From:Subject;
b=AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP
QQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ000011112222333344445555
6666777788889999aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllll
mmmmnnnn0000oooo1111pppp2222qqqq3333rrrr4444ssss5555tttt6666uuuu
vvvv7777wwww8888xxxx9999yyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH;
After the encryption process is complete, the email is sent.
Legend:
Step 3: Validating the DKIM signature with a public key
The MTA receiving the email sees that it has a DKIM signature, which reveals which “domain/selector” combination signed the encryption process. To validate the signature, the MTA will run a DNS query to find the public key for that domain/selector combination.
This public key has the unique characteristic that it is the only match for the private key that signed the email, also known as a “keypair match.” The keypair match enables the MTA to decrypt the DKIM signature back to the original hash string.
MTA then takes the elements of the email signed by DKIM and generates its own hash of these elements. Finally, the MTA compares the hash it generated with the decrypted hash from the DKIM signature. If they match, we know that
DMARC (Domain-based Message Authentication, Reporting & Conformance)
What it is: DMARC ensures that legitimate email is properly authenticating against established DKIM and SPF standards, and that fraudulent activity appearing to come from domains under the organization’s control is blocked. Two key values of DMARC are domain alignment and reporting.
How it works: DMARC’s alignment feature prevents spoofing of the “body from” address by:
To pass DMARC, a message must pass SPF authentication and pass SPF alignment and/or pass DKIM authentication and pass DKIM alignment. A message will fail DMARC if the message fails both (1) SPF or SPF alignment and (2) DKIM or DKIM alignment.
SPF and DKIM alignment results - 4 combinations |
||||||
SPF |
SPF |
Result |
DKIM |
DKIM |
Result |
|
Pass |
Fail |
Fail |
Pass |
Fail |
Fail |
|
Pass |
Pass |
Pass |
Pass |
Pass |
Pass |
|
Fail |
Pass |
Fail |
Fail |
Pass |
Fail |
|
Fail |
Fail |
Fail |
Fail |
Fail |
Fail |
Once we have either a Pass or Fail from SPF and DKIM records, we will then sum the results. DMARC just needs one Pass to issue a Pass.
DMARC results: |
|
SPF Fail + DKIM Pass |
Pass |
SPF Pass + DKIM Pass |
Pass |
SPF Pass + DKIM Fail |
Pass |
SPF Fail + DKIM Fail |
Fail |
Scenarios and examples
Exceptions
Test Cases
Authentication Results Headers SPF
Scenarios |
Fail Reasons |
Auth Result headers |
DNS Entry |
SPF Hard Fail |
IP does not match |
Authentication-Results: mx.messagelabs.com; spf=hardfail |
v=spf1 ip4:1.1.1.37 -all |
SPF Soft Fail |
Not a designated sender |
Authentication-Results: mx.messagelabs.com; spf=softfail |
v=spf1 ip4:1.1.1.30 ~all |
SPF Neutral |
Not a designated sender |
Authentication-Results: mx.messagelabs.com; spf=neutral |
v=spf1 ip4:1.1.1.30 ?all |
SPF record not found |
No SPF records available |
Authentication-Results: mx.messagelabs.com; spf=none (spf record not |
v=DKIM1; k=rsa; p=XXXXXXXXXXXXXX |
SPF Pass |
Authentication-Results: mx.messagelabs.com; spf=pass |
v=spf1 ip4:1.1.1.30 -all |
Authentication Results Headers DKIM
Scenarios |
Fail Reasons |
Auth Result headers |
DNS Entry |
With only DKIM record Pass Scenario |
Authentication-Results: mx.messagelabs.com; spf=hardfail |
"v=DKIM1; k=rsa; p=XXXXXXXXXXXXXX" |
|
With only DKIM record Fail Scenario |
DNS Wrong syntax entry |
Authentication-Results: mx.messagelabs.com; spf=none (spf record not |
_int.domainkey.example.org |
With only DKIM record Fail Scenario |
Corrupted Public key in DNS |
Authentication-Results: mx.messagelabs.com; spf=hardfail |
v=DKIM1; k=rsa; p=XXXXXXXXXXXXXX |
With only DKIM and DMARC |
Authentication-Results: mx.messagelabs.com; spf=none (spf record not |
v=DMARC1; p=reject |
|
With only DKIM record |
Wrong Public key |
Authentication-Results: mx.messagelabs.com; spf=none (spf record not |
v=DKIM1; k=rsa; p=XXXXXXXXXXXXXX |
With only DKIM record |
Modified email From header after encryption |
Authentication-Results: mx.messagelabs.com; spf=hardfail |
v=DKIM1; k=rsa; p=XXXXXXXXXXXXXX |
No Public key in DNS |
Public key not available in DNS |
Authentication-Results: mx.messagelabs.com; spf=hardfail |
v=spf1 ip4:1.1.1.30 -all |
Authentication Results Headers MIXED
Scenarios |
Fail Reasons |
Auth Result headers |
DNS Entry |
With DKIM, SPF and DMARC with subdomain configured Fail Scenario. Email Sent for Parent Domain |
SPF failure |
Authentication-Results: mx.messagelabs.com; spf=hardfail |
v=spf1 ip4:1.1.1.30 -all |
With SPF and DMARC with subdomain configured Fail Scenario. Email Sent for sub Domain |
Authentication-Results: mx.messagelabs.com; spf=none (spf record not |
v=spf1 ip4:1.1.1.30 -all |
|
Alignment failure |
DMARC spf and dkim alignment failure |
Authentication-Results: mx.messagelabs.com; spf=pass |
v=spf1 ip4:1.1.1.23 -all |
DMARC Pass Scenario |
Authentication-Results: mx.messagelabs.com; spf=pass |
v=spf1 ip4:1.1.1.30 -all |
SPF + DMARC + Clientnet Override Outcome Actions
# |
Sender SPF(-all) |
Sender DMARC |
CNet Option SPF/DMARC |
CNet Action |
SPF/DMARC AuthResult = Failed |
Expected |
Comment/ |
1 |
True |
True |
True / True |
Block / Quarantine |
Fail / Fail |
Clientnet DMARC Action |
Quarantine |
2 |
True |
False (p=None) |
True / True |
Block / Quarantine |
Fail / Fail |
Clientnet SPF Action |
Blocked |
3 |
True |
True |
True / False |
Redirect / Off |
Fail / Fail |
Clientnet SPF Action |
Redirected |
4 |
True |
False (p=None) |
True / False |
Quarantine / Off |
Fail / Fail |
Clientnet SPF Action |
Quarantine |
5 |
True |
True |
False / True |
Off / Block |
Fail / Fail |
Clientnet DMARC Action |
Blocked |
6 |
True |
False (p=None) |
False / True |
Off / Tag subject |
Fail / Fail |
Sender DMARC Policy |
SPF Logged |
7 |
False |
True |
True / True |
Redirect / Append |
Fail (Softfail) / Fail |
Clientnet DMARC Action |
Append |
8 |
False |
False (p=None) |
True / True |
Quarantine / Block |
Fail (Softfail) / Fail |
Sender DMARC Policy |
Pass Thru - SPF Result Softfail |
9 |
False |
True |
False / True |
Off / Sender's policy |
Fail (Softfail) / Fail |
Clientnet DMARC Action |
Quarantine as Set In DNS |
10 |
False |
False (p=None) |
False / True |
Off / Sender's policy |
Fail (Softfail) / Fail |
Sender DMARC Policy |
Pass Thru - SPF Result Softfail |
11 |
False |
True |
True / False |
Append / Off |
Fail (Softfail) / Fail |
Sender DMARC Policy |
DMARC Logged |
12 |
False |
False (p=None) |
True / False |
Append / Off |
Fail (Softfail) / Fail |
Email Pass Thru |
Pass Thru - SPF Result Softfail |
13 |
True |
True |
True / True |
Block / Append |
Fail / Fail |
Clientnet DMARC Action |
Append |
14 |
True |
False (p=None) |
False / False |
Off / Off |
Fail / Fail |
Sender DMARC Policy |
SPF Logged |
15 |
True |
True |
False / False |
Off / Off |
Fail / Fail |
Sender DMARC Policy |
DMARC Logged |
16 |
True |
True |
True / True |
Block / Append |
Pass / Fail |
Email Pass Thru |
DMARC, SPF, DKIM - Pass |
17 |
True |
True |
True / False |
Append / Off |
Pass / Fail |
Email Pass Thru |
SPF, DMARC - Pass, DKIM - Fail |
18 |
True |
True |
True / True |
Block / Sender's policy |
Pass / Fail |
Email Pass Thru |
DKIM, DMARC - Pass, SPF - Fail |
19 |
True |
False (p=None) |
False / False |
Off / Off |
Pass / Fail |
Email Pass Thru |
Pass Thru |
20 |
True |
True |
False / False |
Off / Off |
Pass / Fail |
Sender DMARC Policy |
DMARC Logged |
21 |
True |
True |
True / True |
Block / Append |
Pass / Fail |
Clientnet DMARC Action |
Append |
22 |
True |
True |
True / False |
Append / Off |
Pass / Fail |
Sender DMARC Policy |
DMARC Logged |
23 |
True |
True |
True / True |
Block / Sender's policy |
Pass / Fail |
Sender DMARC Policy |
DMARC Blocked |
24 |
True |
False (p=None) |
False / False |
Off / Off |
Fail / Pass |
Email Pass Thru |
Pass Thru - DMARC Check Pass, P=None Check Not Performed. |
25 |
True |
True |
False / False |
Off / Off |
Fail / Pass |
Email Pass Thru |
Pass Thru |
26 |
True |
True |
True / True |
Block / Append |
Fail / Pass |
Email Pass Thru |
Pass Thru |
27 |
True |
True |
True / False |
Append / Off |
Fail / Pass |
Clientnet SPF Action |
Append |
28 |
True |
True |
True / True |
Block / Sender's policy |
Fail / Pass |
Email Pass Thru |
Pass Thru |
29 |
True |
True |
False / True |
Off / Sender's policy |
Fail (Softfail) / Fail |
Clientnet DMARC Action |
If account lacks Quarantine, email gets its subject tagged instead. Pass Thru |
Looking at fictitious domain example.org and its example records
Part 1:
Public Records
SPF v=spf1 ip4:195.232.248.108/30 ip4:178.249.98.16/29 include:spf.messagelabs.com ip4:203.109.136.0/24 ip4:65.254.253.0/24 ip4:195.232.248.240/28 ip4:195.232.245.160/28 ~all
DMARC v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; sp=none; fo=1
DKIM No DKIM found
Let’s assume
Authentication Results:
Authentication-Results-Original: mx.messagelabs.com; spf=fail
(server-11.tower-238.messagelabs.com: domain of example.org does not designates
100.158.142.193 as permitted sender) smtp.mailfrom=example.org; dkim=none
(message not signed); dmarc=fail (p=none sp=none) header.from=example.org
ClientNet options are set to default.
SPF set to “Block and delete de mail”
DMARC set to “User sender’s DMARC policy”
With an email arriving to example.org pretending to be example.org today as is, although we may be faced with both SPF and DMARC fail, the email will continue its path to the user’s mailbox, since both records state that no action is to be taken against the email.
Part 2:
Taking it to the next step, let’s now assume SPF and DMARC are enforced, SPF as -all and DMARC set to p=quarantine and sp=none.
Public Records
SPF v=spf1 ip4:195.232.248.108/30 ip4:178.249.98.16/29 include:spf.messagelabs.com ip4:203.109.136.0/24 ip4:65.254.253.0/24 ip4:195.232.248.240/28 ip4:195.232.245.160/28 -all
DMARC v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; sp=none; fo=1
DKIM No DKIM found
In this scenario, a spoofed email pretending to example.org at the body from level (DMARC only) fails DMARC, will see itself being quarantined as per the action in the record. Here I assume the envelope (SPF) as being some other domain from the spammer which passes SPF.
Because Email Quarantine is enabled for Somedomain’s Inc account in Email.cloud, actions that require it use will be permitted to take effect, like the case of DMARC records that state p=quarantine as their action. If quarantine wasn’t activate, and an email failed DMARC with p=quarantine, the email would be tagged instead.
In this spoofed email, we’ll have DMARC alignment fail at the DKIM level (absent record), where the email even if signed will not match Somedomain’s DKIM signature. And also, an alignment fail at the SPF level, the SPF authentication may have passed, but the domain alignment didn’t leading to the fail result.
Summary:
SPF and DKIM alignment results |
DMARC results (Result SPF + Result DKIM) |
|||||||||
SPF Auth |
SPF Align |
DKIM Auth |
DKIM Align |
Result SPF |
Result DKIM |
|||||
Pass |
Fail |
> |
Pass |
Fail |
> |
Fail |
Fail |
SPF Fail + DKIM Pass |
Pass |
|
Pass |
Pass |
Pass |
Pass |
Pass |
Pass |
SPF Pass + DKIM Pass |
Pass |
|||
Fail |
Pass |
Fail |
Pass |
Fail |
Fail |
SPF Pass + DKIM Fail |
Pass |
|||
Fail |
Fail |
Fail |
Fail |
Fail |
Fail |
> |
SPF Fail + DKIM Fail |
Fail |
A summary result of SPF – PASS, or DKIM – PASS, only happens if both sub-checks within the respective validations passed.
Part 3:
We’ll now change DMARC to reject and have Clientnet intervene with Quarantine at the DMARC setting level. SPF as -all and DMARC set to p=reject and sp=none.
Public Records
SPF v=spf1 ip4:195.232.248.108/30 ip4:178.249.98.16/29 include:spf.messagelabs.com ip4:203.109.136.0/24 ip4:65.254.253.0/24 ip4:195.232.248.240/28 ip4:195.232.245.160/28 -all
DMARC v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; sp=none; fo=1
DKIM No DKIM found
ClientNet options are set to default.
SPF set to “Block and delete de mail”
DMARC set to “Quarantine the mail”
We would get to the same base verdict as shown in the previous example, but we now have the actions in Clientnet also playing a role in the outcome.
Jumping directly to summary:
SPF and DKIM alignment results |
DMARC results (Result SPF + Result DKIM) |
|||||||||
SPF Auth |
SPF Align |
DKIM Auth |
DKIM Align |
Result SPF |
Result DKIM |
|||||
Pass |
Fail |
> |
Pass |
Fail |
> |
Fail |
Fail |
SPF Fail + DKIM Pass |
Pass |
|
Pass |
Pass |
Pass |
Pass |
Pass |
Pass |
SPF Pass + DKIM Pass |
Pass |
|||
Fail |
Pass |
Fail |
Pass |
Fail |
Fail |
SPF Pass + DKIM Fail |
Pass |
|||
Fail |
Fail |
Fail |
Fail |
Fail |
Fail |
> |
SPF Fail + DKIM Fail |
Fail |
We have a SPF set to softfail and a DMARC with reject. SPF passed the authentication, that is, normal SPF check passed. But the final verdict of DMARC was a fail. This time around instead of deleting the email as per p=reject, the email will be quarantined instead. Due to p=reject being an active action, it can be overwritten by Clientnet setting, here we see the reject being overwritten by quarantine.