Performing DNS Queries in Python

dnspython provides a detailed interface into DNS. In its simplest form, it’s possible to perform queries in only a couple of lines of code. Here’s a commented example:

import dns.resolver #import the module
myResolver = dns.resolver.Resolver() #create a new instance named 'myResolver'
myAnswers = myResolver.query("google.com", "A") #Lookup the 'A' record(s) for google.com
for rdata in myAnswers: #for each response
    print rdata #print the data

The results in my case are:

173.194.125.3
173.194.125.7
173.194.125.4
173.194.125.8
173.194.125.9
173.194.125.5
173.194.125.2
173.194.125.0
173.194.125.6
173.194.125.1
173.194.125.14


In the same way, we can perform MX and NS queries with:

myAnswers = myResolver.query("google.com", "MX")

and

myAnswers = myResolver.query("google.com", "NS")

We can easily look up TXT records, which will contain SPF records for a domain if present:

myAnswers = myResolver.query("iodigitalsec.com", "TXT")

Which results in:

"v=spf1 mx a ptr ip4:148.251.196.144/28 ip4:85.10.227.160/28 ip4:85.10.227.160/28 ~all"

These are some of the more common types, however DNS is an expansive protocol and further information on query types can be found here.

When it comes to reverse DNS (IP to hostname), it’s not as simple as performing an A record lookup on the IP address. We need to perform a PTR lookup instead, but not just on the IP address. The IP needs to be reversed, and have “.in-addr.arpa” appended to it.

To resolve the IP 173.194.125.3 to a hostname, we use the code:

myAnswers = myResolver.query("3.125.194.174.in-addr.arpa", "PTR")

We can handle the crafting of the request programatically as follows:

ip = "173.194.125.3"
req = '.'.join(reversed(ip.split("."))) + ".in-addr.arpa"
myAnswers = myResolver.query(req, "PTR")

The DNS resolver also gives us the option of specifying our own nameservers. This can be achieved by using:

myResolver = dns.resolver.Resolver()
myResolver.nameservers = ['8.8.8.8', '8.8.4.4']

Including an error catch, we can put the whole thing together with:

import dns.resolver

myResolver = dns.resolver.Resolver()
myResolver.nameservers = ['8.8.8.8', '8.8.4.4']

try:
        myAnswers = myResolver.query("google.com", "A")
        for rdata in myAnswers:
                print rdata
except:
        print "Query failed"

Now try and put together an application that performs command line DNS queries, i.e.:

./pydnslookup.py A google.com
./pydnslookup.py MX msn.com
./pydnslookup.py PTR 8.8.8.8

Tags: , , ,

2 Responses to “Performing DNS Queries in Python”

  1. Angus says:

    For good practice, and to give an example of the exception name for this module, you should use this:
    try:
    tryBlock
    except dns.exception.DNSException:
    print “Query failed”

  2. CCS says:

    Thank you. This helped me out quite a bit.

Leave a Reply