{"id":53,"date":"2025-02-16T17:40:00","date_gmt":"2025-02-16T14:40:00","guid":{"rendered":"https:\/\/fsaeed.blog\/?p=53"},"modified":"2026-10-31T00:18:52","modified_gmt":"2026-10-30T21:18:52","slug":"spf-dkim-dmarc-explained","status":"publish","type":"post","link":"https:\/\/fsaeed.blog\/index.php\/2025\/02\/16\/spf-dkim-dmarc-explained\/","title":{"rendered":"SPF, DKIM and DMARC Explained (and Why Your Emails Land in Spam)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hello, tech enthusiasts! \ud83d\udc4b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You send an invoice to a customer. They never see it. A week later, they find it in their spam folder. Sound familiar?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Often the problem is not your message. The problem is that the receiving server cannot check that the email really came from you. Anyone can write any &#8220;From&#8221; address on an email, a bit like writing any return address on an envelope. So mail servers look for proof.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That proof comes from three DNS records: <strong>SPF<\/strong>, <strong>DKIM<\/strong> and <strong>DMARC<\/strong>. Let us make them simple.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What you need<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your own domain, for example example.com<\/li>\n\n\n<li>Access to your domain&#8217;s <strong>DNS<\/strong> settings (DNS is the internet&#8217;s phone book: it turns names into addresses)<\/li>\n\n\n<li>The setup values from your email provider<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Understand the three records<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Think of sending a letter from your company.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SPF<\/strong> is the list of post offices allowed to send your letters. The receiver checks: &#8220;Did this email come from an allowed server?&#8221;<\/li>\n\n\n<li><strong>DKIM<\/strong> is a wax seal on the letter. Your server signs each email with a secret key. The receiver checks the seal with a public key in your DNS. If the email was changed on the way, the seal breaks.<\/li>\n\n\n<li><strong>DMARC<\/strong> is your instruction to the receiver: &#8220;If a letter fails these checks, here is what to do with it. And please send me a report.&#8221;<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">All three are <strong>TXT records<\/strong>, which are simple text notes stored in your DNS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Add an SPF record<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Add a TXT record on your main domain (<code>@<\/code> or <code>example.com<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>v=spf1 ip4:192.0.2.10 include:_spf.mailprovider.example -all<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What it means:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>v=spf1<\/code> says &#8220;this is an SPF record&#8221;.<\/li>\n\n\n<li><code>ip4:192.0.2.10<\/code> allows your own mail server.<\/li>\n\n\n<li><code>include:...<\/code> allows your email provider&#8217;s servers. Your provider tells you the exact value.<\/li>\n\n\n<li><code>-all<\/code> says &#8220;nobody else&#8221;. Use <code>~all<\/code> (a softer &#8220;probably not&#8221;) while you test.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Important: a domain must have <strong>only one<\/strong> SPF record. If you use two services, put both <code>include:<\/code> parts in the same record.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Add a DKIM record<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Your email provider creates the key pair for you. You only copy the public key into DNS. It goes on a special name with a <strong>selector<\/strong>, which is just a label for the key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Name:  selector1._domainkey.example.com\nValue: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>p=<\/code> part is very long. Copy it exactly, with no extra spaces. Then turn on DKIM signing in your email provider&#8217;s settings.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Add a DMARC record, starting gently<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Add a TXT record on <code>_dmarc.example.com<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>p=none<\/code> means &#8220;do not block anything yet, just report&#8221;.<\/li>\n\n\n<li><code>rua=<\/code> is where receivers send daily summary reports.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Why start with <code>none<\/code>? Maybe you forgot a service that sends email for you, like a newsletter tool or your accounting software. With <code>none<\/code>, nothing breaks. The reports show you every server sending as your domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DMARC also checks <strong>alignment<\/strong>. This means the domain in the &#8220;From&#8221; address must match the domain checked by SPF or DKIM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Check your records<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After you save the records, wait a little. DNS changes can take from a few minutes to some hours to spread.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On Mac or Linux, use <code>dig<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short TXT example.com\ndig +short TXT selector1._domainkey.example.com\ndig +short TXT _dmarc.example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Windows, use <code>nslookup<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nslookup -type=TXT _dmarc.example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can also use any free online SPF\/DKIM\/DMARC checker. Just type your domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The best test is a real email. Send one to a personal mailbox, then open the message details (often called &#8220;Show original&#8221; or &#8220;View source&#8221;). Look for a line like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Authentication-Results: ... spf=pass ... dkim=pass ... dmarc=pass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Three times &#8220;pass&#8221; means you are done. \ud83c\udf89<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Tighten DMARC over time<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Read your DMARC reports for two to four weeks. When every real sender passes, make the policy stronger:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>quarantine<\/code> sends failing emails to spam. <code>pct=25<\/code> applies it to only 25% of failing mail at first. Raise it to 100, then later move to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now fake emails using your domain are blocked completely.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common problems<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SPF &#8220;permerror&#8221;<\/strong> \u2192 You have two SPF records, or more than 10 DNS lookups. Merge them into one record and remove services you no longer use.<\/li>\n\n\n<li><strong>DKIM fails<\/strong> \u2192 The key was copied with a missing character or extra spaces. Copy it again from your provider.<\/li>\n\n\n<li><strong>Emails from one tool fail DMARC<\/strong> \u2192 That tool sends with its own domain. Add its SPF include and set up DKIM for it in its settings.<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Wrap-up<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">SPF says who may send. DKIM proves the message was not changed. DMARC tells receivers what to do and sends you reports. Together they make your emails trusted, and make it hard for others to pretend to be you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next idea: set a monthly reminder to read your DMARC reports. They are the easiest way to spot a new tool sending email without permission.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn what SPF, DKIM and DMARC are in simple words, and how to set them up so your emails reach the inbox.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[36,37,34,15,35],"class_list":["post-53","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-dkim","tag-dmarc","tag-dns","tag-email","tag-spf"],"_links":{"self":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":1,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"predecessor-version":[{"id":80,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/53\/revisions\/80"}],"wp:attachment":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}