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:
184.108.40.206 220.127.116.11 18.104.22.168 22.214.171.124 126.96.36.199 188.8.131.52 184.108.40.206 220.127.116.11 18.104.22.168 22.214.171.124 126.96.36.199
In the same way, we can perform MX and NS queries with:
myAnswers = myResolver.query("google.com", "MX")
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:188.8.131.52/28 ip4:184.108.40.206/28 ip4:220.127.116.11/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 18.104.22.168 to a hostname, we use the code:
myAnswers = myResolver.query("22.214.171.124.in-addr.arpa", "PTR")
We can handle the crafting of the request programatically as follows:
ip = "126.96.36.199" 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 = ['188.8.131.52', '184.108.40.206']
Including an error catch, we can put the whole thing together with:
import dns.resolver myResolver = dns.resolver.Resolver() myResolver.nameservers = ['220.127.116.11', '18.104.22.168'] 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 22.214.171.124