Delegating the reverse zone of a subnet smaller than /24 in BIND. How it works

Once I faced a task of granting one of the clients permission to edit PTR records for the subnet /28 assigned to them. I don't have automation for editing BIND settings externally. So, I decided to take a different approach – delegating a piece of the PTR zone for the /24 subnet to the client.

It might seem simple – just specify the subnet correctly and point it to the necessary NS as you do with a subdomain. But no. It's not that easy (in reality, it's quite primitive, but intuition won't help), which is why I'm writing this article.

For those who want to figure it out themselves, you can read this. RFC
For those who want a ready-made solution, welcome below the cut.

To not keep those who love the copy-paste method waiting, I'll first place the practical part and then the theoretical one.

1. Practice. Delegating the /28 zone.

Let's assume we have a subnet. 7.8.9.0/24We need to delegate the subnet 7.8.9.240/28 to the DNS client 7.8.7.8 (ns1.client.domain.).

On the provider's DNS, you need to find the file that describes the reverse zone for this subnet. Let's say it's 9.8.7.in-addr.arpa..
Comment out records from 240 to 255 if they exist. And at the end of the file, write the following:

255-240  IN  NS      7.8.7.8
$GENERATE 240-255 $ CNAME $.255-240

don't forget to increase the zone serial and perform

rndc reload.

That's it for the provider part. Let's move on to the client DNS.

First, we create the file. /etc/bind/master/255-240.9.8.7.in-addr.arpa with the following content:

$ORIGIN 255-240.9.8.7.in-addr.arpa.
$TTL 1W
@                       1D IN SOA       ns1.client.domain. root.client.domain. (
                        2008152607      ; serial
                        3H              ; refresh
                        15M             ; retry
                        1W              ; expiry
                        1D )            ; minimum
@                       IN NS        ns1.client.domain.
@                       IN NS        ns2.client.domain.
241                     IN PTR          test.client.domain.
242                     IN PTR          test2.client.domain.
245                     IN PTR          test5.client.domain.

And in named.conf, add the description of our new file:

zone "255-240.9.8.7.in-addr.arpa." IN {
        type master;
        file "master/255-240.9.8.7.in-addr.arpa";
};

Now we restart the BIND process.

/etc/init.d/named restart

That's it. Now we can check.

#>  host 7.8.9.245 
245.9.8.7.in-addr.arpa is an alias for 245.255-240.9.8.7.in-addr.arpa.
245.255-240.9.8.7.in-addr.arpa domain name pointer test5.client.domain.

Note that not only the PTR record is returned, but also the CNAME. This is how it should be. If you're curious why, then welcome to the next chapter.

2. Theory. How it works.

It's difficult to configure and debug a black box. It's much easier if you understand what's happening inside.

When we delegate a subdomain in the domain domain,, we write something like this:

client.domain.	NS	ns1.client.domain.
ns1.client.domain.	A	7.8.7.8

We tell everyone who asks that we are not responsible for this particular area and inform them who is responsible. All requests for client.domain are redirected to 7.8.7.8. When we check, we see the following picture (let's skip what's there with the client, it's not important):

# host test.client.domain
test.client.domain has address 7.8.9.241

That is, we were informed that there is such an A record and its IP is 7.8.9.241. No extra information.

How can the same thing be done with a subnet?

Since our DNS server is registered in RIPE, when a PTR request is made for an IP address in our network, the first request will still be directed to us. The logic is the same as with domains. But how do we write the subnet in the zone file?

We try to write it like this:

255-240  IN  NS      7.8.7.8

And… nothing miraculous happened. We do not receive any request redirection. The thing is that bind is not aware that these records in the reverse zone file are IP addresses and, even more so, it does not understand the range record. To it, this is just some symbolic subdomain. So, for bind, there is no difference between "255-240" and "oursuperclient". And for the request to go where it should, the address in the request must look like this: 241.255-240.9.8.7.in-addr.arpa. Or like this if we use a symbolic subdomain: 241.oursuperclient.9.8.7.in-addr.arpa. This is different from the usual: 241.9.8.7.in-addr.arpa.

Doing such a request manually would be problematic. And even if it is possible, it's still unclear how to apply it in real life. After all, for the request, 7.8.9.241 we still get a response from the provider's DNS, not the client's.

And here comes into play CNAME.

On the provider's side, an alias needs to be created for all IP addresses of the subnet in a format that will redirect requests to the client's DNS.

255-240  IN  NS      ns1.client.domain.
241     IN  CNAME   241.255-240
242     IN  CNAME   242.255-240
and so on.

This is for the hard workers =).

And for the lazy ones, a construction below is more suitable:

255-240  IN  NS      ns1.client.domain.
$GENERATE 240-255 $ CNAME $.255-240

Now, the information request for the address 7.8.9.241 from 241.9.8.7.in-addr.arpa on the provider’s DNS server will be transformed into 241.255-240.9.8.7.in-addr.arpa and will be sent to the DNS client.

On the client’s side, such requests need to be processed. Accordingly, we create a zone 255-240.9.8.7.in-addr.arpa. In it, we can basically place reverse records for any IP in the entire /24 subnet, but we will only be asked about those that the provider redirects to us, so we won't get to play around =).
To illustrate, I will again provide an example of the contents of the reverse zone file from the client's side:

$ORIGIN 255-240.9.8.7.in-addr.arpa.
$TTL 1W
@                       1D IN SOA       ns1.client.domain. root.client.domain. (
                        2008152607      ; serial
                        3H              ; refresh
                        15M             ; retry
                        1W              ; expiry
                        1D )            ; minimum
@                       IN NS        ns1.client.domain.
@                       IN NS        ns2.client.domain.
241                     IN PTR          test.client.domain.
242                     IN PTR          test2.client.domain.
245                     IN PTR          test5.client.domain.

This is because we use CNAME on the provider side, which is why we receive two records in response to the data request. IP address two records instead of one.

#>  host 7.8.9.245 
245.9.8.7.in-addr.arpa is an alias for 245.255-240.9.8.7.in-addr.arpa.
245.255-240.9.8.7.in-addr.arpa domain name pointer test5.client.domain.

And don't forget to correctly configure the ACL. Because it's pointless to claim the PTR zone and not respond to anyone from the outside =).

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster