The spf-tools-perl package provides you with a simple daemon, and a simple application which allows you to test that a given IP address may send mail from a particular domain.
apt-get install spf-tools-perl
NOTE: This needs the exim4-daemon-heavy package installed, and not the light variants of exim.
To perform such a test
spfquery.mail-spf-perl --ip-address 1.2.3.4 --mfrom john@example.com
shows
example.com: Sender is not authorized by default to use 'john@example.com' in 'mfrom' identity (mechanism '-all' matched)
That command showed that the IP address 1.2.3.4 was not permitted to send mail for the domain example.com. By contrast this example shows that the IP address 212.110.179.70 is permitted to send mail from this domain:
spfquery.mail-spf-perl --ip-address 5.42.134.35 --mfrom john@sharewiz.net
shows
sharewiz.net: 5.42.134.35 is authorized to use 'jihn@sharewiz.net' in 'mfrom' identity (mechanism 'ip4:5.42.134.35/28' matched)
Add the following to the file /etc/exim4/conf.d/main/00_local_macros, creating that file if necessary:
CHECK_RCPT_SPF=true
Once you've done that, and applied the change, you'll find that SPF-failures will be rejected at SMTP-time.
update-exim4.conf service exim4 restart
If you do not really like the perl thing for performance reasons, you may use the native spfquery tool.
The package spfquery has to be installed and the following rules should be added to acl_check_mail:
defer set acl_m_spf = ${run{/usr/bin/spfquery \ -ip "$sender_host_address" \ -sender "$sender_address" \ -helo "$sender_helo_name"}{}{}} set acl_m_spf = $runrc logwrite = ++ spf=$acl_m_spf \ ip=$sender_host_address \ sender=$sender_address \ helo=$sender_helo_name message = SPF record for $sender_address \ cannot be verified at the moment condition = ${if ={$acl_m_spf}{6}} deny message = SPF policy prohibits sending from \ address $sender_host_address condition = ${if ={$acl_m_spf}{3}}
WARNING: I had to add line breaks due to the code not fitting the screen so they were not tested)
spfquery returns the following rcs:
Now what's really interesting from the practical point of view is the third option, which requires the -all flag to be set in SPF rule. Not many domains have this in fact.
CAUTION: Having analysed many logs to check how effecient this is in stopping spam, shows that SPF is unfortunately very inefficient way to filter incoming mail, even for botnet spam which is rather simple to filter out by other means. It will never work for professional corporate spammers sending targeted messages to dozens of valid addresses at a time.
Due to bad design of the protocol each SPF query may require several DNS queries (the spfquery tool has default limit of 10). On busy servers that's a lot. Server receiving 10 mails per second may potentially generate 50-100 additional DNS queries per second.
For example the rule for mozilla.com has 2 includes at root level, then 3 + 3 for the 2nd level, that's 7 queries in total ending up with ~all, a soft failure which basically means… accept. And so the whole rule with its 7 queries is completely useless anyway.
This probably explains the reason why so few sysadmins actually bother writing SPF rule for their mail relays let alone checking them.