Doing DNS queries in Python

July 28, 2005

Every now and then, there comes a time when you need to make DNS queries more complicated than gethostbyname and gethostbyaddr. Or at least, that's what happens to me.

When this happens, my best Python tool is the dnspython module, a pure Python module for doing all sorts of DNS manipulation. But dnspython is a little bit obscure to use, so here's a sample program.

This program looks up IP addresses on the command line that are in the SBL and reports the URLs to their SBL records, so you can see exactly why something is listed. (If an IP address isn't actually in the SBL, nothing gets printed.)

#!/usr/bin/python
import sys
from dns.resolver import query
from dns.exception import DNSException
def revip(ip):
	n = ip.split('.')
	n.reverse()
	return '.'.join(n)
sstr = '%s.sbl.spamhaus.org.'
def sblip(ip):
	qstr = sstr % revip(ip)
	try:
		qa = query(qstr, 'TXT')
	except DNSException:
		return
	for rr in qa:
		for s in rr.strings:
			print s
def process(args):
	for ip in args:
		sblip(ip)
if __name__ == '__main__':
	process(sys.argv[1:])

The SBL DNS blocklist zone lists the SBL record URLs as TXT DNS records, so all we have to do is to make a TXT query against the proper zone. dns.resolver.query is the easiest interface for most simple query operations, so that's what we use. There are two tricky bits having to do with how DNS and TXT DNS records work.

First, a DNS reply can include more than one record in the answer; for example, a single IP address might be in several SBL records. So we have to iterate over the answer to get every rr (which I believe is short for 'resource record', and is a standard DNS thing).

Second, a single TXT record can include multiple pieces of text. I don't believe the SBL uses this, but other places do; for example, the routeviews.org DNS-queryable database of IP to ASN mappings does. So in this program, we iterate over all the strings in each rr and print that.

(Perhaps next I'll do a version of this program in perl for comparison purposes. (Feel free to beat me to it in comments.))


Comments on this page:

From 147.31.171.8 at 2006-04-11 20:31:50:

Hey I had a bit of an issue with running the look-up. I kept getting syntax error at: sstr = "%s.sbl.spamhaus.org."

A ^ would appear below the r in sstr. I have fiddled with it a few times but the syntax error keeps coming up. Can you help me?

By cks at 2006-04-11 22:21:27:

You're probably cut and pasting this into an interactive Python interpreter. If you do this, you need to add a blank line after each function. (I'm not sure why the interpreter requires this, but it does.)

The easiest way to play with this is to dump it into a file, and then load the file as a module.

Written on 28 July 2005.
« Spam Storm, July 26th 2005
How spammers seem to be coping with greylisting »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Jul 28 01:31:48 2005
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.