is it dns? / wiki ← back to the live monitor

Reverse DNS: in-addr.arpa and ip6.arpa

Reverse DNS is the IP-to-name lookup. It's the part of DNS that looks weird the first time you see it, because the zones have names like 53.100.51.198.in-addr.arpa instead of example.com. The structure is fine. It's the ergonomics of ip6.arpa that hurt.

Why reverse DNS exists#

Forward DNS asks: "What's the address of example.isitdns.net?": a name in, an address out.

Reverse DNS asks the other direction: "Who lives at 198.51.100.53?": an address in, a name out. Used by:

  • mail servers verifying that the connecting IP has matching forward/reverse records (the "FCrDNS check": see ptr for how FCrDNS asymmetry breaks mail delivery)
  • SSH log enrichment (sshd reverse-resolves the connecting client when UseDNS is enabled; note it defaults to no in modern OpenSSH, precisely because a slow PTR lookup delays logins)
  • spam scoring (mail from a host with no PTR is suspicious)
  • observability tooling labeling traffic by host name instead of IP
  • humans reading tcpdump output without going cross-eyed

The DNS protocol has exactly one way to do this: define a special domain tree where every IP address is encoded as a name, and resolve it the normal way.

The in-addr.arpa tree (IPv4)#

The IPv4 address 198.51.100.53 becomes the DNS name:

53.100.51.198.in-addr.arpa
 |   |   |   |  +--------- the reverse-DNS root for IPv4
 |   |   |   +------------ most-significant octet
 |   |   +---------------- next octet
 |   +-------------------- next octet
 +------------------------ least-significant octet (the host)

The octets are reversed so the DNS hierarchy walks the same way it does for forward names: most-general on the right, most-specific on the left. The root delegates arpa, which delegates in-addr.arpa, which delegates 198.in-addr.arpa, and so on. For RFC 1918 private space (10/8, 172.16/12, 192.168/16) the public tree dead-ends on purpose: IANA delegates those reverse zones to the AS112 blackhole servers, which serve them as empty zones (NXDOMAIN for every address), and RFC 6303 tells recursive resolvers to answer them locally with NXDOMAIN without asking anyone. So on a private network you stand up your own reverse zone. See ip-address-spaces for the full breakdown.

The shorthand form, letting dig handle the name reversal:

dig -x 198.51.100.53

What it actually sends on the wire:

dig 53.100.51.198.in-addr.arpa PTR

198.51.100.x is one of the three RFC 5737 documentation prefixes (TEST-NET-2). It has no reverse zone, so these commands return NXDOMAIN. They are shown here only to illustrate the name format. For a live working example, see the Quick check section below.

The shorthand form for nslookup:

nslookup 198.51.100.53

What it actually sends on the wire:

nslookup -type=PTR 53.100.51.198.in-addr.arpa

Both forms send a PTR query and return a PTR record. Every reverse zone also requires an SOA at the apex and NS records, just like any other zone. For classless sub-range delegations (RFC 2317), the parent /24 zone also uses CNAME records to redirect individual host queries to the delegated sub-zone.

The ip6.arpa tree (IPv6)#

Same idea, with twice as much pain. Each IPv6 address is 128 bits = 32 hex nibbles, and reverse DNS encodes one nibble per label, in reverse order. The address 2001:db8::1 becomes:

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa

Yes really. Thirty-two single-character labels. Plus ip6.arpa. That's the lookup name for 2001:db8::1.

Ouch, my eyes. This is why every reverse-DNS tool on the planet has a built-in formatter. You will never type these by hand. dig -x does it for you.

The shorthand form (using the RFC 3849 documentation prefix to illustrate the format):

dig -x 2001:db8::1

What hits the wire:

dig 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa PTR

2001:db8:: is the RFC 3849 documentation prefix. It has no reverse zone, so both commands return NXDOMAIN. These are shown to illustrate the nibble format, not as live lookups. For a working IPv6 PTR example, see the ptr page.

The shorthand form for nslookup:

nslookup 2001:db8::1

What hits the wire:

nslookup -type=PTR 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa

The two principles to remember:

  1. One nibble per label. Not one hex-byte (two nibbles) per label. One nibble.
  2. Reversed nibble order. Most-significant nibble of the original address ends up on the right.

That's it. The verbosity is the price of using the same delegation machinery as forward DNS.

Delegation: who's authoritative for what#

For IPv4:

RangeAuthoritative for the reverse zone
Public, allocated to your ISPUsually the ISP: call them if you want a custom PTR for your static IP
Public, allocated to you (BYOIP)You: your RIR (or the ISP/LIR you got the block through) delegated the relevant /24 (or smaller, via RFC 2317 classless delegation)
RFC1918 (10/8, 172.16/12, 192.168/16)You. The public zones (168.192.in-addr.arpa etc.) are delegated to the AS112 blackhole servers (blackhole-1.iana.org, blackhole-2.iana.org), which answer NXDOMAIN for everything, and most resolvers short-circuit them locally per RFC 6303. Stand up your own.
Link-local (169.254/16)No one usable: 254.169.in-addr.arpa points at the same blackhole servers, so these addresses never get real global reverse DNS

For IPv6 the analogous split applies. ULA space (fc00::/7) is yours to host; public allocations are usually delegated by your RIR.

The categorization of public, private, and documentation addresses, and why RFC 1918 reverse zones get treated differently, is covered in detail at ip-address-spaces.

RFC 2317: classless reverse delegation#

If your ISP delegates a /26 to you, the classful reverse zone (x.y.z.in-addr.arpa: a /24) doesn't line up. RFC 2317 defines a CNAME-based trick to delegate a sub-range. You don't need this for RFC 1918 space; you do need it if you're getting a small public allocation. The pattern shows up in customer environments more than home labs.

PTR records inside any reverse zone are documented on the PTR page, including the FCrDNS gotchas that trip up mail delivery.

Quick check that reverse is working#

Pick an IP you know has a PTR record. Cloudflare's 1.1.1.2 works reliably, and unlike 1.1.1.1 its reversal is visible (1.1.1.2 becomes 2.1.1.1.in-addr.arpa):

dig @1.1.1.1 -x 1.1.1.2 +short
security.cloudflare-dns.com.

With nslookup:

nslookup 1.1.1.2 1.1.1.1
2.1.1.1.in-addr.arpa	name = security.cloudflare-dns.com.

Authoritative answers can be found from:

Exact framing varies by nslookup build: current BIND 9.18 nslookup prints just the answer for the by-IP form, while other builds add a Server: banner and a Non-authoritative answer: line first, as in the next example. The answer line is the part that matters.

Or query the reverse name directly:

dig @1.1.1.1 2.1.1.1.in-addr.arpa PTR +short
security.cloudflare-dns.com.
nslookup -type=PTR 2.1.1.1.in-addr.arpa 1.1.1.1
Server:		1.1.1.1
Address:	1.1.1.1#53

Non-authoritative answer:
2.1.1.1.in-addr.arpa	name = security.cloudflare-dns.com.

Authoritative answers can be found from:

Failure modes to distinguish:

  • NXDOMAIN: the reverse zone exists and is authoritative, but no PTR is provisioned for that IP. (Also what you get for RFC 1918 and documentation addresses, per the delegation table above.)
  • SERVFAIL: the reverse zone delegation is broken (missing or misconfigured NS/glue), DNSSEC validation failed, or the resolver gave up trying to reach the authoritative servers. A resolver that cannot reach the authoritative side reports SERVFAIL to you; it does not go silent.
  • Timeout: your query never got any answer at all, which points at the path between you and the resolver, not the authoritative side. Start at the L3 path to the resolver.

See also#