Skip to main content

SPF module

The SPF module checks the sender's SPF Many mail providers use SPF records to determine eligible hosts for sending email on a specific domain. There are various ways to create and use SPF records, but they all primarily verify the sender's domain and IP.

A specific scenario involves automated messages from the special mailer daemon address: <>. In this case, Rspamd utilizes HELO to retrieve domain information according to the standard.

Principles of work

When used correctly, SPF can be a valuable tool. However, it often becomes vulnerable in situations where a message is redirected or modified by mailing list software.

Furthermore, numerous mail providers lack a proper understanding of this technology, resulting in the misuse of SPF techniques. As a result, the scores for SPF symbols in Rspamd tend to be relatively low.

The cache follows the principle of least recently used expiration, meaning that the lifetime of each cached item is determined by the time to live of the corresponding DNS record.

To configure the SPF module, you have the option to manually specify the cache size and maximum expiration time. Additionally, you can define parameters such as the maximum number of recursive DNS subrequests (including chain length), the maximum count of DNS requests per record, the minimum TTL enforced for all elements in SPF records, and the ability to disable all IPv6 lookups.

Configuration options

OptionDefaultDescription
spf_cache_size2048Number of elements in the LRU cache of parsed SPF records
spf_cache_expire1dCarried in the default config file for reference; not currently consumed by the SPF library (cache lifetime is determined by DNS record TTL)
max_dns_nesting10Maximum number of recursive DNS subrequests (include chain length)
max_dns_requests30Maximum count of DNS requests per record
min_cache_ttl5minMinimum TTL enforced for all elements in SPF records
disable_ipv6falseDisable all IPv6 lookups
whitelistnilMap of IP addresses to whitelist from checks
external_relaynilRadix map of trusted relay IP addresses. When a received header's by IP matches an entry, the next hop's IP from the received chain is used as the SPF check source instead of the connection IP. Useful when the MTA sits behind a fixed trusted relay and the external_relay module is not applicable.

Symbols

The module produces the following symbols:

SymbolDescription
R_SPF_ALLOWSPF check passed
R_SPF_FAILSPF check failed (hard fail)
R_SPF_SOFTFAILSPF check soft failed
R_SPF_NEUTRALSPF neutral result
R_SPF_DNSFAILDNS failure during SPF check
R_SPF_PERMFAILPermanent SPF failure (e.g., invalid record)
R_SPF_NANo SPF record found
R_SPF_PLUSALLSPF record contains +all (accepts all)

Example configuration

# local.d/spf.conf

spf_cache_size = 2048; # cache up to 2048 of the most recent SPF records
max_dns_nesting = 10; # maximum number of recursive DNS subrequests
max_dns_requests = 30; # maximum count of DNS requests per record
min_cache_ttl = 5min; # minimum TTL enforced for all elements in SPF records
disable_ipv6 = false; # disable all IPv6 lookups
whitelist = "/path/to/some/file"; # whitelist IPs from checks
# external_relay = ["192.168.1.1"]; # use IP from received headers when connection comes via this relay

Using SPF with forwarding

If your MTA is placed behind some trusted forwarder you can still check SPF policies for the originating domains and IP addresses. The recommended approach is to use the dedicated external relay module, which provides richer functionality. Alternatively, the external_relay option in the SPF plugin itself is fully functional: configure it as a list of trusted relay IPs and the SPF check will use the preceding hop's IP from the received headers instead of the connection IP.