User Tools

Site Tools


exim4:validating_spf

Exim4 - Validating SPF

SPF-Checking at SMTP-time

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)

Enable this in exim4

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

Another method

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:

  • 1 = neutral
  • 2 = success
  • 3 = failure
  • 4 = soft failure
  • 5 = no SPF entry for the domain
  • 6 = NS unreachable – defer in Exim's terms
  • 7 = error on parsing SPF record(s); functionally equivalent to 5

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.

exim4/validating_spf.txt · Last modified: 2020/07/15 09:30 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki