How to set up a local DNS server in python

imp picture imp · May 9, 2014 · Viewed 9.7k times · Source

I am using windows 7 and python 2.7 I want to map 172.16.45.84 IP address to myapp.nobies.in without mapping in hosts file.

I have the required certificate to this hostname. I don't want to map in hosts file as it requires administrative privileges.

So, how to create a DNS python server for it, which can be shipped with my app.

Answer

nettux picture nettux · May 9, 2014

see this post How can I do DNS lookups in Python, including referring to /etc/hosts? for how to do dns lookups in python.

You could do something like:

import socket
name = raw_input("hostname:")
if name == "mpapp.nobies.in":
    print "172.16.45.84"
else:
    print socket.gethostbyname(name)

This will perform normal DNS lookups unless you lookup "myapp.nobies.in" which will return 172.16.45.84

Note: this is not a functioning DNS server application. It is however a (very basic) nslookup-like command alternative. To make this an actual server you need to listen for DNS packets on port 53 (which will require admin rights as it's a privileged port. I guess you could use a higher one but you'd have to configure that on your DNS client too). Investigate socket server programming in python. Good reading here from the python docs:

https://docs.python.org/2/howto/sockets.html

and here:

https://docs.python.org/2/library/socket.html

I'd also suggest looking up dnslib and/or dnspython for parsing DNS packets

EDIT:

try this code as to get you going: (start in a command prompt and minimize)

#!/usr/bin/python

import socket

def resolve(name):
    if name == "mpapp.nobies.in":
        return "172.16.45.84"
    else :
        # you ought to add some basic checking of name here
        return socket.gethostbyname(name)

host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
    client, address = s.accept()
    data = client.recv(size)
    if data:
        bits = data.split(":")
        if bits[0] == 'h':
            client.send(resolve(bits[1]))
    client.close()

and use this as a client: (customize variables and run after you've started the server)

#!/usr/bin/python

import socket

### configure me ###

dns_server_ip = '127.0.0.1'
dns_server_port = 50000
query = 'mpapp.nobies.in' # change this to the hostname you want to lookup

### configure me ###

size = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((dns_server_ip,dns_server_port))
s.send('h:' + query)
data = s.recv(size)
s.close()
print data

Note: this is not really a dns server, it doesn't not understand dns packets it just takes a hostname string prefixed with 'h:' on port 50000 and returns an ip address. I hope this meets your needs.

Usage:

$ START "" .\dns-server.py
$ .\dns-client.py
172.16.45.84