How to configure DNS SPF records for many subdomains

Solution 1:

Your description of your use case is not complete enough. But if your goal is to send email from *@example.com from any of those servers, then the SPF ptr mechanism is designed precisely for this use case.

You would set up proper reverse DNS 1.2.3.4 → sub1.example.com → 1.2.3.4, for each of the subdomain servers.

Then you would install the following SPF record at the main domain example.com:

v=spf1 ptr -all

That is all.

The advantage of this over other approaches is that it is easy to set up, does not run into lookup limits, and scales to an arbitrary number of subdomain hosts.

The disadvantage is that it is somewhat at odds with the prescriptions of the SPF RFC: RFC 7208 discourages use of the ptr mechanism. However, an argument can be made that the wording there is too severe, and given your use case usage of ptr is acceptable. See also my question 1063826.

Solution 2:

It depends a bit on what your aims are, and which problems you into.

There are several SPF mechanisms to match classes of hosts without enumerating all hosts directly in the SPF record, for example:

  • the ip4 mechanism and equivalent ip6 mechanism to match subnets when all your servers belong to one or more IP-address ranges that are exclusively yours:

    ip4:<ip4-network>/<prefix-length>
    ip6:<ip6-network>/<prefix-length>
    
  • you can create a single A record (for example bob.example.com) that contains all IPv4 A and/or IPv6 AAAA records (in round-robin fashion) of the servers that you wish to allow to send mail directly over IPv4 resp. IPv6 and refer to that in your SPF record:

    “v=spf1 a:bob.example.com. ~all”
    
    bob.example.com.  IN A     10.0.0.1
    bob.example.com.  IN A     192.168.0.1
    bob.example.com.  IN A     172.16.0.2
    bob.example.com.  IN AAAA  2001:db8:ffff:ffff:ffff:ffff:ffff:fff1 
    
  • the include keyword can be used when your SPF record becomes too long to fit in a single DNS record. For example the current Gmail/Google SPF record does not directly include any IP ranges but includes those from three additional records:

    _spf.google.com.  300 IN  TXT "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"
    
    _netblocks.google.com.    300 IN  TXT "v=spf1 ip4:35.190.247.0/24 ip4:64.233.160.0/19 ip4:66.102.0.0/20 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:74.125.0.0/16 ip4:108.177.8.0/21 ip4:173.194.0.0/16 ip4:209.85.128.0/17 ip4:216.58.192.0/19 ip4:216.239.32.0/19 ~all"
    
    _netblocks2.google.com.   300 IN  TXT "v=spf1 ip6:2001:4860:4000::/36 ip6:2404:6800:4000::/36 ip6:2607:f8b0:4000::/36 ip6:2800:3f0:4000::/36 ip6:2a00:1450:4000::/36 ip6:2c0f:fb50:4000::/36 ~all"
    
    _netblocks3.google.com.   300 IN  TXT "v=spf1 ip4:172.217.0.0/19 ip4:172.217.32.0/20 ip4:172.217.128.0/19 ip4:172.217.160.0/20 ip4:172.217.192.0/19 ip4:172.253.56.0/21 ip4:172.253.112.0/20 ip4:108.177.96.0/19 ip4:35.191.0.0/16 ip4:130.211.0.0/22 ~all"
    

An alternative is to NOT allow all your hosts to send email directly. Set up one or more servers as dedicated mail relays and authorise only those in your SPF. All other servers you then configure to use those relays hosts.