How SPF, DKIM, and DMARC Protect Your Email Domain from Spoofing
Email spoofing is one of the most effective techniques used in phishing attacks and business email compromise. An attacker does not need to breach your server or steal your credentials. They simply send an email that appears to come from your domain, and your customers, suppliers, or colleagues see a familiar sender address and act on it.
The reason this works is that standard SMTP, the protocol email is built on, has no built-in mechanism to verify that the From address matches the actual sending server. Without proper email authentication records published in your DNS, any mail server on the internet can send an email claiming to be from yourdomain.com. Google, Microsoft, and Yahoo have all confirmed that email authentication failures are a primary criterion for spam rejection. If your domain is not authenticated, your legitimate transactional email, such as booking confirmations, password reset messages, and invoices, is increasingly likely to land in spam or be rejected entirely.
SPF, DKIM, and DMARC are the three email authentication standards that solve this problem. Together they allow receiving mail servers to verify that an email claiming to be from your domain was actually sent by an authorised server and was not modified in transit.
Why Email Spoofing Works and What Attackers Gain
The mechanics of a spoofing attack are straightforward. An attacker obtains a list of email addresses, purchases a domain similar to yours (yourcompanysecure.com instead of yourcompany.com), or simply spoofs your domain directly. They configure their mail server to send email with a From header of [email protected]. The email arrives in your customer's inbox looking completely legitimate. It contains an invoice with new banking details. The customer pays. The money is gone.
The attack succeeds because the email looks right. Your customer sees the familiar domain name, trusts the content, and acts on the request. This is why email authentication matters for every business domain, regardless of size.
Beyond financial fraud, spoofing is used to distribute phishing links, steal credentials, and gather intelligence on businesses. Your domain being used in spoofed emails also damages your sender reputation, which affects whether your legitimate email reaches the inbox at all. Understanding how these authentication layers work helps you configure them correctly and maintain both security and deliverability.
SPF: Defining Which Servers Are Allowed to Send for Your Domain
SPF works by publishing a TXT record in your domain's DNS that lists every IP address permitted to send mail for your domain. When a receiving mail server gets an email from @yourdomain.com, it looks up your SPF record and compares the sending server's IP against your list. If the IP is not listed, the check fails.
An SPF record starts with a version identifier and then uses mechanisms to specify authorised servers. The most common mechanisms are:
- ip4: Specifies an exact IPv4 address or CIDR range. Example:
ip4:203.0.113.50/32authorises that specific IP address. - ip6: Same as ip4 but for IPv6 addresses.
- include: Pulls in another domain's SPF record. Used for mail providers:
include:_spf.google.comfor Google Workspace. - a: Authorises the A or AAAA records of the specified domain.
a:mail.yourdomain.comauthorises whatever IP address that hostname resolves to. - mx: Authorises the MX records of the specified domain.
mx:yourdomain.comauthorises your mail server IP addresses from DNS. - ~all: Soft fail. Unlisted servers are marked as suspicious but not rejected. This is used during initial setup.
- -all: Hard fail. Unlisted servers should be rejected. Use this only when you are confident your SPF record is complete.
- ?all: Neutral. No policy is enforced. Used when you want to observe without taking action.
A complete SPF record for a business using Google Workspace and a third-party marketing platform looks like this:
v=spf1 include:_spf.google.com include:eu2.icmailcenter.com ~all
The include: directive for Google Workspace pulls in all the IP ranges Google uses for Gmail sending. You do not need to know Google's IP addresses. The include directive resolves the _spf.google.com TXT record and uses whatever IP addresses are listed there. When Google adds new sending IP addresses, your SPF record automatically covers them because the include pulls the current record.
You can have multiple include statements for each email service you use. If you send via Google Workspace, SendGrid for transactional email, and Mailchimp for marketing, your record would be:
v=spf1 include:_spf.google.com include:sendgrid.com include:servers.mcsv.net ~all
The include mechanism works as long as the included domain has a valid SPF record. If you include a domain that does not have an SPF record, the include returns no IP addresses and all email from that service fails SPF.
SPF has a practical limit. You can have at most 10 DNS lookups in your SPF record. The include:, a:, mx:, and ptr: mechanisms each count as a lookup. Exceeding 10 lookups causes a permerror, which most receiving servers treat as a failed SPF check. If you have many email services, consider a subdomain delegation strategy where each service sends from its own subdomain, keeping each subdomain's SPF record simple.
DKIM: Cryptographic Proof That an Email Was Not Modified
DKIM adds a digital signature to email headers. When your mail server sends an email, it computes a hash of selected headers and the message body, then signs this hash with a private key. The public key is published in your DNS as a DKIM record. The receiving mail server looks up the DKIM record, verifies the signature using the public key, and if verification succeeds, knows the email was not modified after signing.
It is important to understand what DKIM does not do. DKIM does not verify the From header. It verifies that the content was signed by a server holding the private key and was not altered. An email can have a valid DKIM signature but a completely forged From address. This is why SPF and DKIM individually are insufficient on their own. You need both plus DMARC alignment to tie them together and protect your domain effectively.
DKIM records use a selector to distinguish between multiple signing keys. A selector is part of the DKIM signature header added to every outgoing email. The receiving server uses the selector to look up the corresponding TXT record in your DNS and retrieves the public key to verify the signature. You can have multiple DKIM keys by using different selectors. This is a common practice when rotating keys or using different signing services.
To generate a DKIM key pair using OpenDKIM on a Linux mail server:
# Generate the selector and key pair
mkdir -p /etc/opendkim/keys
opendkim-genkey -D /etc/opendkim/keys/ -s mail -d yourdomain.com
# The private key is mail.private, public key is mail.txt
# Set correct ownership
chown -R opendkim:opendkim /etc/opendkim
Add the contents of mail.txt as a TXT record at mail._domainkey.yourdomain.com. The format is:
mail._domainkey.yourdomain.com IN TXT "v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_HERE"
Configure OpenDKIM in /etc/opendkim.conf:
KeyTable /etc/opendkim/keys/keytable
SigningTable refile:/etc/opendkim/keys/signingtable
ExternalIgnoreList refile:/etc/opendkim/keys/trustedhosts
InternalHosts refile:/etc/opendkim/keys/trustedhosts
Configure the keytable at /etc/opendkim/keys/keytable:
mail._domainkey.yourdomain.com yourdomain.com:mail:/etc/opendkim/keys/mail.private
Configure the signing table at /etc/opendkim/keys/signingtable:
*@yourdomain.com mail._domainkey.yourdomain.com
Restart OpenDKIM after any key change. When rotating a DKIM key, generate a new key pair, publish the new public key in DNS, keep the old public key in DNS for a transition period of at least 48 hours to allow for DNS propagation and retry queues, update the signing configuration to use the new key, and then remove the old key from DNS after confirming all sending is using the new key.
DMARC: Policy Enforcement and Domain Alignment
DMARC is the layer that makes SPF and DKIM actionable. Without DMARC, SPF and DKIM tell you whether an email passed authentication, but receiving servers do not know what to do with that information. DMARC provides the policy: what should happen to email that fails authentication, and where to send aggregate reports about authentication results.
DMARC is published at _dmarc.yourdomain.com as a TXT record. A basic DMARC record looks like this:
v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100
The p= parameter sets the policy. Three values are available:
- p=none: Monitor only. Receiving servers take no action on failing emails. Use this for initial deployment to identify all legitimate sending sources before enforcing a policy.
- p=quarantine: Receiving servers treat failing emails as suspicious, typically by placing them in the spam folder.
- p=reject: Receiving servers reject failing emails outright. This is the goal, but only after confirming all legitimate email passes DMARC.
The rua parameter specifies an email address to receive aggregate DMARC reports. These are XML reports sent daily (sometimes more frequently) by participating receivers. They tell you how many emails were sent purporting to be from your domain, how many passed or failed DMARC, and which sending IP addresses were involved. This is your primary monitoring tool during and after DMARC deployment.
The pct parameter controls what percentage of failing emails the policy applies to. Setting pct=100 applies the policy to all failing emails. Setting pct=50 applies the policy to half of them. During initial deployment with a quarantine policy, you might start with pct=10 to limit disruption while you monitor results.
DMARC also introduces the concept of alignment. An email passes DMARC authentication only if one of the following is true:
- SPF aligned: The SPF-authenticated domain matches the From header domain. For example, if the From header is from @yourdomain.com but the SPF check authorises a subdomain like @mail.yourdomain.com, alignment fails unless you explicitly configure subdomain matching.
- DKIM aligned: The DKIM-authenticated domain matches the From header domain. If the DKIM signature is from a subdomain that does not match the From header domain, alignment fails.
This alignment check is what prevents an attacker from sending email through an authorised server with a forged From header. If the From header is @yourdomain.com but the sending server's SPF is authorised for a subdomain that DMARC does not consider aligned with yourdomain.com, the email fails DMARC.
Start with p=none and monitor for at least two to four weeks. Review the aggregate reports to identify every IP address sending email for your domain. Ensure each one is either in your SPF record or signing with a DKIM key aligned to your domain. Only when all legitimate sources pass DMARC should you move to p=quarantine.
Reading DMARC Aggregate Reports
DMARC aggregate reports arrive as XML attachments to the address specified in your rua parameter. They contain counts of emails from your domain seen by participating mail servers, broken down by source IP address, result (pass or fail), and disposition. They do not contain message content. Only metadata about authentication results is included.
A typical report covers a 24-hour period and lists every sending IP address that generated mail for your domain during that period. For each IP, it shows how many emails passed SPF, DKIM, and DMARC, and how many failed. If you see a sending IP that you do not recognise, with a high proportion of failures, that is likely spoofing of your domain. If all your known legitimate IP addresses show high pass rates, your configuration is working correctly.
For small businesses, dmarcian.com offers a free tier that accepts DMARC reports and presents them in a web dashboard. It is a practical way to handle DMARC reporting if you are not equipped to parse XML reports manually. MXToolbox also provides DMARC report aggregation. Either service receives the XML reports, parses them, and shows you a dashboard of pass and fail rates by IP address and by date.
# Manually parse a DMARC report XML file
xmllint --xpath "//record" dmarc-report.xml 2>/dev/null
# Look for source_ip, row/result, and identifiers/header_from values
If you handle reports manually, look specifically for IP addresses not in your SPF record that are sending significant volumes, IP addresses that are signing with DKIM keys not aligned to your domain, sudden changes in volume that suggest a spoofing campaign, and consistent failures from a known legitimate source that indicates a configuration problem.
Common DMARC Failures and How to Fix Them
Using Multiple Email Service Providers Without Updating SPF
The most common DMARC failure is using multiple email sending services without updating your SPF record for each one. A business that sends transactional email through SendGrid, marketing through Mailchimp, and internal email through Microsoft 365 has three distinct sending infrastructures. If your SPF record only includes Microsoft 365 IP addresses, emails sent through SendGrid and Mailchimp will fail SPF and thus fail DMARC, unless they are also DKIM-signed with a domain aligned to your From address.
The fix requires adding an include statement for each service's SPF record to your domain's SPF record and ensuring each service has DKIM keys configured for your domain, not their own default signing domain. Mailchimp's default DKIM signature uses mailchimp.com, which does not align with yourdomain.com. You need to configure a custom DKIM domain in Mailchimp's DNS settings that uses your domain, which requires adding a DKIM record in your DNS for Mailchimp's selector.
Subdomain Alignment Issues
DMARC alignment checks the RFC5321 From domain against the SPF-authenticated domain and the DKIM-authenticated domain. If your From header is @yourdomain.com, SPF is aligned to mail.yourdomain.com, and DKIM is aligned to yourdomain.com, the email may pass DMARC because DKIM alignment succeeds. However, if SPF is aligned to a subdomain and DKIM is also aligned to a different subdomain that does not match @yourdomain.com, DMARC fails.
This is particularly problematic when different business units use different subdomains for email sending. Configure each subdomain with its own SPF record and its own DKIM key, then add a DMARC record for each subdomain if they have different sending requirements.
# DMARC record for the root domain
_dmarc.yourdomain.com IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=r; aspf=r"
# DMARC record for a subdomain used by marketing
_dmarc.marketing.yourdomain.com IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
The adkim=r and aspf=r parameters set relaxed alignment mode, which means subdomains of yourdomain.com are considered aligned. Without these flags, a subdomain that is authorised to send email and DKIM-signed for that subdomain would fail DMARC when the From header uses the root domain.
Forwarded Email Failing DMARC
When an email is forwarded through a mailing list, the forwarded email may fail DMARC because the forwarding server changes the message, which breaks the DKIM signature, and the forwarding server's IP address is not in the original sender's SPF record. This is a known limitation of email authentication and is one reason why mailing list operators use their own sending infrastructure with explicit From header rewriting.
Implementing BIMI for Brand Visibility in the Inbox
BIMI (Brand Indicators for Message Identification) lets you display your brand logo next to your emails in supporting email clients. This feature is currently supported by Apple Mail, Gmail, Yahoo Mail, and some other providers. BIMI requires a valid DKIM signature, a passing DMARC policy at quarantine or reject level, and a BIMI DNS record that points to your logo file.
The BIMI record for your domain is:
default._bimi.yourdomain.com IN TXT "v=BIMI1; l=https://yourdomain.com/logo.svg; a=https://yourdomain.com/bimi.pem"
The l= parameter is the URL of your logo file in SVG format. The a= parameter is the URL of your Authority Token, which is a Base64-encoded X.509 certificate that proves you control the logo URL. The certificate must be valid and not expired.
Obtain a Verified Mark Authority (VMA) certificate from a supported certificate authority. Currently DigiCert and Entrust issue these certificates. This certificate is different from a standard SSL certificate. It specifically validates that your organisation legally owns the trademark for the logo. The certificate costs more than a standard SSL certificate and requires trademark registration evidence, but it is required for BIMI to display correctly in Gmail.
Once you have the VMA certificate in PEM format, publish both the BIMI DNS record and the logo SVG. Test with a tool like MXToolbox BIMI lookup before expecting to see the logo in your inbox. BIMI has a strict validation chain and failures at any step result in the logo not appearing.
Email Authentication for Self-Hosted Mail Servers
If you run your own mail server using Postfix or Exim, you need to configure SPF, DKIM, and DMARC for your server's IP addresses and domain. This is more work than using a managed email provider but gives you full control over your sending infrastructure.
For Postfix, SPF is handled by the policy daemon in your milter chain. Install postsrsd (Sender Rewriting Scheme daemon) if you send email from subdomains that need to be aligned with your root domain for DMARC compliance. Configure DKIM with OpenDKIM as described earlier in this article.
# Postfix milter configuration for OpenDKIM
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
Add this to /etc/postfix/main.cf and reload Postfix. The milter tells Postfix to sign outgoing email with your DKIM key before sending.
DMARC reporting for self-hosted mail requires a tool that can aggregate and send RUA reports. OpenDMARC is the companion tool that enforces DMARC policy and can generate aggregate reports. Alternatively, use a third-party service that receives your DMARC reports and forwards them to dmarcian or MXToolbox.
# OpenDMARC configuration
AuthservID yourdomain.com
UserID opendmarc:opendmarc
Socket inet:8892@localhost
Syslog true
RejectFailures false
IgnoreAuthenticatedClients true
UMask 007
Setting RejectFailures false during initial deployment lets you observe which emails are failing DMARC without losing legitimate mail. Once you are confident in the configuration, switch to true to enforce the policy.
The 10-DNS-Lookup SPF Limit and How to Work Around It
SPF records are limited to 10 DNS lookups. This limit exists because some mail servers refuse to process SPF records with more lookups. If your SPF record causes a permerror, all emails from your domain might be rejected or flagged as suspicious by receiving servers that implement strict SPF processing.
The limit counts each include:, a:, mx:, ptr:, and exists: mechanism. A typical SPF record with three include statements uses three lookups. You are unlikely to hit the limit unless you have many email service providers or deeply nested includes.
If you need to work around the limit, consider using a subdomain strategy where each service sends from its own subdomain, each with a simple SPF record containing only the relevant IP addresses. Alternatively, use a third-party email infrastructure that aggregates your sending through a single provider, or reduce the number of include statements by consolidating email services.
When to Move to p=reject
The goal of DMARC deployment is p=reject, where all failing email is rejected by receiving servers. This provides maximum protection against domain spoofing. However, moving to reject prematurely, before all legitimate email sources are authenticated, will cause you to lose legitimate emails.
The checklist before moving to reject includes confirming that 100% of legitimate sending IP addresses are in your SPF record, all sending services use DKIM keys aligned to your domain, there are no email forwarding scenarios that cause DMARC failures, and DMARC reports show consistent high pass rates from all known sources over at least two to four weeks of monitoring.
Move gradually through the deployment phases. Use p=none for two to four weeks, then p=quarantine for two to four weeks, then p=reject once you have confirmed all legitimate email passes DMARC.
What Authentication Setup Means for Your Email Program
Configuring SPF, DKIM, and DMARC correctly takes some initial effort, but it delivers meaningful protection for your domain and your recipients. Domain spoofing becomes significantly harder when receiving servers check authentication before delivering mail. Your transactional email is more likely to reach the inbox when authentication passes, and phishing campaigns impersonating your domain are visible in DMARC reports so you can respond quickly.
If you need help reviewing your current email authentication setup, gather your domain name, current hosting setup, list of email service providers you use, and any recent delivery issues before getting in touch.