Daniel Ouellet wrote:
Jeff Simmons wrote:
So I just set up a nice spamd for a client, and then watched Google's Postini try to resend a single email message from just about every IP they own.

For google, why not get it from the source itself?

Example:

# dig txt _spf.google.com | grep spf
; <<>> DiG 9.3.4 <<>> txt _spf.google.com
;_spf.google.com.               IN      TXT
_spf.google.com. 187 IN TXT "v=spf1 ip4:216.239.32.0/19 ip4:64.233.160.0/19 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:209.85.128.0/17 ip4:66.102.0.0/20 ip4:74.125.0.0/16 ip4:64.18.0.0/20 ip4:207.126.144.0/20 ?all"
Here's a script I use. It handles includes by using recursion, which is a bit dangerous if there's an endless loop of includes out in the world, but it's worked for me so far. It will also do DNS lookups for hosts that are specified by name instead of an IP address and handles sites that don't put in a FQDN in for the hostname. The output can be fed to pfctl such as:
pfctl -t local-white -T replace -f /etc/spamd/whitelist.txt

The output from my script for google is: (I actually have a list of
# ./extract_spf spf_hosts.txt
# google.com
# Additional spf: include:_netblocks.google.com
# ==========
# Recursing for additional spf records
# ==========
# _netblocks.google.com
216.239.32.0/19
64.233.160.0/19
66.249.80.0/20
72.14.192.0/18
209.85.128.0/17
66.102.0.0/20
74.125.0.0/16
64.18.0.0/20
207.126.144.0/20

For Hotmail...
# ./extract_spf spf_hosts.txt >  /tmp/x
vi # vi /tmp/x
# cat /tmp/x
# microsoft.com
# Additional spf: include:_spf-a.microsoft.com
# Additional spf: include:_spf-b.microsoft.com
# Additional spf: include:_spf-c.microsoft.com
# Additional spf: include:_spf-ssg-a.microsoft.com
# ==========
# Recursing for additional spf records
# ==========
# _spf-a.microsoft.com
216.99.5.67
216.99.5.68
202.177.148.100
203.122.32.250
202.177.148.110
213.199.128.139
213.199.128.145
207.46.50.72
207.46.50.82
# dns lookup delivery.pens.microsoft.com
# dns lookup mh.microsoft.m0.net
# _spf-b.microsoft.com
# dns lookup delivery2.pens.microsoft.com
# dns lookup delivery.smtp.microsoft.com
131.107.65.22
131.107.65.131
131.107.1.101
131.107.1.102
217.77.141.52
217.77.141.59
# _spf-c.microsoft.com
203.32.4.25
213.199.138.181
213.199.138.191
207.46.52.71
207.46.52.79
131.107.1.18
131.107.1.19
131.107.1.20
131.107.70.12
131.107.70.16
86.61.88.25
# _spf-ssg-a.microsoft.com
207.68.169.173/30
207.68.176.1/26
207.46.132.129/27
207.68.176.97/27
65.55.238.129/26
207.46.222.193/26
207.46.116.135/29
65.55.178.129/27
213.199.161.129/27
65.55.33.70/28
# =========
# DNS Lookups
# =========
# delivery.pens.microsoft.com
207.46.248.68
207.46.248.69
207.46.248.64
207.46.248.65
207.46.248.66
207.46.248.67
# mh.microsoft.m0.net
209.11.164.116
# delivery2.pens.microsoft.com
207.46.248.41
207.46.248.42
207.46.248.43
207.46.248.40
# delivery.smtp.microsoft.com
207.46.22.98
207.46.22.101
207.46.248.70
207.46.248.71




#!/bin/sh
if [ $# -ne 1 ]; then
 echo "Usage: `basename $0` hostlist_file"
 exit 1
fi

if [ ! -f "$1" ]; then
 echo "Unable to locate: $1"
 exit 1
fi

> /tmp/spf_lookup.$$
> /tmp/more_spf.$$

cat $1 | while read host; do
 echo "# $host"
 dig $host TXT +short | sed 's/"//g' | \
 awk '$1 == "v=spf1" {
   num=split($0,stuff," ")
   for (i=1;i<=num;i++){
     if (substr(stuff[i],1,4)=="ip4:") {
       print substr(stuff[i],5)
     } else {
       if (substr(stuff[i],1,2)=="a:") {
         _tmp=substr(stuff[i],3)
         _octet=split(_tmp,_tmpsplit,".")
         if (_octet==1) {
           printf("%s.%s\n", substr(stuff[i],3), host) >> lookup
           printf("# dns lookup %s.%s\n", substr(stuff[i],3), host )
         } else  {
           print substr(stuff[i],3) >> lookup
           printf("# dns lookup %s\n", substr(stuff[i],3) )
         }
       } else {
         if (substr(stuff[i],1,8)=="include:") {
           printf("# Additional spf: %s\n", stuff[i],0)
           print substr(stuff[i],9) >> spf
         }
       }
     }
   }
 }' host=$host lookup="/tmp/spf_lookup.$$" spf="/tmp/more_spf.$$"
done

if [ -s /tmp/spf_lookup.$$ ]; then
 echo "# ========="
 echo "# DNS Lookups"
 echo "# ========="

 while read host; do
   echo "# $host"
   dig $host A +short | grep -v '^;;'
 done < /tmp/spf_lookup.$$
fi

if [ -s /tmp/more_spf.$$ ]; then
 echo "# =========="
 echo "# Recursing for additional spf records"
 echo "# =========="

 $0 /tmp/more_spf.$$
fi

rm -f /tmp/spf_lookup.$$ /tmp/more_spf.$$

exit 0

Reply via email to