RRset and Rdata Demystified
By Joe St Sauver, Ph.D.
Because Farsight Security, Inc. (FSI) arose from the domain name system (DNS) community, a lot of DNS-related "terms of art" end up getting casually thrown around. These terms allow for very precise conversations among colleagues, but can end up sounding like jargon and confuse (rather than inform) those whose expertise may be in another area.
For example, consider "RRset" vs. "Rdata." Those terms are routinely used in conjunction with FSI's Passive DNS database, DNSDB(tm) and are discussed on the DNSDB info page. We could talk about what "RRset" and "Rdata" mean based on their description in RFC1034, the November 1987 "Domain Names Concepts and Facilities" document that was written by Dr. Paul Mockapetris, one of Farsight Security's Board Members, but let's try a different, "more hands-on" approach.
Why try a hands-on approach? Well, many of you are working cybersecurity people who are investigating cyberincidents. You're not "DNS people," and you don't want to become DNS people, and you may not even care what things are called. Instead, you just want to be able to take what you've already got (perhaps a domain name or an IP address of interest), and use DNSDB to follow those leads in useful ways.
That's entirely reasonable.
So, if you have a domain name or an IP address, what can you do with Farsight Security's DNSDB? And can we figure out what "RRset" vs. "Rdata" means by a bit of trial and error?
If you're a relatively new DNSDB subscriber, you may find using the web
interface to query DNSDB suits your needs. However, most day-in-day-out DNSDB
users prefer the
python command line client instead. (We'll talk about the
client below, but much of what we'll say will be equally applicable to the web
When querying DNSDB with
dnsdb_query.py, you have a choice of three query
-r: to query the RRset
-n: to query the Rdata by name
-i: to query the Rdata by IP address (or by CIDR netblock)
dnsdb_query.py does on your behalf, and the output you receive, depends
on which of those three options you specify. But which option should you
Your options are actually narrower than you might think:
- If you have an IP address (or CIDR netblock), you'll always use
-i, since that's the only option that will work with an IP address.
- If you have a domain name, you'll use either
So how do you know which to use?
If you're not sure, you can always try using both and see which one works best for your needs, but we can also give you some guidance to help you select the best option as a matter of judgment rather than trial and error.
Let's start by considering
-r query for "A records" associated with the host
www.farsightsecurity.com, we see:
1 $ dnsdb_query.py -r www.farsightsecurity.com/A 2 ;; bailiwick: farsightsecurity.com. 3 ;; count: 4,329 4 ;; first seen: 2013-09-25 20:02:10 -0000 5 ;; last seen: 2015-01-28 17:16:11 -0000 6 www.farsightsecurity.com. IN A 220.127.116.11 7 ;; bailiwick: farsightsecurity.com. 8 ;; count: 164 9 ;; first seen: 2013-07-01 17:37:26 -0000 10 ;; last seen: 2013-09-24 17:14:08 -0000 11 www.farsightsecurity.com. IN A 18.104.22.168
Substantively, lines 6 and 11 indicate that
resolved to the IPv4 addresses
If we scrutinize the output from that command more closely, we can see that the
records returned for that query contain
www.farsightsecurity.com on the
"left-hand side" of the DNS records. That is:
www.farsightsecurity.com IN A 22.214.171.124 ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ Left-hand side Right-hand side
As illustrated above,
IN A in this case is the "split" or "dividing point"
between what's "on the left-hand side" and what's "on the right-hand side".
This "stuff on the left-hand side" and "stuff on the right-hand side" concept
is fundamental to the difference between RRset queries and Rdata queries:
- When you make RRset queries (
-r), you're searching DNSDB for matches in the "left-hand side" of DNSDB DNS records
- When you make Rdata queries (
-i), you're searching DNSDB for matches in the "right-hand side" of DNSDB DNS records
A couple more quick notes about
- While we searched for an exact match (e.g.,
www.farsightsecurity.com), we could also have searched for a wildcard match, such as
*.farsightsecurity.com, which would have matched a far wider range of records. By using a wildcard query, we'll find many different hosts that are part of the
farsightsecurity.comdomain name space, but the
-rquery will still only search the "left-hand side" part of the DNS records in the DNSDB database.
- In our original
-rsearch, we specifically asked to just see the A records that DNSDB knew about for
www.farsightsecurity.com; if we'd omitted the
/Afrom the end of the query string, we would have seen ALL the different sorts of records that DNSDB knows about which could include AAAA, MX, or CNAME records. Sometimes a wider range of records is quite helpful, other times those extra records returned are just distracting noise.
Rdata Queries for domain names
Now it's time to see a
-n query for
$ dnsdb_query.py -n www.farsightsecurity.com 81.64-126.96.36.199.in-addr.arpa. IN PTR www.farsightsecurity.com.
This query matches only a single DNSDB record that has
www.farsightsecurity.com on the "right-hand side."
We know that you may be somewhat underwhelmed by the single result from our
-n query – that's because we only asked about one specific host,
-n queries tend to be particularly useful if they're made about a known DNS
server rather than just a run-of-the-mill average host name.
DNS servers map domain names to IP addresses, and they're defined via DNS
"NS records", with the name of the name server on the "right-hand side,".
That's perfect for
For instance, if we make a
-n query for a sample university name server, in
dnsdb_query.py returns a list of over 1,500
domain names that DNSDB knows about, all of which rely on
for name service:
$ dnsdb_query.py -n phloem.uoregon.edu/NS uoregon.biz. IN NS phloem.uoregon.edu. maoz.com. IN NS phloem.uoregon.edu. ...
Major name servers may answer for even more domains – sometimes for hundreds
of thousands of domains, or even more. By default,
dnsdb_query.py will tell
you about 10,000 records, but you can get up to a million records if you use
-l (record limit) command, e.g.:
$ dndsb_query.py -l 1000000 [other options here]
Rdata Queries for IP addresses
-i queries are used to find DNSDB records matching a specific IP address. If
we issue the query:
$ dnsdb_query.py -i 188.8.131.52 farsightsecurity.com. IN A 184.108.40.206 www.farsightsecurity.com. IN A 220.127.116.11
DNSDB is searched and returns two matches for that IP address, both based on
IP addresses found in "right-hand side data." The
-i right-hand side query is
just like the
-n query discussed above, except that the
-i query is
searching for IP addresses, not domain names.
-i queries can also be used to return all records that match a CIDR netblock. For example:
$ dnsdb_query.py -i 18.104.22.168/24 d17-86.uoregon.edu. IN A 22.214.171.124 d17-87.uoregon.edu. IN A 126.96.36.199 d17-88.uoregon.edu. IN A 188.8.131.52 d17-89.uoregon.edu. IN A 184.108.40.206 ...
You might ask, "but what if I want to search the left-hand side of the records in the DNSDB database for an IP address?" The answer there is, "You can't."
Why? There's no such thing as an "IP address-only left-hand side" in DNSDB
records. :-) There are some DNS records that are CLOSE to being all numeric on
the left-hand side, but even those inverse address records are actually names
("labels"), not just IP addresses, so you'd search for them with a
just as you would search for any other "left-hand side" label.
Leveraging the dnsdb_query C-language Client for making bulk RRset and Rdata queries
In addition to the dnsdb_query.py (Python) client shown in the preceding example, FSI also offers a C-language dnsdb_query client
The C-language client is particularly noteworthy for allowing
batch file input, while also supporting conventional
arguments on the command line.
If you're going to use the C-language client's batch input file option,
your batch input file can have three different sorts of queries:
rrset/name/NAME[/TYPE[/BAILIWICK]] rdata/name/NAME[/TYPE] rdata/ip/ADDR[/PFXLEN]
If you've been following along to this point, you should be able to easily translate or decode what those three types of queries represent:
rrset/name/NAMErepresents the "batch" version of a
-rquery, looking at domain name-related labels matches on the LEFT-hand side
-nquery, looking at DOMAIN NAME-related results matches on the RIGHT-hand side
-iquery, looking at IP ADDRESS-related results matches on the RIGHT-hand side
For example, you might create a file called temp-input.txt that has the lines:
rrset/name/\*.wikipedia.org rrset/name/\*.dmoz.org rdata/name/\*.pbs.org rdata/name/\*.opb.org rdata/ip/220.127.116.11 rdata/ip/18.104.22.168 ...
and then run that through the C-language client's batch input file submission option by saying:
$ dnsdb_query -f < temp-input.txt > temp-output.txt
Another unique feature of the C-language client is that it supports comma-separated value ("CSV") format output. While the default text-format output is easy to visually scan, CSV format output makes it easy to import DNSDB output into Microsoft Excel and other applications that consume CSV-format data files.
To request CSV-format output, simply add
-p csv to the dnsdb_query command
you'd otherwise enter.
Pretty convenient and easy, now that you know how to interpret RRset and Rdata!
The best way to become more familiar with the power of DNSDB and
dnsdb_query.py is by trying it with some queries of your own. We hope you
enjoy the experience!
Joe St. Sauver is a Distributed Research Scientist for Farsight Security, Inc.