开发者

Python DNS server with custom backend

Is there any DNS server w开发者_Python百科ritten in python where I can easily use a custom backend?

Basically, I just want to answer look-ups for some domain names with my own IPs, but pass the rest of the look-ups on to a real DNS server.


I wrote such a thing recently, maybe you can use it as an example. It uses a DHT as the backend and looks up all .kad domains there. If you simply replace the P2PMapping with your own mapping (ie a dict like {'google.com' : '127.0.0.1'}) it should do what you want.

"""
Created on 16.08.2010

@author: Jochen Ritzel
"""

import dht

from twisted.names import dns, server, client, cache
from twisted.application import service, internet

class P2PMapping(dht.EntangledDHT):

    def __contains__(self, key):
        return key.endswith('.kad')

class MapResolver(client.Resolver):
    """
    Resolves names by looking in a mapping. 
    If `name in mapping` then mapping[name] should return a IP
    else the next server in servers will be asked for name    
    """
    def __init__(self, mapping, servers):
        self.mapping = mapping
        client.Resolver.__init__(self, servers=servers)
        self.ttl = 10

    def lookupAddress(self, name, timeout = None):
        # find out if this is a .kad. request
        if name in self.mapping:
            result = self.mapping[name] # get the result
            def packResult( value ):
                return [
                        (dns.RRHeader(name, dns.A, dns.IN, self.ttl, dns.Record_A(value, self.ttl)),), (), ()
                ]
            result.addCallback(packResult) # put it in a A Record
            return result
        else:
            return self._lookup(name, dns.IN, dns.A, timeout)


## this sets up the application


application = service.Application('dnsserver', 1, 1)


## set up the DHT
mapping = P2PMapping(bootstrap=[('127.0.0.1', 4001)])
mapping['jochen.kad'] = '99.99.99.99' # "register" domain with IP


# set up a resolver that uses the mapping or a secondary nameserver
p2presolver = MapResolver(mapping, servers=[('192.168.178.1', 53)])


# create the protocols
f = server.DNSServerFactory(caches=[cache.CacheResolver()], clients=[p2presolver])
p = dns.DNSDatagramProtocol(f)
f.noisy = p.noisy = False


# register as tcp and udp
ret = service.MultiService()
PORT=53

for (klass, arg) in [(internet.TCPServer, f), (internet.UDPServer, p)]:
    s = klass(PORT, arg)
    s.setServiceParent(ret)


# run all of the above as a twistd application
ret.setServiceParent(service.IServiceCollection(application))


# run it through twistd!
if __name__ == '__main__':
    import sys
    print "Usage: twistd -y %s" % sys.argv[0]


Actually, I found an even simpler method: PowerDNS with the pipe backend:

http://doc.powerdns.com/pipebackend-dynamic-resolution.html

http://doc.powerdns.com/backends-detail.html#PIPEBACKEND

Just install the PowerDNS server, write a small script that forwards the queries to your server and you are done.


Many people would advise writing it in Twisted, and adding a customization so that you can answer a request yourself if you want to. Some links:

http://twistedmatrix.com/documents/10.1.0/names/howto/names.html

http://twistedmatrix.com/documents/10.1.0/api/twisted.names.dns.DNSDatagramProtocol.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜