Today while spending some time at the book store with my family, I decided to peruse a copy Craig Hunt’s TCP/IP Network Administration. It covers BIND software for DNS. I’ve been thinking about my post Asset Management Assistance via Custom DNS Records. In the book I noticed the following:

“Responsible Person” record? That sounds perfect. I found RFC 1183 from 1990 introduced these.
I decided to try setting up these records on a VM running FreeBSD 7.1 and BIND 9. The VM had IP 172.16.99.130 with gateway 172.16.99.2. I followed the example in Building a Server with FreeBSD 7.
First I made changes to named.conf as shown in this diff:
# diff /var/named/etc/namedb/named.conf /var/named/etc/namedb/named.conf.orig132c132< // zone "16.172.in-addr.arpa" { type master; file "master/empty.db"; };---> zone "16.172.in-addr.arpa" { type master; file "master/empty.db"; };274,290d273< zone "example.com" {< type master;< file "master/example.com";< allow-transfer { localhost; };< allow-update { key rndc-key; };< }; < < zone "99.16.172.in-addr.arpa" {< type master;< file "master/example.com.rev";< allow-transfer { localhost; };< allow-update { key rndc-key; };< };< key "rndc-key" {< algorithm hmac-md5;< secret "4+IlE0Z/oHoHok9EnVwkUw==";< };
To generate the last section I ran the following:
# rndc-confgen -awrote key file "/etc/namedb/rndc.key"# cat rndc.key >> named.conf
Next I created /var/named/etc/namedb/master/example.com:
# cat example.com$TTL 3600
example.com. IN SOA host.example.com. root.example.com. (
1 ; Serial 10800 ; Refresh 3600 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL
;DNS Serversexample.com. IN NS host.example.com.
;Machine Nameshost.example.com. IN A 172.16.99.130gateway.example.com. IN A 172.16.99.2
;Aliaseswww IN CNAME host.example.com.
;MX Recordexample.com. IN MX 10 host.example.com.
;RP Recordhost.example.com. IN RP taosecurity.email.com. sec-con.example.com.gateway.example.com. IN RP networkteam.email.com. net-con.example.com.
;TXT Recordsec-con.example.com. IN TXT "Richard Bejtlich"sec-con.example.com. IN TXT "Employee ID 1234567890"sec-con.example.com. IN TXT "Northern VA office"net-con.example.com. IN TXT "Network Admin"net-con.example.com. IN TXT "Group ID 0987"net-con.example.com. IN TXT "DC office"
Then I created /var/named/etc/namedb/master/example.com.rev:
# cat example.com.rev $TTL 3600
99.16.172.in-addr.arpa. IN SOA host.example.com. root.example.com. (
1 ; Serial 10800 ; Refresh 3600 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL
;DNS Servers99.16.172.in-addr.arpa. IN NS host.example.com.
;Machine IPs1 IN RP networkteam.email.com. net-con.example.com.2 IN PTR gateway.example.com.130 IN PTR host.example.com.130 IN PTR www.example.com.
;RP Record2 IN RP networkteam.email.com. net-con.example.com.13 IN RP taosecurity.email.com. sec-con.example.com.
If you caught my ommission, I’ll point it out near the end of the post.
Finally I edited /etc/resolv.conf so it pointed only to 127.0.0.1, and restarted named:
# /etc/rc.d/named restartStopping named.Starting named.
Now I was able to query the name server.
# dig @127.0.0.1 version.bind chaos txt | grep version.bind; <<>> DiG 9.4.2-P2 <<>> @127.0.0.1 version.bind chaos txt;version.bind. CH TXTversion.bind. 0 CH TXT "9.4.2-P2"version.bind. 0 CH NS version.bind.
Let’s do zone transfers for the forward and reverse zones.
# dig @127.0.0.1 axfr example.com.
; <<>> DiG 9.4.2-P2 <<>> @127.0.0.1 axfr example.com.; (1 server found);; global options: printcmdexample.com. 3600 IN SOA host.example.com. root.example.com. 1 10800 3600 604800 86400example.com. 3600 IN MX 10 host.example.com.example.com. 3600 IN NS host.example.com.gateway.example.com. 3600 IN RP networkteam.email.com. net-con.example.com.gateway.example.com. 3600 IN A 172.16.99.2host.example.com. 3600 IN RP taosecurity.email.com. sec-con.example.com.host.example.com. 3600 IN A 172.16.99.130net-con.example.com. 3600 IN TXT "Network Admin"net-con.example.com. 3600 IN TXT "Group ID 0987"net-con.example.com. 3600 IN TXT "DC office"sec-con.example.com. 3600 IN TXT "Richard Bejtlich"sec-con.example.com. 3600 IN TXT "Employee ID 1234567890"sec-con.example.com. 3600 IN TXT "Northern VA office"www.example.com. 3600 IN CNAME host.example.com.example.com. 3600 IN SOA host.example.com. root.example.com. 1 10800 3600 604800 86400;; Query time: 41 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Sun Mar 1 04:22:57 2009;; XFR size: 15 records (messages 1, bytes 480)
# dig @127.0.0.1 axfr 99.16.172.in-addr.arpa.
; <<>> DiG 9.4.2-P2 <<>> @127.0.0.1 axfr 99.16.172.in-addr.arpa.; (1 server found);; global options: printcmd99.16.172.in-addr.arpa. 3600 IN SOA host.example.com. root.example.com. 1 10800 3600 604800 8640099.16.172.in-addr.arpa. 3600 IN NS host.example.com.1.99.16.172.in-addr.arpa. 3600 IN RP networkteam.email.com. net-con.example.com.13.99.16.172.in-addr.arpa. 3600 IN RP taosecurity.email.com. sec-con.example.com.130.99.16.172.in-addr.arpa. 3600 IN PTR host.example.com.130.99.16.172.in-addr.arpa. 3600 IN PTR www.example.com.2.99.16.172.in-addr.arpa. 3600 IN RP networkteam.email.com. net-con.example.com.2.99.16.172.in-addr.arpa. 3600 IN PTR gateway.example.com.99.16.172.in-addr.arpa. 3600 IN SOA host.example.com. root.example.com. 1 10800 3600 604800 86400;; Query time: 27 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Sun Mar 1 04:26:36 2009;; XFR size: 9 records (messages 1, bytes 380)
Now let’s pretend we have a security incident involving 172.16.99.2. You want to know who owns it. Let’s query for RP records.
VirtualBSD# host -t rp 172.16.99.22.99.16.172.in-addr.arpa domain name pointer gateway.example.com.
Ok, I see that I get a PTR record for 172.16.99.2. I can look for a RP record for that hostname.
# host -t rp gateway.example.com.gateway.example.com has RP record networkteam.email.com. net-con.example.com.
That worked. I see the email address for the Responsible Person is networkteam@email.com (you have to imagine the @ instead of the . there), and I also get indication of a TXT record. I query for that next.
# host -t txt net-con.example.com.net-con.example.com descriptive text "Network Admin"net-con.example.com descriptive text "Group ID 0987"net-con.example.com descriptive text "DC office"
Great, I have some additional details on the network team.
What if I try 172.16.99.130?
# host -t rp 172.16.99.130130.99.16.172.in-addr.arpa domain name pointer www.example.com.130.99.16.172.in-addr.arpa domain name pointer host.example.com.
# host -t RP www.example.com.www.example.com is an alias for host.example.com.host.example.com has RP record taosecurity.email.com. sec-con.example.com.
# host -t TXT sec-con.example.com.sec-con.example.com descriptive text "Richard Bejtlich"sec-con.example.com descriptive text "Employee ID 1234567890"sec-con.example.com descriptive text "Northern VA office"
How about 172.16.99.1?
# host -t rp 172.16.99.11.99.16.172.in-addr.arpa has no PTR record
That was the error in the example.com.rev file I posted earlier. Or is it an error? Maybe not:
# host -t rp 1.99.16.172.in-addr.arpa 1.99.16.172.in-addr.arpa has RP record networkteam.email.com. net-con.example.com.
If we query for the IP in in-addr.arpa format, we can find a RP record. So, it’s possible to have IPs without hostnames in your DNS and still have RP records. You just need to know how to ask for them.
I think this is really promising. At the very least, an DNS admin responsible for hosts in a certain subnet could add RP records, like that of 172.16.99.1, for every host. This would probably work best for servers, but it should be possible to extend it to hosts with dynamic DNS assignments.
Incidentally, RP records do not seem very popular on the Internet. If you find any in the wild, please let me know.
Richard Bejtlich is teaching new classes in
Europe in 2009.
Register by 1 Mar for the best rates.