2010-12-09 3 views
8

Gibt es einen DNS-Server in Python geschrieben, wo ich einfach ein benutzerdefiniertes Backend verwenden kann?Python DNS-Server mit benutzerdefiniertem Backend

Grundsätzlich möchte ich nur für einige Domain-Namen mit meinen eigenen IP-Adressen Look-Ups beantworten, aber den Rest der Look-ups an einen echten DNS-Server weitergeben.

+2

So ziemlich jeder DNS-Server (Python oder nicht) wird das tun, wenn sie richtig konfiguriert sind. Haben Sie eine sehr große Anzahl von Domänen, so dass Sie zum Beispiel eine SQL-Datenbank benötigen? – kindall

Antwort

12

Ich schrieb eine solche Sache vor kurzem, vielleicht haben Sie es als ein Beispiel verwenden können. Es verwendet einen DHT als Backend und sucht dort alle .kad Domains. Wenn Sie einfach die P2PMapping durch Ihr eigenes Mapping (dh ein Diktat wie {'google.com' : '127.0.0.1'}) ersetzen, sollte es tun, was Sie wollen.

""" 
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

Gibt es irgendeinen Weg, den ich ohne Twistd aufrufen könnte? dh es in einen Thread meiner Anwendung einfügen. Das würde es viel einfacher machen, DNS-Anfragen zu beantworten. – Mononofu

4

Viele Leute würden empfehlen, es in Twisted zu schreiben, und eine Anpassung hinzufügen, so dass Sie eine Anfrage selbst beantworten können, wenn Sie möchten. Einige 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

danke für den Vorschlag, aber ich weiß nicht, wie man eine solche Anpassung hinzufügen kann (derzeit zu sehen) - könnten Sie mir einen Tipp geben? – Mononofu

Verwandte Themen