SPF and Include Directive

SPF allows include: directives, but there are also limits to the number of DNS lookups which can be made. Since included rules can contain other included rules, it is not simple to determine how many levels you have, and you can quickly exceed the number of DNS lookups

RFC 7208 (section 4.6.4) states

 Some mechanisms and modifiers (collectively, "terms") cause DNS
 queries at the time of evaluation, and some do not.  The following
 terms cause DNS queries: the "include", "a", "mx", "ptr", and
 "exists" mechanisms, and the "redirect" modifier.  SPF
 implementations MUST limit the total number of those terms to 10
 during SPF evaluation, to avoid unreasonable load on the DNS

The following scripts does not take all of that into account, though it could be easily modified to do so. Instead, it simply builds a visual display of the include tree. To get an accurate account, add the records in the RFC above, or simply visit http://mxtoolbox.com/ which has some very good tools to check your spf records

Note: this was a quick and dirty, and could use some cleanup, especially since there aren't even comments in it. Requires a system with the commands dig and grep on it.

tracespf
#! /usr/bin/env perl
 
use warnings;
use strict;
 
sub getIncludes {
   my $indent = shift;
   my $return = '';
   foreach my $domain ( @_ ) {
      $return .= ' 'x$indent . "$domain\n";
      my @lines = `dig $domain TXT | grep spf`;
      chomp @lines;
      foreach my $entry ( @lines ) {
         while ( $entry =~ m/include:([_a-zA-Z0-9\-\.]+)/g ) {
            $return .= &getIncludes( $indent+3, $1 );
         } # while
      } # foreach
   } # foreach
   return $return;
} # sub
 
while ( my $domain = shift ) {
   print &getIncludes( 0, $domain );
}
1;