SPF (Sender Policy Framework) allows the receiver to check that an email claimed to have come from a specific domain comes from an IP address authorized by that domain's administrators.

Domain SPF #

You can lookup TXT entries of a domain pretty easily to get a SPF record but the problem is most mail services will have multiple servers seperated into lists of their own. (most companies rely heavily on these external services)
This can also include external providers for sending newsletters.

Example google.com

    dig +short google.com TXT | grep spf1
    "v=spf1 include:_spf.google.com ~all"

In some cases these include lists expand into even more lists.

    dig +short _spf.google.com TXT | grep spf1
    "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"

Now we have 3 lists to look into.

    dig +short _netblocks.google.com TXT | grep spf1
    "v=spf1 ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ~all"

Finally we hit some server IP addresses.

Security Note

If you have an external provider included in your SPF you are giving full trust to their servers, allowing them to send from any address (@yourdomain) on your behalf.

CLI Script #

It would be nice to be able to type one command in CLI with a domain and have it extract all of these server IPs.
You could then use it to whitelist or blacklist IP addresses.

    └── google.com
        └── v=spf1 include:_spf.google.com
            └── v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com

Given the problem shown above we will need to iterate over each spf list.

This involves using a function to extract ip4: and ip6: entries which can loop itself using include: as an input until there are no include: remaining.

Example Output #

./spf_list.sh github.com
[+] looking up SPF records for domain [  github.com  ]
[+] IP addresses allowed to send from domain  github.com
# github.com
## 19/02/2020
# github.com
# _spf.google.com
# _netblocks.google.com

Download #

The script can be downloaded from github.