Restored Article: SPF: The Foundation of Email Sender Authentication

The Sender Policy Framework (SPF) is a foundational email authentication technology. It enables a domain owner to specify, via a special DNS record, which hosts are authorized to send mail on behalf of their domain.

This is a resurrected article, originally written by me on January 21, 2018, and thoughtfully reviewed and expanded to reflect current, production-ready standards.

When an email arrives from a system not listed in this authorization record, the receiving mail server can choose to block, heavily filter, or merely tag the message, depending on the policy defined in the SPF record. The check applies to both the address in the MAIL FROM envelope and the address used in the HELO/EHLO command.

How SPF Works: A Practical Example

If an email with the sender address info@no-uce.de arrives, the receiving mail server performs an SPF query against the domain’s DNS.

jean@andor ~ $ host -t TXT no-uce.de
no-uce.de descriptive text "v=spf1 a mx -all"

In this classic example, emails for no-uce.de are only authorized if they originate from an IP found in the domain’s A or MX records. The prepended minus sign (-) on the final all mechanism specifies a strict rejection policy for all other sending sources. The receiving mail server is thus instructed to reject unauthorized emails.

The deployment of SPF is divided into two independent areas:

  1. Publishing an SPF Record: This allows other servers to validate your sending sources, preventing unauthorized use of your domain in phishing and spam campaigns.
  2. Evaluating SPF Records: This involves implementing a check on your receiving server to validate the SPF records of incoming emails, providing a reliable anti-spam signal.

The Components of an SPF Record

Mechanisms

Mechanisms are used in the main body of the record to define which IPs are authorized.

MechanismDescription
allThe final, mandatory mechanism. It matches everything and is used to define the policy for all traffic not matched by preceding mechanisms.
ip4Matches the client IP against a specified IPv4 address or range.
ip6Matches the client IP against a specified IPv6 address or range.
aMatches the client IP against the IP addresses found in the A records of the current domain.
mxMatches the client IP against the IP addresses found in the MX records of the current domain.
ptrDEPRECATED (RFC 7208): Matches if the client’s IP has a hostname that resolves back to the original IP. Avoid using this mechanism due to the high load it places on DNS servers.
existsUsed for specific checks, testing whether a domain resolves to an A record.
includeAllows you to reference the SPF record of another domain (e.g., include:_spf.google.com).

Critical Limitation: The 10-Lookup Limit (PermError) The 10-lookup limit is still in effect today and is mandated by RFC 7208. The SPF specification limits a single record to a maximum of 10 DNS lookup mechanisms (a, mx, ptr, exists, include, redirect). Exceeding this limit results in a PermError, which causes the receiving server to treat the SPF result as invalid, usually resulting in a failed delivery. This most often happens due to nested include statements.

Qualifiers (The Policy)

Every mechanism must be preceded by a qualifier (or use the default +):

QualifierMeaningAction (DMARC Context)
+ (Pass)Sender is authorized. (Default if omitted).Pass (Alignment required for DMARC success).
- (Fail)Sender is explicitly not authorized.Hard Fail (Clear instruction to Reject).
~ (SoftFail)Sender is likely not authorized, but treat non-fatally.Soft Fail (Instruction to Quarantine/Accept).
? (Neutral)No statement can be made about authorization.Neutral (Instruction to Accept).

Example Record Breakdown:

The record v=spf1 exists:example.com a mx ?include:_spf.google.com -all means:

  • v=spf1: SPF version 1.
  • exists:example.com: Checks for the existence of an A record for example.com.
  • a and mx: IPs matching the domain’s A or MX records are authorized.
  • ?include:_spf.google.com: If Google’s SPF rules match, treat the result as neutral (accept).
  • -all: All other sending sources must be rejected.

SPF Implementation and The Modern Security Chain

1. The Full Security Chain (SPF, DKIM, DMARC, and BIMI)

The biggest drawback of SPF is that it does not provide feedback if an email is rejected, and SPF alone does not prevent spoofing. A spoofer can still forge the visible sender address (Header From) while passing the SPF check on the envelope (MAIL FROM).

This is why SPF must be deployed alongside DKIM and DMARC. The modern, complete E-Mail-Authentication-Chain is:

  • SPF (The Foundation): Verifies the sending server IP.
  • DKIM (The Signature): Verifies the content has not been tampered with.
  • DMARC (The Enforcer): Uses the results of SPF and DKIM to enforce a policy (p=reject) and provides failure reports.
  • BIMI (The Brand Indicator): (New Technology) Requires a strict DMARC policy to display your brand logo next to the email in the recipient’s inbox, proving a fully authenticated message.

2. Integration into Postfix

To check SPF on incoming mail, you need a policy daemon. The Python variant, postfix-policyd-spf-python, is still a widely used and reliable solution today.

  1. Installation: Install the policy daemon (e.g., using apt-get install postfix-policyd-spf-python on Debian).
  2. main.cf Configuration: Add the time limit and integrate the policy service into your smtpd_recipient_restrictions (must follow reject_unauth_destination):

    policy-spf_time_limit = 3600s
    smtpd_recipient_restrictions =
    ...
    reject_unauth_destination check_policy_service unix:private/policy-spf
    ...
  3. master.cf Configuration: Define the policy daemon service:

    policy-spf unix - n n - - spawn user=nobody argv=/usr/bin/policyd-spf

3. Fallacies and Pitfalls

  • Internal Mail: If a customer or internal user sends mail through a different local system not covered by the A or MX records, those emails will be blocked by SPF-filtering receiving servers. The internal IP/Hostname must be explicitly added to the SPF record.
  • External Sender: An employee sending an email from a university mail server with a private GMX address as the sender will fail SPF. This is because the university server’s IP is not authorized in the GMX SPF record. SPF correctly flags this as potentially spoofed mail.
  • HELO Hostname SPF Records: It is best practice to have a dedicated SPF record for the hostname your Mail Transfer Agent (MTA) uses in the HELO/EHLO command, separate from the domain’s primary SPF record.

    # SPF for the domain used in MAIL FROM (e.g., no-uce.de)
    no-uce.de. IN TXT "v=spf1 mx -all"

    # SPF for the MTA's HELO/EHLO hostname
    mail.no-uce.de. IN TXT "v=spf1 a -all"

4. Null-SPF for Non-Sending Subdomains

To prevent spoofing from subdomains that should never send mail (like www., ftp., or services), set a Null-SPF record with a hard fail:

www.no-uce.de. IN TXT "v=spf1 -all"

This clearly signals to all receiving servers that any email claiming to be from www.no-uce.de is fraudulent and must be rejected.

5. SPF Macros (Advanced Usage)

SPF macros allow the dynamic checking of conditions. While complex, they can be used for advanced filtering, such as querying a custom DNS Blacklist (DNSBL) maintained by your system:

Example ScenarioSPF Record EntryBenefit
Real-time Failure Loggingv=spf1 ... exp=spf-fail.%{i}._ip.%{h}.spf.example.com -allIf SPF fails, the recipient server attempts to resolve the record spf-fail.<Sender-IP>.<HELO-Hostname>.spf.example.com. By logging queries to your domain’s DNS, you instantly know which IP caused the rejection, giving you a powerful, decentralized auditing log.

Quellen / See Also

  • RFC 7208. Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1. https://www.rfc-editor.org/rfc/rfc7208
  • RFC 7489. Domain-based Message Authentication, Reporting, and Conformance (DMARC). https://www.rfc-editor.org/rfc/rfc7489
  • RFC 4408. Classic SPF specification. https://www.rfc-editor.org/rfc/rfc4408
  • DMARC.org. The official site for SPF, DKIM, and DMARC. https://dmarc.org/
  • BIMI Group. Brand Indicators for Message Identification. https://bimigroup.org/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.