Spam messages have become a huge issue. They are both annoying, flooding our mailboxes with unneeded content and they are a security risk too, as many of them contain links to malicious websites or even viruses. To fight spamming SPF, DKIM and DMARC emerged. The basic idea behind them is to check the probability of a message being spam, then our mail server can decide what to do with the message: likely putting it in the "Spam" or "Junk" folder, or simply fropping the email altogether.
To measure the spam confidence level of incoming emails, the servers do the following simple checks:
Let's dive deeper in these three!
SPF
There is one thing we need to clarify at the very beginning: anyone can send messages from any email addresses. With no sugar coating, that is a fact. You can set up a basic mail server and send me an email from POTUS@whitehouse.gov, or Bill.Gates@microsoft.com that will appear in my inbox as the actual sender. This is how scammers might use your email address to email your clients with fake data.
But there is good news also because these messages will likely land in the spam folder, or they might not even be delivered to the end user thanks to SPF.
How it works
SPF stands for Sender Policy Framework. It is basically a public DNS record that contains all the webservers that should be sending out messages from the domain in question.
For instance, Always Hot Café has the following public TXT record added in DNS
The structure of the record is very simple: v=spf1 says the clients that this record contains the SPF records for the domain. The consecutive part contains the servers that should be able to send emails form *@alwayshotcafe.com addresses. There we have many options to state the servers, also there can be multiple entries separated by spaces.
ip4 | the ipv4 addresses or address ranges of accepted servers |
ip6 | ipv6 addresses of mail-enabled servers |
include | Including the servers specified in another domain's SPF records [v=spf1 include:outlook.microsoft.com -all] |
mx | all A record the specified MX records refer to |
a | the A record of the mail server. Less preferred as this case another DNS lookup is needed by the client so it is slower, when it is possible, ipv4 or 6 addresses should be used |
+ | Pass |
- | Fail |
~ | SoftFail, host receives the message but it is marked as spam |
? | Neutral, neither pass, no fail |
1. Messages are allowed originating from 80.12.33.132 public IP. Messages from any other addresses will fail
v=spf1 ip4:80.12.33.132/32 -all
2. Messages are allowed from 10.5.22.1 and from all servers that the outlook.office.com SPF records specify. All other sources will fail
v=spf1 ip4:10.5.22.1 include:outlook.office.com -all
3. Messages form the actual domain's MX records will pass, also messages from 1.1.1.1 IP will fail, all other messages are marked as neutral
v=spf1 mx -ip4:1.1.1.1 ?all
4. All the A records from our domain pass, also messages from mail.partner.com is allowed, all other will soft fail. Say our domain is alwayshotcafe.com, then mail.alwayshotcafe.com, and www.alwayshotcafe.com or any other records we have will be able to send emails.
v=spf1 a a:mail.partner.com ~all
5. If no operator is specified (+, -, ~ or ?), then + is assumed.
v=spf1 a mx ip4:2.2.2.2 -all == v=spf1 +a +mx +ip4:2.2.2.2 -all
DKIM
It stands for DomainKeys Identified Mail. It is used to prove that the message is authentic. That means it is truly from the organization that is claims to be originated from. Also proves that the message was not tampered with in transit.
For a detailed Exchange 2019 DKIM deployment guide please click HERE!
We go through an example email to see how it happens: John Doe sends an email from his John.Doe@alwayshotcafe.com email address. Our email server checks the header of the message and finds the DKIM-Signature section, that tells the server a lot of things:
Header
...
Received-SPF: Pass (protection.outlook.com: domain of alwayshotcafe.com
designates 31.132.34.130 as permitted sender)
receiver=protection.outlook.com; client-ip=31.132.34.130;
helo=MAIL.AlwaysHotCafe.com;
Received: from MAIL.AlwaysHotCafe.com (31.132.34.130) by
LO2GBR01FT003.mail.protection.outlook.com (10.152.42.89) with Microsoft SMTP
Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
15.20.2921.25 via Frontend Transport; Sat, 18 Apr 2020 09:48:28 +0000
Content-Language: en-US
DKIM-Signature: v=1; a=rsa-sha256; d=alwayshotcafe.com; s=selector1;
c=relaxed/relaxed; t=1587203307; h=from:subject:to:date:message-id;
bh=3ECfkrEiARfvXNGT95TLaUGgi50dOXnbyEyBN92OL7I=;
b=ezzdjkLHWh038rZ2rzGtOK8iDkICzeabakYi7WMNFb362wrSZ9BakHhjjca5a/+oqKbwGO9fA59
nshOeqvy6AzwuT7B3gPJPJ6kAaTXu6T8L5GYjeJaWm5T5Gk9/gxaDJxMqtM9JCt+w6wUN6xfjjRgW
fRQrkM4GJ5WUs+tPJ+KGWn9nyIU01VeFPwnPx7xlXCfKrTjmRhaAu0hyPNviO/MdvEqCMUZA+3tVk
1YAZ6xwL4c6SLx8N1zK88O/0Uk6gnQItG4UcYsxJ2+/Z0Jk0MMnNDpvvJGkpo34HAkuWXg74m70oY
zcI+mTn/lM2yPJzu6fJ+/HBZ/rnfDins6nOw==
Received: from MAIL.AlwaysHotCafe.com (10.0.1.2) by MAIL.AlwaysHotCafe.com
(10.0.1.2) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.397.3; Sat, 18 Apr 2020
10:48:23 +0100
...
a=hashing algorithm that was used by John's server to hast the original message.
b and bh: the hashes of the body and header of the original message, encrypted with the private key of the originating email server.
s: the selector tells our mail server where to find the public key to decrypt the encypted hashes stored in b and bh. Here it is selector1, as the domain is alwayshotcafe.com, our mail server knows to check the selector1._domainkey.alwayshotcafe.com DNS record to retrieve the public key, that is:
$ nslookup -q=txt selector1._domainkey.alwayshotcafe.com
Server: 10.255.255.254
Address: 10.255.255.254#53
Non-authoritative answer:
selector1._domainkey.alwayshotcafe.com text = "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhrpIyJKHENA97MGhuGG1rtxelIj51h361yidGpsm8nVjJVwxmNHEJuj5Ekw/CEqowQMO2H6V2XeMaw8mgF+iaGaXsAxBR0wQhsMMWMQ62VF5D/nz3pCoqE69hLcbvHAPRoeSljthlxWHl1JMop4rQqdtqK5US+kXWr/vTPgpRNio0doo+SumkPa9I66JHenIP" "y4oA94GEOs65vQQPOAxxUnfJws8uq7F6tEdwo28Cf/D5ECR3SuTFlv4yDvVMenLzdsz2tCVWY+Un9zWvDC4F9R7qtx/jl7PhHcUNaTDIiWZPWWErx53n6UuWXAKavU9XIBC9eG9hWaCSkgcezUrrwIDAQAB"
After decrypting the b and bh values, we have the original hashes the sender generated. Our server calculates the hashes by itself as well and compares those hash values with the originals. If there was a single character difference the hashes would not match.
This check confirms two things: first, if the calculated and decrypted hashes match, that means the message was not changed, it was not tampered with in between sending and receiving. This proves authenticity as if someone intercepted our message, then re-hashed it, they could not have encrypted it again without the private key that only the original sender has.
So, if the calculated and decrypted hashes match, DKIM passes.
DMARC
Domain-based Message Authentication, Reporting, and Conformance, the third pillar of email security. It is also a DNS record, that has one purpose: telling us what should happen if either SPF or DKIM or both fail.
Back to our example the record is the following _dmarc.alwayshotcafe.com TXT record:
It has a few very simple parts:
v | protocol version | v=DMARC |
pct | percentage of messages to be filtered | pct=100 |
ruf | address to send the forensic report to | ruf=mailto:zsolt@opentechtips.com |
rua | address to the the aggregate reports to | |
p | policy (none, reject, quarantine) | p=none |
adkim | mode for DKIM (strict, relaxed) | adkim=s |
aspf | mode for SPF (strict, relaxed) | aspg=r |
Strict means: the sender domain name must match exactly with the DKIM or SPF specified.
Relaxed: subdomains are also accepted
Examples:
1. 100% of the messages should be filtered, subdomains are allowed for both DKIM and SPF. Also if the check fails, there is no action taken
TXT record: _dmarc.[domain.com]
value: "v=DMARC1; p=none; adkim=r; aspf=r; pct=100"
Hope it was informative.
Comments