What to request when you're requesting (reverse DNS)
This is a story about requesting reverse DNS.
Put yourself in my shoes; imagine your ISP gave you a static IPv4 address (meaning a /32 “range”) and a hopefully larger IPv6 range (in my case a /56).
You now want your very own, cool, reverse DNS, self-hosted of course.
IPv6
For IPv6 this usually is not a problem if your ISP is complicit.1 Just reverse the range you have, set up a zone with your favorite DNS provider and write a nice email to your ISP:
Dear ISP, can you please add the following DNS records in your IPv6 rDNS setup?
In my case, for my range 2a00:6340:2044:200::/56 I had to ask them for the following entries:
$ORIGIN 0.4.3.6.0.0.a.2.ip6.arpa.
2.0.4.4.0.2.0.4.3.6.0.0.a.2.ip6.arpa. IN NS ns1.homecloud.lol.
2.0.4.4.0.2.0.4.3.6.0.0.a.2.ip6.arpa. IN NS ns1.famfo.xyz.
2.0.4.4.0.2.0.4.3.6.0.0.a.2.ip6.arpa. IN NS ns2.famfo.xyz.
2.0.4.4.0.2.0.4.3.6.0.0.a.2.ip6.arpa. IN NS miyuki.sakamoto.pl.
2.0.4.4.0.2.0.4.3.6.0.0.a.2.ip6.arpa. IN NS sakamoto.pl.
Parallel to this, I created the 2.0.4.4.0.2.0.4.3.6.0.0.a.2.ip6.arpa. zone on the servers listed above and added some fun entries.
I got the size of the $ORIGIN by running a dig +trace -x on the IPv6 range and seeing what they provide, but you should be able to leave this blank and have the ISP figure it out.
IPv4
This was the easy part, but due to its age, IPv4 won’t be as trivial.
The issue is, since most IPv4 ranges don’t fall on the octet boundaries (i.e. are not /8, not /16 and not /24), it is not trivial to add NS records without also delegating the rDNS for IP addresses that are not yours. While a /32 does technically fall on an octet boundary, you cannot add NS records to the single IP address, otherwise the resolver will just get NS records back and not a PTR record. You could ask the ISP for a PTR record directly, but then you cannot change it yourself the next time and also that would be boring when RFC 2317 exists.
This RFC specifies a best practice on how to do it that should work without any special implementations in the logic of the resolver or the authoritative servers.
Let’s tackle this with an example, with my IPv4 address 45.11.248.94.
The trivial, non-self-service case would be requesting something like:
$ORIGIN 248.11.45.in-addr.arpa.
94 IN PTR example.com.
For the reasons listed above, we want to solve this properly. The way RFC 2317 specifies is adding a CNAME to each and every IP address pointing to a label for the subnet you want to delegate:
$ORIGIN 248.11.45.in-addr.arpa.
94/32 IN NS ns1.homecloud.lol.
94/32 IN NS ns1.famfo.xyz.
94/32 IN NS ns2.famfo.xyz.
94/32 IN NS miyuki.sakamoto.pl.
94/32 IN NS sakamoto.pl.
94 IN CNAME 94.94/32.248.11.45.in-addr.arpa.
Since I only have a single IPv4 right now, I only have to specify one (1) CNAME, pointing to a label named 94/32, which reads as “a /32-sized subnet starting from address 94”.
On your authoritative DNS side you now create a zone called 94/32.248.11.45.in-addr.arpa. 2 and can put the PTR record for 94.94/32.248.11.45.in-addr.arpa. inside it.
Also note that some ISP infra and some authoritative DNS infra does not support slashes in DNS labels, which is why it is often (like in this case) being replaced by a minus sign.
What happens when resolving this is the recursor requesting the rDNS record for 94.248.11.45.in-addr.arpa, being told (via CNAME) to check 94.94-32.248.11.45.in-addr.arpa. instead, then walking down this hierarchy again to see that 94-32.248.11.45.in-addr.arpa. has been delegated to cool, new authoritative DNS servers and finding the appropriate PTR record there.
Here’s a DNS trace to visualize this:
;merlin@sakamoto:~ % dig -x 45.11.248.94 +trace
; <<>> DiG 9.20.22 <<>> -x 45.11.248.94 +trace
;; global options: +cmd
. 87203 IN NS h.root-servers.net.
. 87203 IN NS m.root-servers.net.
. 87203 IN NS b.root-servers.net.
. 87203 IN NS c.root-servers.net.
. 87203 IN NS d.root-servers.net.
. 87203 IN NS k.root-servers.net.
. 87203 IN NS f.root-servers.net.
. 87203 IN NS j.root-servers.net.
. 87203 IN NS a.root-servers.net.
. 87203 IN NS l.root-servers.net.
. 87203 IN NS e.root-servers.net.
. 87203 IN NS i.root-servers.net.
. 87203 IN NS g.root-servers.net.
. 87203 IN RRSIG NS 8 0 518400 20260619050000 20260606040000 54393 . PqFeApG7UMGyIaAQMrdvF1BBSbp2OVpohiaQV9Gd0bjjbhy7QeBQPVeM zy4jDucwSwy9OEpi8OAAkBanwxaQH3bGk9uLiJGWS88ci24LELPPh4kl IjcCf886Me7oLVs1Y2DJNJr6cS3Wpiy6+wLDohvuqF9DI8aK0vlOPPY0 l6jYISIraw2O5hD0HXo9RPOBwfk5ZwHSu79nTgIuSdpc2b119OvUulgX GvO2r9+L6zUaULnnsb4ULENq/j2NganEH14d5vqnZxFpdlw+/nhbPXnJ 65JVqzkqoW8X1c5PO1GrhihpnDbmFJfWlPZRUjNSda1ePS/PVg9J52Ge xWISvg==
;; Received 525 bytes from 127.0.0.1#53(127.0.0.1) in 1 ms
in-addr.arpa. 172800 IN NS a.in-addr-servers.arpa.
in-addr.arpa. 172800 IN NS b.in-addr-servers.arpa.
in-addr.arpa. 172800 IN NS c.in-addr-servers.arpa.
in-addr.arpa. 172800 IN NS d.in-addr-servers.arpa.
in-addr.arpa. 172800 IN NS e.in-addr-servers.arpa.
in-addr.arpa. 172800 IN NS f.in-addr-servers.arpa.
in-addr.arpa. 86400 IN DS 47054 8 2 5CAFCCEC201D1933B4C9F6A9C8F51E51F3B39979058AC21B8DF1B1F2 81CBC6F2
in-addr.arpa. 86400 IN DS 53696 8 2 13E5501C56B20394DA921B51412D48B7089C5EB6957A7C58553C4D4D 424F04DF
in-addr.arpa. 86400 IN DS 54956 8 2 E0E2BF5CFBD66572CA05EC18267D91509BA6A9405AF05C3FD4141DFA 45200C08
in-addr.arpa. 86400 IN DS 63982 8 2 AAF4FB5D213EF25AE44679032EBE3514C487D7ABD99D7F5FEC3383D0 30733C73
in-addr.arpa. 86400 IN RRSIG DS 8 2 86400 20260619060000 20260606050000 53731 arpa. EI3dCLaxqSwmVFImi8N2T1+qx/voflrycoGViCjoftHfXgB1ijIImlxb HpXFNSBSQLhzpiMEpODs+9RHduymaU09WmSariskQ12PpE3QB+3a5VFD hG2/4gid3VNA2iAmOrCDfDiBG4odSIhk2VmeMm/MHtMSZRjISc5rGng3 SqH9GZtb+JB/F+rUWA5c2q2b9IcPy5G+uS00iy7f33lHzdiDW9+ebTr6 pWP5TrFDR8s/Lqg2L45WC5sm0cMlzVEa5OOStHrwkGs7zvagQ7FsafSm CkdviRF9NleAcA5BlaJ5IOMJSHerVSW+5IRJFR67dMvWTGpr5deUSN9n FCFLPg==
;; Received 914 bytes from 199.7.83.42#53(l.root-servers.net) in 11 ms
45.in-addr.arpa. 86400 IN NS r.arin.net.
45.in-addr.arpa. 86400 IN NS u.arin.net.
45.in-addr.arpa. 86400 IN NS x.arin.net.
45.in-addr.arpa. 86400 IN NS y.arin.net.
45.in-addr.arpa. 86400 IN NS z.arin.net.
45.in-addr.arpa. 86400 IN NS arin.authdns.ripe.net.
45.in-addr.arpa. 86400 IN DS 29152 8 2 7FB94BA4B585474CF83364283789420CE8EE1EAED724AAFE14151E91 976E5575
45.in-addr.arpa. 86400 IN RRSIG DS 8 3 86400 20260618201025 20260529020847 37731 in-addr.arpa. Qbx5LDfJqxNOfVQTKCGQ0iNh/HBfvvePqvPZlG6GabrYiRjXfvYX5pyR /pPYj0abjaXbhiztmFm0kRQdlp/NwWP7D/2VXIeDDaM8qOKAOJWJHpIU M4mSuqSu1foTAZjXv9hX0qBR3wXx1EEMTQ7U4Z4opk/osu93BpavHi36 0eI=
;; Received 394 bytes from 2001:500:87::87#53(b.in-addr-servers.arpa) in 23 ms
248.11.45.in-addr.arpa. 86400 IN NS ns2.pcdog.ch.
248.11.45.in-addr.arpa. 86400 IN NS ns4.pcdog.ch.
248.11.45.in-addr.arpa. 86400 IN NS ns1.pcdog.ch.
248.11.45.in-addr.arpa. 86400 IN NS ns3.pcdog.ch.
248.11.45.in-addr.arpa. 3600 IN DS 26712 14 2 78A96F35307E83BE04ED5182614B3315DAE6E8A9F2DADB0050651FEA C193D38D
248.11.45.in-addr.arpa. 3600 IN RRSIG DS 8 5 3600 20260620162830 20260606152830 18639 45.in-addr.arpa. a7e0A3u9zxJ5lyIihIuSfxT+x0uCXPn/3NMzATKE1yE81zN9jWsXhaZl AWxURYyST3zRH8DFhcf97wdRfknE3iURblrZOag1Vx0Ss3tMTicBPK3c HbGec7tYA1EHGzytz7BsP+A3Hd2X4eI5O7nmGERRRBpCRJxr9dd8BfaS g0g=
;; Received 385 bytes from 199.180.180.63#53(r.arin.net) in 157 ms
94.248.11.45.in-addr.arpa. 38400 IN CNAME 94.94-32.248.11.45.in-addr.arpa.
94.248.11.45.in-addr.arpa. 38400 IN RRSIG CNAME 14 6 38400 20260705194403 20260605194403 26029 248.11.45.in-addr.arpa. vCG6Wk3/Nu6gEcjWEnH5Bvatmu6fjiZzEVOxLIUNH36Oew9hxPcF9dbC b7LiextV43CL5I4wAXbpM9A065z4TXuR3qcqe8gJZa9kGExWwrIEDNzy kvXMoM7llXb2PYtU
94-32.248.11.45.in-addr.arpa. 38400 IN NS nsr1.scholz.ruhr.
94-32.248.11.45.in-addr.arpa. 38400 IN NS nsr2.scholz.ruhr.
94-32.248.11.45.in-addr.arpa. 38400 IN NS nsr3.scholz.ruhr.
94-32.248.11.45.in-addr.arpa. 38400 IN NS nsr4.scholz.ruhr.
5M17TUQRHDVV9ABHO6NV4CTQNE8RG3ON.248.11.45.in-addr.arpa. 38400 IN NSEC3 1 0 0 - 83IJHAT45SU1I3CFFN7CS4HPPO4DOF3L NS
5M17TUQRHDVV9ABHO6NV4CTQNE8RG3ON.248.11.45.in-addr.arpa. 38400 IN RRSIG NSEC3 14 6 38400 20260705194403 20260605194403 26029 248.11.45.in-addr.arpa. j2jFJKV8/GgG3HyBOK2eF3p4olLPEn34NGCrqHJOPcVM4pAAcqWB2Dw5 t/oACMy/SidGvSTMGUNbp0/WsIDR+a7jok0rVTukH7/YzHxdONniTamB hrOx+cVQZ4DgZDZu
;; Received 566 bytes from 2a00:1828:2000:568::53#53(ns2.pcdog.ch) in 38 ms
;merlin@sakamoto:~ % dig -x 45.11.248.94
; <<>> DiG 9.20.22 <<>> -x 45.11.248.94
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62473
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;94.248.11.45.in-addr.arpa. IN PTR
;; ANSWER SECTION:
94.248.11.45.in-addr.arpa. 21600 IN CNAME 94.94-32.248.11.45.in-addr.arpa.
94.94-32.248.11.45.in-addr.arpa. 3600 IN PTR northstar.scholz.ruhr.
;; Query time: 210 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sat Jun 06 18:33:07 CEST 2026
;; MSG SIZE rcvd: 112
The reason the actual PTR record is not displayed in the first request is that dig does not follow CNAMEs when running a trace.
-
My ISP of choice usually is, if they aren’t too annoyed by the Deutsche Bahn to think properly ↩︎
-
You may have to prove ownership of the domain which can be difficult for reverse DNS. If you are with Servfail you can just ask in the IRC and we will happily add it to your account. ↩︎