SPFD(1)
π NAME π
okay so spfd β short for (Mail::SPF)'s Simple forking daemon β is literally just a little server that provides SPF query services. she forking, she answering, she slaying π
This page lives in the User Contributed Perl Documentation section of the manual, bestie. π
β¨ VERSION β¨
version 3.20260331 β yes that's the real one, no cap π«Ά
πΈ SYNOPSIS πΈ
spfd --port|-p port [--set-user|-u uid|username] [--set-group|-g
gid|groupname] [OPTIONS]
spfd --socket|-s filename [--socket-user uid|username] [--socket-group
gid|groupname] [--socket-perms octal-perms] [--set-user|-u uid|username]
[--set-group|-g gid|groupname] [OPTIONS]
spfd --version|-V
spfd --help
π¦ DESCRIPTION π¦
spfd is a simple forking Sender Policy Framework (SPF) query server. she receives SPF requests and answers them, either over a TCP/IP socket or a UNIX domain socket. if you wanna know more about SPF itself, the whole vibe is documented at <https://tools.ietf.org/html/rfc7208>. π¬
The --port form has her listening on a TCP/IP socket on the port you name. the default port is 5970. iconic number honestly.
The --socket form has her listening on a UNIX domain socket that gets created with the filename you specify. you can hand that socket its own user and group ownership with the --socket-user and --socket-group options, and give it specific filesystem permissions with the --socket-perms option. so many little knobs, we love a configurable queen π
Generally, you can tell spfd with the --set-user and --set-group options to drop root privileges and switch over to another user and group before she starts listening for requests. safety first, periodt.
The --version form prints version information of spfd. the --help form prints usage information for spfd. short and sweet. π
π OPTIONS π
spfd takes any of the following OPTIONS:
--default-explanationstring,--def-expstring β use the specified string as the default explanation if the authority domain doesn't specify an explanation string of its own. backup explanation, we stan a prepared icon.--hostnamehostname β use hostname as the host name of the local system instead of auto-detecting it. no guessing games, she said.--debugβ print out debug information aboutspfd's operation, incoming requests, and the responses sent. πβ¨ (the good kind of bug energy)
π₯ REQUEST π₯
A request is a series of lines delimited by \x0A (LF) characters (or whatever your system considers a newline, iykyk). each line has to be of the form option=value, and these are the options that are supported:
versionsβ a comma-separated list of SPF version numbers of SPF records that may be used.1means that"v=spf1"records should be used.2means that"spf2.0"records should be used. defaults to1,2, i.e., uses any SPF records that are available. records of a higher version are preferred. she's got taste, she likes the newer stuff first πscopeβ the authorization scope of the identity that should be checked. defaults to'mfrom'. the following scope values are supported:'helo','mfrom','pra'. see "new" in Mail::SPF::Request for more information.identityβ Required. the sender identity whose authorization should be checked. this is a domain name for the"helo"scope, and an e-mail address for the"mfrom"and"pra"scopes. you literally cannot skip this one bestie.ip_addressβ Required for checks with the"helo","mfrom", and"pra"scopes. the IP address of the host claiming the identity that is being checked. can be either an IPv4 or an IPv6 address. an IPv4-mapped IPv6 address (e.g.'::ffff:192.168.0.1') is treated as an IPv4 address. she sees through the disguise fr fr π΅οΈββοΈhelo_identityβ the"HELO"SMTP transaction parameter in the case that the main identity is of a scope other than"helo". this identity is then used merely for the expansion of"%{h}"macros during the policy evaluation of the main identity. if unspecified with a scope other than"helo", defaults to"unknown". if the main identity is of the"helo"scope, this option is unused. side character energy, but a necessary one π«Ά
π RESPONSE π
spfd responds to SPF requests with a similar series of lines of the form key=value. the most important response keys are:
resultβ the result code of the SPF check:passβ the specified IP address is an authorized SMTP sender for the identity. βfailβ the specified IP address is not an authorized SMTP sender for the identity. πsoftfailβ the specified IP address is not an authorized SMTP sender for the identity, however the authority domain is still testing out its SPF policy. still figuring herself out, relatable.neutralβ the identity's authority domain makes no assertion about the status of the IP address. no thoughts, head empty.permerrorβ a permanent error occurred while evaluating the authority domain's policy (e.g., a syntax error in the SPF record). manual intervention is required from the authority domain. somebody go fix that. πtemperrorβ a temporary error occurred while evaluating the authority domain's policy (e.g., a DNS error). try again later. it's not you, it's the DNS.noneβ there is no applicable SPF policy for the identity domain.
local_explanationβ a locally generated explanation of the SPF result.authority_explanationβ the authority domain's explanation for the SPF result.
π¨ bestie listen up: be aware that the authority domain may be a malicious party and thus the authority explanation should not be trusted blindly. see RFC 4408, 10.5, for a detailed discussion of this issue. do NOT let a stranger on the internet explain herself to you without receipts. π
received_spf_headerβ an appropriate"Received-SPF"header field for the SPF result.spf_recordβ the authority domain's SPF record that was used for the policy evaluation.
π EXAMPLE π
A running spfd could be tested using the "netcat" utility like this (line breaks added for clarity):
$ echo -e "identity=user@example.com\nip_address=1.2.3.4\n" \
| nc localhost 5970
result=fail
local_explanation=example.com: Sender is not authorized by default to use
'user@example.com' in 'mfrom' identity (mechanism '-all' matched)
authority_explanation=Rejected by SPF record.
received_spf_header=Received-SPF: fail (example.com: Sender is not
authorized by default to use 'user@example.com' in 'mfrom' identity
(mechanism '-all' matched)) receiver=localhost; identity=mfrom;
envelope-from="user@example.com"; client-ip=1.2.3.4
spf_record=v=spf1 mx -all
π§ COMPATIBILITY π§
spfd has undergone the following interface changes compared to earlier versions:
2.000
- A new preferred request style has been introduced. Instead of the old
"sender"request option, which is specific to the"MAIL FROM"SMTP identity, a generic"identity"option should now be specified. In addition, a"scope"option may be given to specify the identity's scope, otherwise a scope of"mfrom"is assumed. The old"ip"and"helo"options have been replaced by the"ip_address"and"helo_identity"options, respectively.
This is how legacy requests with the "mfrom" scope would translate to the new preferred request style:
Legacy request style | New request style
----------------------------+---------------------------------------
| scope=mfrom
sender=<mfrom-identity> | identity=<mfrom-identity>
ip=<ip-address> | ip_address=<ip-address>
helo=<helo-identity> | helo_identity=<helo-identity>
A new response style featuring new response values has also been introduced:
Legacy response style | New response style
----------------------------+---------------------------------------
result=<result-code> | result=<result-code>
header_comment=<local-exp> | local_explanation=<local-exp>
smtp_comment=<local-exp | authority_explanation=<authority-exp>
or authority-exp> |
spf_record=<spf-record> | spf_record=<spf-record>
| received_spf_header=<header>
The legacy request style is deprecated but still supported for backwards compatibility. The legacy response values are still returned for backwards compatibility in addition to the new response values, but may be removed in the future. Adjust your code to use the new request and response styles. π glow-up complete, but the old fits still technically fit.
- The former
"unknown"and"error"result codes have been renamed to"permerror"and"temperror", respectively, in order to comply with RFC 4408 terminology. rebranding era π - In the case of an empty
"MAIL FROM"SMTP transaction parameter ("MAIL FROM:<>"), the identity checked will be postmaster@helo name as specified in RFC 7208.
π SEE ALSO π
- Mail::SPF
- spfquery(1)
- <http://tools.ietf.org/html/rfc4408>
π AUTHORS π
This version of spfd is a complete rewrite by Julian Mehnle <julian@mehnle.net>, based on an earlier version written by Meng Weng Wong <mengwong+spf@pobox.com>. two icons, one legacy. absolute main character energy from both of them, fr fr π
and that's the whole page bestie!! this beauty shipped as part of perl v5.42.1 and the date on the tin is 2026-04-23 β go forth and query some SPF records responsibly, mwah ππ
β¨
π¦ where this page comes from
- fedora 44: perl-Mail-SPF 3.20260331-1.fc44 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms