Yes you can publish IP-address ranges and subnets in DNS records but there is, as far as I know, not a dedicated and established DNS resource record type to represent IP-address ranges.
So people typically resort to using TXT records for that.
A common example of how that is done is how SPF uses TXT records to among others publish the IP’s and subnets that a domain owner expects to be used for sending their e-mail.
A good example is the _spf.google.com
record that references _netblocks.google.com
and several additional TXT 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"
The difference with SPF is that all mail servers (that support SPF) understand and implement the same parsing rules for the policy that a domain owner publishes in DNS for their domain, and such a standard does not exist (yet) for firewall access rules.
Your suggestion of putting in several A and/or AAAA records as a round-robin record also has merit (although that becomes slightly cumbersome if you need to write out an entire subnet in its constituent IP-addresses)
The problem for both approaches is that firewalls don’t have built in support to properly load the IP’s you publish in DNS and when they do, they may not properly update their policy when you make changes to the DNS records.
Many firewalls already accept a FQDN but will only lookup the associated IP and/or IP-addresses once, when the rule is loaded. (Linux iptables for example will correctly load all IP’s when the FQDN is a round-Robin record.) The firewall will then internally continue to use the discovered IP-address(es). The firewall won’t do a new lookup until the firewall appliance gets restarted and or the rule base gets reloaded. Most current firewalls don’t honor the TTL on Dns records and when the FQDN gets updated the firewall won’t update the IP’s they use within a predictable interval
Doing DNS lookups is relatively slow and a firewall can’t perform a DNS lookup every time a packet / connection needs to be checked against an active firewall rule. Remember: that connection, that IP packet only contains numeric IP data i.e. the source & destination IP-address and Port numbers. hence that FQDN’s get stored as IP-addresses in the active rule set.
I was on mobile before and just tested a Linux firewall with iptables
:
Adding rules with a FQDN is fully supported.
The FQDN gets resolved to an IP-address by iptables
and the resolved IP is what will be used in the effective rule base.
When the FQDN is a round-robin DNS record, iptables
will add several rules, one each for every one of the IP's in that round-robin DNS record.
(so far so good, right)
Saving the firewall rule set with iptables-save
does NOT revert the resolved IP-addresses back to a FQDN.
That implies that after a reboot, my server will NOT pick any changes that were made in the FQDN. If gateway.example.com
initially points to 192.0.2.1 and 192.0.2.2 and for example changes to 192.0.2.1 and 192.0.2.5 , my server will simply restore rules with the IP's 192.0.2.1 and 192.0.2.2. The new round-robin record in gateway.example.com
192.0.2.5 does not get added and 192.0.2.2 won't be removed.
Create the test records
round-robin.example.com. 349 IN A 192.0.2.2
round-robin.example.com. 349 IN A 192.0.2.1
round-robin.example.com. 349 IN A 192.0.2.4
Followed by iptables -A INPUT -p tcp --dport 22 --source round-robin.example.com -j ACCEPT
iptables -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
...
ACCEPT tcp -- 192.0.2.4 anywhere tcp dpt:ssh
ACCEPT tcp -- 192.0.2.2 anywhere tcp dpt:ssh
ACCEPT tcp -- 192.0.2.1 anywhere tcp dpt:ssh
iptables-save |grep 22
-A INPUT -s 192.0.2.4/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 192.0.2.2/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 192.0.2.1/32 -p tcp -m tcp --dport 22 -j ACCEPT