En utilisant circuits et dnslib est ici un serveur dns récursive complet écrit en Python en seulement 143 lignes de code:
#!/usr/bin/env python
from __future__ import print_function
from uuid import uuid4 as uuid
from dnslib import CLASS, QR, QTYPE
from dnslib import DNSHeader, DNSQuestion, DNSRecord
from circuits.net.events import write
from circuits import Component, Debugger, Event
from circuits.net.sockets import UDPClient, UDPServer
class lookup(Event):
"""lookup Event"""
class query(Event):
"""query Event"""
class response(Event):
"""response Event"""
class DNS(Component):
def read(self, peer, data):
record = DNSRecord.parse(data)
if record.header.qr == QR["QUERY"]:
return self.fire(query(peer, record))
return self.fire(response(peer, record))
class ReturnResponse(Component):
def response(self, peer, response):
return response
class Client(Component):
channel = "client"
def init(self, server, port, channel=channel):
self.server = server
self.port = int(port)
self.transport = UDPClient(0, channel=self.channel).register(self)
self.protocol = DNS(channel=self.channel).register(self)
self.handler = ReturnResponse(channel=self.channel).register(self)
class Resolver(Component):
def init(self, server, port):
self.server = server
self.port = port
def lookup(self, qname, qclass="IN", qtype="A"):
channel = uuid()
client = Client(
self.server,
self.port,
channel=channel
).register(self)
yield self.wait("ready", channel)
self.fire(
write(
(self.server, self.port),
DNSRecord(
q=DNSQuestion(
qname,
qclass=CLASS[qclass],
qtype=QTYPE[qtype]
)
).pack()
)
)
yield (yield self.wait("response", channel))
client.unregister()
yield self.wait("unregistered", channel)
del client
class ProcessQuery(Component):
def query(self, peer, query):
qname = query.q.qname
qtype = QTYPE[query.q.qtype]
qclass = CLASS[query.q.qclass]
response = yield self.call(lookup(qname, qclass=qclass, qtype=qtype))
record = DNSRecord(
DNSHeader(id=query.header.id, qr=1, aa=1, ra=1),
q=query.q,
)
for rr in response.value.rr:
record.add_answer(rr)
yield record.pack()
class Server(Component):
def init(self, bind=("0.0.0.0", 53)):
self.bind = bind
self.transport = UDPServer(self.bind).register(self)
self.protocol = DNS().register(self)
self.handler = ProcessQuery().register(self)
class App(Component):
def init(self, bind=("0.0.0.0", 53), server="8.8.8.8", port=53,
verbose=False):
if verbose:
Debugger().register(self)
self.resolver = Resolver(server, port).register(self)
self.server = Server(bind).register(self)
def main():
App().run()
if __name__ == "__main__":
main()
Utilisation:
Par défaut, cet exemple se fixe aller 0.0.0.0:53
donc vous aurez besoin de faire quelque chose comme:
sudo ./dnsserver.py
Sinon, modifiez le paramètre bind
.
Je suppose que ce n'est pas le cas. De quoi aurais-je besoin alors? Je pensais avoir besoin d'un proxy parce que je voulais qu'il soit facile pour les réseaux d'utiliser mon programme pour le filtrage des adresses web. Si vous utilisez un proxy, il ne peut pas s'agir d'un utilitaire "réseau", car il n'y a pas de place dans la plupart des paramètres du routeur pour définir un proxy. –
@Zachary, je ne sais pas ce dont vous avez besoin car je ne comprends toujours pas quel type de "filtrage d'adresse Web" vous essayez d'accomplir - je viens de répondre à la question que vous avez posée. Si vous écrivez un serveur web qui doit répondre différemment selon l'IP qui fait la demande, par exemple, c'est une question complètement différente (en fonction du framework web que vous avez choisi & c, pour commencer ;-). –
... et si ce que vous voulez, c'est que votre serveur puisse utiliser des proxy différents, sans être techniquement un proxy HTTP, c'est faisable aussi, mais _yet une autre question complètement différente. S'il vous plaît poser une question différente en spécifiant ce que vous essayez d'accomplir plus précisément, et fermez celui-ci! -) –