abstract image of blue color
Blog Farsight TXT Record

Going From An IP Address to A Fully Qualified Domain Name (FQDN) In DNSDB

I. Introduction

In the first article from this series (see Going From A Domain Name to IP Address in DNSDB: Some “Pro Tips” To Keep In Mind ) we started with a fully qualified domain name (FQDN) and talked about using DNSDB to resolve that FQDN to its IP address. Normally that’s a pretty straightforward process, but in some cases, we may run into some less straightforward answers. We discussed some of the most common examples of those, and explained how to handle them.

In this article, we’re going to go “the other direction,” and talk about using DNSDB to go from an IP address to a FQDN. Again, this is often quite straightforward, but we wanted to make sure that you’re ready for the times when you might end up going through some “chicanes.”

II. The Most Straight Forward Case: An IPv4 Address That Maps To A Single Domain Name

Let’s start with a simple example using Farsight Security’s command line DNSDB client, dnsdbq (see https://github.com/dnsdb/dnsdbq ).

We’re going to assume that you’ve already got it installed on your system, and that you’ve also purchased and received a DNSDB API key that will allow you to make queries.

Imagine we’ve stumbled across the IP address 129.72.61.236. Checking DNSDB using dnsdbq, we can see that that IP address resolves to a single fully qualified domain name, and has done so since at least November 19th, 2010:

$ dnsdbq -i 129.72.61.236
;; record times: 2010-11-19 14:36:04 .. 2021-09-20 22:30:02 (~10y ~308d)
;; count: 33551
jobs.uwyo.edu.  A  129.72.61.236

Decoding that command, we’re simply asking dnsdbq to

  • Search the “right hand side” of the resource records in its database for the IP address 129.72.61.236.

We should mention that while we used the popular dnsdqb command line interface for this query, we could just as easily have made the same query using Farsight’s point-and-click web interface to DNSDB, DNSDB Scout.

As shown by that single result, no other domain names have been seen using that IP address by DNSDB’s sensors.

Moreover, by looking up the jobs.uwyo.edu domain name in DNSDB, we can confirm that that’s the ONLY IP address that FQDN has used:

$ dnsdbq -r jobs.uwyo.edu
;; record times: 2010-11-19 14:36:04 .. 2021-09-20 22:30:02 (~10y ~308d)
;; count: 33551; bailiwick: uwyo.edu.
jobs.uwyo.edu.  A  129.72.61.236

Decoding that command, this time we’re asking DNSDB to

  • Search DNSDB RRnames (the “left hand side” of DNS resource records) for the specified domain name.

The substantive result? A beautifully simple and symmetric case: 129.72.61.236 –> jobs.uwyo.edu –> 129.72.61.236

If we wanted to, we could also check to see what we see in the “regular” or “live” DNS by using the dig command (dig may be preinstalled on some operating systems, available as part of a dnsutils package from your favorite package manager, or come as a utility bundled with BIND, see https://www.isc.org/bind/ ):

$ dig -x 129.72.61.236 +short
jobs.uwyo.edu.
$ dig jobs.uwyo.edu +short
129.72.61.236

As you become familiar with dig, note that:

  • dash x is used when making a dig query for an IP address
  • plus short tells dig we want “brief” output (just the basic result)

The output we see above confirms that the “live” DNS agrees with what we’ve seen in DNSDB for this simple example.

Note: The example shown above in this part refers to a single IPv4 address (129.72.61.236), but we can also make DNSDB queries for IPv6 addresses (such as 2604:a880:400:d0::20a3:d001), dash-separated arbitrary IP address ranges (such as 128.223.32.4-128.223.35.121) and CIDR address blocks (such as 104.244.12.0/22) as discussed in https://www.farsightsecurity.com/blog/txt-record/CIDR-20180601/ .

For the pedagogical purposes of this article, we’ll typically just continue to show individual addresses in our examples below.

III. Sometimes IP Addresses May Not Be Associated With ANY Domain Name

An IP address is not “guaranteed” to always be associated with a domain name. So checking another randomly chosen IP, 129.72.61.9, we can see that dnsdbq has no results for that DNSDB IP address query:

$ dnsdbq -i 129.72.61.9
Query status: NOERROR (no results found for query.)

This can mean one of several things:

  • The IP address may simply not be in use by a computer or other device.
  • The IP address may be getting used “raw,” without the convenience of using a domain name.
  • The IP address may be in use (and may even have DNS), but we may not have seen any traffic for it from any of our sensors worldwide.
  • We may have seen traffic involving that IP, but we may have filtered it from DNSDB for one reason or another.

IV. An IP Address May Be Associated With Multiple Domains At the Same Time: The Shared Hosting Case

We’ve talked about IPs that are associated with a single domain, and IPs that aren’t associated with ANY domain. Now let’s talk about IPs that may be associated with multiple domains at the same time.

This is quite common for shared web-hosting scenarios, where a single server with a single IP address can easily and inexpensively host hundreds or even thousands of domains.

For example, hypothetically assume we became interested in the IP address 92.204.136.134

If we check Whois, we can see that this is a GoDaddy-related IP address:

$ whois 92.204.136.134
[...]
inetnum:        92.204.128.0 - 92.204.143.255
netname:        GDY-US-EAST
country:        US
admin-c:        GDDY
tech-c:         GDDY
abuse-c:        AR16180-RIPE
status:         SUB-ALLOCATED PA
mnt-by:         GODADDY-MNT
created:        2020-02-20T08:24:24Z
last-modified:  2020-02-20T08:33:37Z
source:         RIPE # Filtered

role:           GoDaddy LIR
address:        GoDaddy
​[etc]

But what domain names are associated with that IP address? Are the domains all ones that GoDaddy itself has? No, this is an IP address used by GoDaddy’s customers.

Sorting the domains associated with that IP (in descending order by count), and limiting ourselves to FQDNs seen within the last thirty days, some of our results look like the following:

$ dnsdbq -i 92.204.136.134 -S -k count -A30d
;; record times: 2021-05-25 20:43:02 .. 2021-09-21 06:17:34
;; count: 10191
ns1.gomontessori.com.  A  92.204.136.134

;; record times: 2021-05-25 20:43:02 .. 2021-09-21 06:17:34
;; count: 10183
ns2.gomontessori.com.  A  92.204.136.134

;; record times: 2021-04-03 15:03:32 .. 2021-09-21 04:04:21
;; count: 7080
arcadiabio.com.  A  92.204.136.134

;; record times: 2021-04-03 14:02:30 .. 2021-09-21 11:45:35
;; count: 5844
amgassociatesinc.com.  A  92.204.136.134

;; record times: 2021-04-15 18:01:23 .. 2021-09-21 10:17:58
;; count: 5540
springsmontessori.com.  A  92.204.136.134

;; record times: 2021-04-12 20:00:12 .. 2021-09-21 17:07:27
;; count: 4691
khalsamontessorischool.com.  A  92.204.136.134

;; record times: 2021-04-06 01:45:08 .. 2021-09-21 02:22:27
;; count: 3260
bloomingtonmontessori.org.  A  92.204.136.134

;; record times: 2021-05-01 21:03:41 .. 2021-09-21 11:41:10
;; count: 3117
yolocountysheriff.com.  A  92.204.136.134

;; record times: 2021-04-03 17:09:26 .. 2021-09-21 17:27:19
;; count: 3009
ranchoviejoschool.com.  A  92.204.136.134

;; record times: 2021-04-03 18:13:12 .. 2021-09-21 07:04:09
;; count: 2829
villagemontessoricenter.com.  A  92.204.136.134

;; record times: 2021-05-06 21:07:15 .. 2021-09-21 11:03:30
;; count: 2708
www.montessoripensacola.com.  A  92.204.136.134

;; record times: 2021-04-15 19:57:17 .. 2021-09-21 08:01:33
;; count: 2252
ssmsmontessori.net.  A  92.204.136.134
​[etc]

Decoding the preceding dnsdbq command:

  • Dash capital S sorts in descending order.
  • Dash kay count specifies that we should sort by the count field.
  • Dash capital A thirty dee specifies that we only want records seen over the last 30 days.

Note that the various domains (ranging from preschools to a sheriff’s department) were all observed using that same IP address over the same time interval — this IP address is apparently a shared one. IPv4 addresses are now in short supply and relatively expensive to obtain, so shared IPs are exceedingly common at large web hosting concerns, leveraging Server Name Indication (see https://datatracker.ietf.org/doc/html/rfc6066 ).

Without additional information (such as full packet captures of network traffic), we’d be hard pressed to say which (if any) of these hosts might have been associated with hypothetical traffic to/from 92.204.136.134 — a hypothetical connection to (or from) that IP could literally have been associated with any of the hosts mentioned, or any of the scores of other results we’ve elided in order to limit the length of this article.

V. IPs May Get Recycled and Reused Sequentially

We’ve just talked about multiple domains that may be interleaved on the same IP address at the same time. Another pattern we may see in DNSDB results may involve IPs that are assigned for use by one FQDN and then repurposed later for use by a completely different FQDN (much as a landlord will typically clean and re-rent each of his or her apartments to a new tenant after the former renter’s lease expires).

For example:

$ dnsdbq -i 128.223.42.146
;; record times: 2011-01-05 06:43:17 .. 2011-01-05 06:43:17 (1s)
;; count: 1
skipmcf.uoregon.edu.  A  128.223.42.146

;; record times: 2016-07-19 20:11:52 .. 2018-09-24 08:11:34 (~2y ~66d)
;; count: 45
esbl.uoregon.edu.  A  128.223.42.146

;; record times: 2019-01-13 23:04:08 .. 2021-09-14 11:18:51 (~2y ~244d)
;; count: 82
esblold.uoregon.edu.  A  128.223.42.146

The reality of this pattern underscores the importance of having a full timestamp (including time zone information) when using passive DNS to map IP addresses to domain names. Full timestamp information can be critical to ensuring we get the right host mapped to a given IP for a particular time (for the record, DNSDB’s own timestamps are always stored and displayed in UTC).

VI. Wildcards

Wildcards are another type of domain name we may encounter when resolving IP addresses in DNSDB. Wildcard domains are often defined as “catch all” resource records that will resolve literally any hostname that hasn’t already been defined by a more specific DNS resource record.

Our first clues that we may be running into an IP with wildcarded domains on it may be:

  • Finding a LOT of unique results (often tens of thousands (or even hundreds of thousands or more!) for individual delegation points)
  • All/most of the responses we’re looking at have small counts (often just 1 or 2 hits per unique result)
  • The hostname parts may look random, or may perhaps may have been chosen to be “amusing”
  • There may be multiple subdomains present between the hostname part and the base domain name part.

For example, let’s look at 72.52.10.14. That IP is part of a Prolexic netblock assigned to Akamai:

$ whois 72.52.10.14
[...]
NetRange:       72.52.0.0 - 72.52.63.255
CIDR:           72.52.0.0/18
NetName:        PROLEXIC
NetHandle:      NET-72-52-0-0-1
Parent:         NET72 (NET-72-0-0-0-0)
NetType:        Direct Allocation
OriginAS:       
Organization:   Akamai Technologies, Inc. (AKAMAI)
RegDate:        2005-07-11
Updated:        2019-10-21
​[etc]

How many unique results do we find for just that one IP over the last month? We may need to make several DNSDB queries to try to find out. Our first query:

$ dnsdbq -i 72.52.10.14 -A30d -l0 -j > part1.jsonl
$ wc -l part1.jsonl
1000000

Decoding that dnsdbq command:

  • The dash ell zero in the dnsdbq command asks for as many results as are permitted (e.g., up to a maximum of one million).
  • The dash jay option asks for our output to be delivered in JSON Lines format (see https://jsonlines.org/ ).
  • The greater than sign pointing at a file name puts the output from the preceding command into that file.
  • The Un*x wc dash ell command reports the number of lines found in the specified file.

We’ve now found that there are at least a million results for that one IP (a million results, as reported in this case, is the most results that DNSDB will return for any single query).

We can now check for additional results by “offsetting” into the total results known to DNSDB for this query, asking for three more slices of up to a million, for up to a maximum of 4 million total results. Doing this:

$ dnsdbq -i 72.52.10.14 -A30d -l0 -j -O1000000 > part2.jsonl
$ wc -l part2.jsonl
1000000
$ dnsdbq -i 72.52.10.14 -A30d -l0 -j -O2000000 > part3.jsonl
$ wc -l part3.jsonl
1000000
$ dnsdbq -i 72.52.10.14 -A30d -l0 -j -O3000000 > part4.jsonl
$ wc -l part4.jsonl
1000000

The preceding commands are quite similar to the original dnsdbq command we’ve previously explained, except for one new dnsdbq option:

  • Dash capital oh (followed by an integer) tells dnsdbq to jump forward (or “offset into the results”), by the specified number of observations.

So now we know that there are AT LEAST four million unique results associated with that IP from just the last month (there may be more results, but a total of four million results is the most we can extract for any given unique query).

Which of the domains seen using that IP have the largest number of unique hostnames? We can answer that question by extracting the names seen using jq (see https://stedolan.github.io/jq/ ) and some simple Un*x utility commands:

$ cat part[1234].jsonl | jq -r '.rrname' | 2nd-level-dom | sort | uniq -c | sort -nr > top-72.52.10.14.txt

$ more top-72.52.10.14.txt
 203561 demandware.hk
 183747 demandware.ca
 182558 demandware.net.cn
 178553 demandware.com.hk
 176860 cloudcraze.com.cn
 172321 exacttarget.cn
 171524 exacttarget.com.hk
 170666 ali-salesforce.cn
 168418 demandware.cc
 162489 commerceagility.cn
 162383 analytics.ai
 159063 commerceagility.hk
 156333 app-datorama.cn
 147332 buddymedia.cc
  66971 patreon.io
  54824 paypal-mobiletopup.ca
  49252 paypal-marketing.com.hk
  35472 paypal-press.fr
  33739 paypalqrshopping.de
  31161 paypalcreditcard.cn
  30840 paypal-shopping.co.il
  ​[etc]

Decoding the preceding commands:

  • cat part[1234].jsonl concatenates the four files (part1.jsonl, part2.jsonl, part3.jsonl, and part4.jsonl) together and sends the combined output onward to the next command
  • the vertical bar character pipes the output from the oreceding command into the next command in the pipeline
  • *jq -r ‘.rrname’ prints just the rrnames (without quotation marks, e.g., “raw”)
  • The 2nd-level-dom script leverages the Public Suffix List ( https://publicsuffix.org/ ), and can be found in Appendix III to this article It drops any “hostname” (or subdomain) parts that may be part of a name, leaving just the effective 2nd-level delegation point.
  • sort sorts the input it receives
  • uniq -c finds unique lines, and counts the number of times each unique line value is seen
  • sort -nr sorts the liens it receives in descending numeric order according to the first field
  • The more command lets us page through a text file screenful by screenful

Just based on the number of unique hostnames we’re seeing for even that small set of delegation points shown above, we’re pretty suspicious that something unusual is going on with those domain names — it would be quite atypical for a domain to have 100,000 (or more!) manually-assigned hostnames, unless we’re talking about a large corporation or a big university.

So let’s drill down on one of those delegation points, such as demandware.hk, and see what some of those hostnames look like (we’ll reverse them by label for output so we can easily group related domains next to each other).

Note: if the version of dnsdbq you’re using complains about the -T reverse,chomp subcommand, you may have an outdated copy of dnsdbq, and should update to the latest version from https://github.com/dnsdb/dnsdbq

$ dnsdbq -r \*.demandware.hk/A -l0 -A30d -T reverse,chomp -j | jq -r '.rrname' | sort
[...]
hk.demandware.0.test1-omsproxy-e6zyxw.comv2.comdev.google.www
hk.demandware.0.test.db.blogs.redirect
hk.demandware.0.testdjotrt.db.blogs.web
hk.demandware.0.test.nnxtplcpr.db.blogs.web
hk.demandware.0.th.co.0.dtac
hk.demandware.0.th.co.0.dtac-01
hk.demandware.0tljul7f8lk5tek.gazetazone
hk.demandware.0.tmpay
hk.demandware.0.traffic.team.jobs-bdjobs-com.univeryountselegorysistmall.idcjoy.webproxy.svc-panel
hk.demandware.0.try.12.rule.r0.infrastructurewww
hk.demandware.0.try.aws.rule.r0.q-2020-twitch.twitchabout
[...]
hk.demandware.1.sncf.office.com.exz-log-assets-publiclabs
hk.demandware.1.s.occ-0-1189-89
hk.demandware.1.southeast.ap.1622116411.07.miui.lb
hk.demandware.1.southeast.ap-umraniye.b.kms.zwb
hk.demandware.1.southeast.ashburn-ap.b.kms
hk.demandware.1.southeastasia.ca.gallery
hk.demandware.1.sru
hk.demandware.1.ssl.mail1-webdisk
hk.demandware.1.st6.eu5
hk.demandware.1.staff.8-5-248-103
hk.demandware.1st-annual-famil-1.www
hk.demandware.1.statichost148.loadbal.workspace.cnimt.appkeke.rule7rjqa-fec-prod-proxy.r0.0zyx3sandbox-docker-dev1
​[etc]

Everyone sees these things differently, but those names look pretty “random”/”janky” to us.

OK. Now as a final check, let’s trying to resolve a fake pseudorandom hostname of our own creation based on demandware.hk:

$ dig jjiojoiajsdoasd.demandware.hk +short
72.52.10.14

Our randomly chosen hostname successfully resolves! Our conclusion is that demandware.hk is indeed a wildcarded domain. You can check the other high-count domains mentioned above using a similar approach, if desired.

VII. People May Sometimes Point Their Domain Names At IPs They Don’t Control

A DNS administrator can accidentally (or intentionally!) point one of their domain names at an IP address they don’t actually control. DNSDB may see and index that, even though the IP that a name points at may have absolutely no locally-relevant connection to that IP. If you don’t understand this critical fact, it is easy to just about have a heart attack when you see unexpected passive DNS results for an IP address of interest.

For example, consider the domain name topology4.dyndns.atlas.ripe.net

If we check that domains in DNSDB, we’ll see that this domain resolves to a large number of unique IP addresses:

$ dnsdbq -p minimal -r topology4.dyndns.atlas.ripe.net/A -l0 > results.txt
$ dnsdbq -p minimal -r topology4.dyndns.atlas.ripe.net/A -l0 -O1000000 >> results.txt
$ sort -u results.txt > results2.txt
$ wc -l results2.txt
1031664 

In the above command:

  • greater than greater than (e.g., >>) means “append what you receive to the end of the potentially-pre-existing file specified.”

Looking at the results from those commands:

$ more results2.txt
[...]
128.134.97.1
128.135.0.1
128.135.255.1
128.136.0.1
128.136.104.1
128.136.110.1
128.136.112.1
128.136.113.1
128.136.120.1
128.136.128.1
128.136.137.1
128.136.143.1
128.136.144.1
128.136.146.1
128.136.151.1
128.136.152.1
128.136.156.1
128.136.158.1
128.136.16.1
128.136.160.1
128.136.164.1
128.136.168.1
​[etc]

If we now “double check” a few of those IPs in DNSDB, we’ll see topology4.dyndns.atlas.ripe.net show up in the results (as expected given the previous query):

$ dnsdbq -i 128.106.5.1
;; record times: 2019-05-02 00:48:50 .. 2021-09-15 08:54:32 (~2y ~137d)
;; count: 45
topology4.dyndns.atlas.ripe.net.  A  128.106.5.1

$ dnsdbq -i 128.136.112.1
;; record times: 2016-05-15 13:01:13 .. 2021-09-02 03:35:49 (~5y ~110d)
;; count: 75
topology4.dyndns.atlas.ripe.net.  A  128.136.112.1

$ dnsdbq -i 128.136.168.1
;; record times: 2016-12-05 23:36:10 .. 2021-09-23 01:23:10 (~4y ~292d)
;; count: 73
topology4.dyndns.atlas.ripe.net.  A  128.136.168.1

If we look at topology4.dyndns.atlas.ripe.net in the “live” DNS, we see an interesting behavior. Let’s query that name once:

$ dig topology4.dyndns.atlas.ripe.net
[...]
;; ANSWER SECTION:
topology4.dyndns.atlas.ripe.net. 0 IN	A	24.238.110.1

Notice the 0 TTL. That TTL=0 setting means that DNS entry will not be cached.

What do we see if we query the “live” DNS repeatedly for that name?

$ dig topology4.dyndns.atlas.ripe.net +short
109.236.60.1

$ dig topology4.dyndns.atlas.ripe.net +short
109.67.83.1

$ dig topology4.dyndns.atlas.ripe.net +short
194.63.66.1

Every time we query that name, we will get a new pseudo-random IP address from a different /24 netblock (each time ending with a last octet of dot 1). We believe that these addresses represent pseudo-randomly-generated probe targets for use by RIPE Atlas Internet measurement project sensors (see https://atlas.ripe.net/ ).

This ends up being a nice example of a domain name that may end up being seen in the results from many queries, where in fact the domain is NOT one that the owner of the IP might have expected to see. We routinely run into other domains of this sort, too.

The important thing to note is that the existence of a 3rd-party domain name does NOT mean that the system actually USING that IP has been “hacked” or “cracked.” Just because someone points a third-party domain name at an IP, that doesn’t mean that there’s anything “behind that IP” that will answer for connections to that third party domain name.

At some point in the future, Farsight may remove known names of this sort as part of its routine curation/filtering of DNSDB, to help preserve the signal-to-noise ratio of our data and to reduce DNSDB “pollution.”  

A final category of IP to domain name IPs we should discuss in this article involves:

  • “Localhost” IPv4 addresses from 127.0.0.0/8

  • IPv4 RFC1918 addresses from 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16

  • IPv4 addresses reserved for documentation per RFC5737 (192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24)

  • The IPv6 “loopback” address ::1/128

  • Link-local IPv6 unicast addresses from FE80::/10

  • IPv6 addresses reserved for documentation per RFC3849 (2001:DB8::/32)

These IPs were originally intended primarily for access to local systems or for other dedicated purposes (such as use in examples in documentation) ONLY, and as such, have no global reachability nor do they represent globally unique “real destinations:”

$ dnsdbq -i 127.0.0.0/8 -l0 -A90d -S -k count
[...]
;; record times: 2019-07-18 09:54:26 .. 2021-09-27 12:02:46 (~2y ~72d)
;; count: 998068
bt1.xxxxbt.cc.  A  127.0.0.1

;; record times: 2018-02-01 07:12:18 .. 2021-09-27 11:51:07 (~3y ~239d)
;; count: 948394
crypto.ibank.bveb.by.  A  127.0.0.1

;; record times: 2021-07-17 15:19:38 .. 2021-08-30 07:04:58 (~43d 15h 45m)
;; count: 924137
ns.westidc.net.cn.  A  127.0.0.1
​[etc]

$ dnsdbq -i FE80::/10 -l0 -A90d -S -k count
;; record times: 2020-08-06 12:44:30 .. 2021-09-27 07:51:04 (~1y ~51d)
;; count: 3645586
ns4.ultahost.com.  AAAA  fe80::5400:2ff:fe93:34e8

;; record times: 2020-10-09 12:15:07 .. 2021-09-09 14:35:25 (~335d 2h 20m)
;; count: 2816017
ads13.adtelligent.com.  AAAA  fe80::ec4:7aff:fe7e:de5e

;; record times: 2019-02-21 14:57:51 .. 2021-09-27 10:57:49 (~2y ~218d)
;; count: 2170905
ns5.claretianos.es.  AAAA  fe80::529a:4cff:fe74:2f2
​[etc]

Over time, some IPs from 127.0.0.8/8 have also ended up being repurposed for use as coded “signal” values for things like DNS-based blocklists. An example of a blocklist using coded values:

$ dnsdbq -i 127.0.0.5 -l0 -A90d
[...]
;; record times: 2021-06-27 15:34:29 .. 2021-06-29 20:55:02 (~2d 5h 20m)
;; count: 4
38.117.65.124.bl.blocklist.de.  A  127.0.0.5

;; record times: 2021-09-24 13:35:45 .. 2021-09-24 13:35:45 (1s)
;; count: 2
2.113.205.129.bl.blocklist.de.  A  127.0.0.5
​[etc]

The “semantics” of blocklist signal values (what the signal values “mean”) for any given blocklist is defined by the blocklist operator, and won’t necessarily be the same between any two given blocklists.

The point of calling out all these IP address ranges is that while we may encounter these sort of IPs in DNSDB, we should not expect to actually be able to “go to” the “systems” that these IPs might hypothetically refer to.

IX. Conclusion

We’ve now looked at seven different types of responses we may get for a DNSDB IP query:

  1. IP maps to just a single domain name
  2. IP doesn’t map to any domain name
  3. IP maps to multiple domains (at the same time)
  4. IP maps to multiple domains (sequentially)
  5. Wildcard domain IPs (IP maps to an unlimited number of FQDNs for a given delegation point)
  6. IPs that are associated with 3rd party domain names due to action by that 3rd party
  7. Loopback/Localhost/Documentation-Only/Link-Local/RFC1918 Addresses not representing actual globally-reachable systems.

Knowing about these different potential responses should help with interpretation of the responses seen from DNSDB when making IP address queries.

Appendix I. Querying DNSDB for Actual PTR (“Inverse Address”) Records

In part III of this blog article, we checked passive DNS for 129.72.61.9 and didn’t find any results. We can use the regular DNS dig utility to check the “live” DNS for a formal PTR (or “inverse address” record) for that IP.

PTR records may be used in the normal “live” DNS to formally establish a mapping from an IP address to a domain name.

$ dig -x 129.72.61.9 +short
​[nothing is returned as output for that command]

Note that PTR records will often NOT be defined for IPs (even if an IP is in active use), but from a DNSDB point of view, that’s okay — DNSDB does NOT rely solely on formal PTR records to infer IP to FQDN mappings.

The key to DNSDB’s indexing “magic?” If a DNSDB sensor observes a domain name resolving to an IP, we’ll record that fact, as we’d expect. HOWEVER, we’ll ALSO record the “reverse” association between that IP and the domain name that resolved to it, even if that relationship hasn’t been formally defined with a PTR record. Those are the relationships we’ll find when we make a dnsdbq -i query.

If we’d ever like to check DNSDB to see if we HAVE in fact seen a formal PTR record for an IP address of interest, we can also do that. Let’s try doing so for another IP, 142.251.33.68:

$ dnsdbq -r 68.33.251.142.in-addr.arpa/PTR
;; record times: 2021-08-10 00:24:20 .. 2021-09-21 05:03:58 (~42d 4h 39m)
;; count: 288; bailiwick: 251.142.in-addr.arpa.
68.33.251.142.in-addr.arpa.  PTR  sea09s28-in-f4.1e100.net.

;; record times: 2021-02-28 12:49:12 .. 2021-09-21 07:11:56 (~204d 18h 22m)
;; count: 19079; bailiwick: 33.251.142.in-addr.arpa.
68.33.251.142.in-addr.arpa.  PTR  sea09s28-in-f4.1e100.net.

Things to note about that query:

  • We’re making a -r (RRname) query, not a -i (IP Rdata) query because we’re searching the left-hand side of formally defined PTR records (we’re NOT just searching the right-hand side of “A” records)

  • To make a PTR query for an IPv4 address, we reverse the IPv4 address by label (so 142.251.33.68 becomes 68.33.251.142), and then we add the suffix .in-addr.arpa (since this is the formal notation used for IPv4 PTR records in zone files).

  • If we’re making PTR query for an IPv6 address, we reverse the IPv6 address “hex digit by hex digit” (so 2604:a880:400:d0::20a3:d001 becomes 1.0.0.d.3.a.0.2.0.0.0.0.0.0.0.0.0.d.0.0.0.0.4.0.0.8.8.a.4.0.6.2), and then we add the suffix .ip6.arpa (instead of .in-addr.arpa). Again, this notation follows the formal notation used for IPv6 PTR records in the DNS.

  • In our dnsdbq command, we show specifying /PTR for the RRType in our query (but we can normally just leave that part off)

  • We’ve received two “seemingly identical” results (as highlighted above), but in fact those ARE distinct and separately tracked results — they come from different places in the DNS hierarchy, e.g., they have different bailiwicks. (For some background on bailiwicks, see https://www.farsightsecurity.com/blog/txt-record/what-is-a-bailiwick-20170321/ )

All that said, be aware that making formal PTR queries in DNSDB will often yield less-valuable insights for the analyst than simply querying DNSDB for the IP address of interest directly. If you look for an IP of interest directly in DNSDB, the primary use of that IP becomes will often be easy to discern. In this case, it’s easy to see that www.google.com has been seen resolving to 142.251.33.68 (which may be more noteworthy than finding that that IP ALSO has a PTR pointing at the rather obscure address of sea09s28-in-f4.1e100.net):

$ dnsdbq -i 142.251.33.68 -S -k count
;; record times: 2021-03-09 12:33:21 .. 2021-09-21 11:21:49 (~195d 22h 48m)
;; count: 144998
www.google.com.  A  142.251.33.68
​[etc]

A final caution: be careful about how far you “trust” IP query results — DNS administrators can (and have!) defined bogus relationships, either accidentally or on purpose, pointing an IP at domain names that they may not, in fact control, either as "A" or "AAAA" records or with PTR records. So if we’re checking DNSDB for “anything that matters,” we may want to ensure we check IP to FQDN, and then ALSO confirm that the FQDN we find resolves back to that IP — sometimes they may, sometimes they may not.  

Appendix II. Dynamic IP Addresses

IP addresses can be assigned to devices statically or dynamically. Static IP address assignments are normally done “long term,” and may be manually configured in a server or other equipment (or configured automatically via a DevOps provisioning system such as Ansible, Chef, Puppet, or Saltstack).

Dynamic IP addresses are typically issued via DHCP (“Dynamic Host Configuration Protocol”, RFC2132) for short term use. These addresses are normally assigned to users who need to access the Internet, but who are NOT expected to be running a server that will be accessed by third parties.

For example, when we connect to a WiFi network, we’ll typically get assigned a dynamic IP address via DHCP. When we disconnect, the IP address that we were temporarily assigned gets returned to the pool of available IPs and may be reassigned to someone else.

Keys to spotting this type of domain in DNSDB output:

  • If a domain name is found, it may have a name that includes a sign of dynamic assignment such as:

    • Names that mention “dhcp,” “dynamic,” “pool,” etc.

    • Names that mention a customer access mode technology (such as “ADSL” or “wireless”)

    • Names that have a pattern that mechanically follows the underlying IP address, such as:

      d18-156.uoregon.edu.  A  128.223.18.156
      d18-157.uoregon.edu.  A  128.223.18.157
      d18-158.uoregon.edu.  A  128.223.18.158
      etc.
      
  • The primary domain name associated with dynamically assigned IPs will normally NOT change, even though multiple distinct customers may be using the IP at different times.

  • Some customers (typically wanting to run a server (notwithstanding their provider’s expectations to the contrary)) may use a third-party service such as dyn.com or noip.com to temporarily point a convenient-to-the-server-running-customer FQDN at these IPs, but that usage will typically be relatively uncommon and often just for short periods of time.

Appendix III. 2nd-level-dom

#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::SSL::PublicSuffix;

my $pslfile = '/usr/local/share/public_suffix_list.dat';
my $ps = IO::Socket::SSL::PublicSuffix->from_file($pslfile);

my $line;

foreach $line (<>) {
        chomp($line);
        my $root_domain = $ps->public_suffix($line,1);
        printf( "%s\n", $root_domain );
}

You can download a copy of the public_suffix_list.dat file that script uses from https://publicsuffix.org/