2010-12-09 5 views
8

Existe-t-il un serveur DNS écrit en python où je peux facilement utiliser un backend personnalisé? Fondamentalement, je veux juste répondre à des recherches pour certains noms de domaine avec mes propres adresses IP, mais passer le reste des recherches sur un vrai serveur DNS.Serveur DNS Python avec backend personnalisé

+2

Pratiquement tout serveur DNS (Python ou non) le fera s'il est configuré correctement. Avez-vous un très grand nombre de domaines dont vous aurez besoin, disons, d'une base de données SQL pour eux? – kindall

Répondre

12

J'ai écrit une telle chose récemment, vous pouvez peut-être utiliser comme un exemple. Il utilise un DHT comme backend et y recherche tous les domaines .kad. Si vous remplacez simplement le P2PMapping avec votre propre cartographie (par exemple une dict comme {'google.com' : '127.0.0.1'}), il devrait faire ce que vous voulez.

""" 
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] 
+3

est-il possible de lancer ceci sans appeler twistd? c'est-à-dire le mettre dans un fil de mon application. Cela rendrait beaucoup plus facile de répondre aux requêtes DNS. – Mononofu

4

Beaucoup de gens vous conseilleraient de l'écrire en Twisted, et en ajoutant une personnalisation afin que vous puissiez répondre à une demande vous-même si vous le souhaitez. Quelques liens:

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

merci pour la suggestion, mais je ne sais pas comment ajouter une telle personnalisation (actuellement la recherche) - pourriez-vous me donner un indice? – Mononofu