|
|
@@ -0,0 +1,59 @@ |
|
|
# dns server using dnslib and gevent |
|
|
# based on https://bitbucket.org/paulc/dnslib/src/80d85555aae4/src/server/gevent_server.py |
|
|
# set the key as |
|
|
# set IP:name ip_addr |
|
|
# set TXT:name txtfield |
|
|
# fallback on gevent's dns resolver |
|
|
# gleicon 2011 |
|
|
|
|
|
|
|
|
import gevent |
|
|
from gevent import socket |
|
|
import gevent.dns; |
|
|
from gevent import monkey; |
|
|
monkey.patch_socket() |
|
|
|
|
|
import urllib2,sys |
|
|
import redis |
|
|
import random |
|
|
from dnslib import * |
|
|
|
|
|
|
|
|
AF_INET = 2 |
|
|
SOCK_DGRAM = 2 |
|
|
|
|
|
s = socket.socket(AF_INET,SOCK_DGRAM) |
|
|
s.bind(('',53)) |
|
|
|
|
|
def dns_handler(s, peer, data, r): |
|
|
request = DNSRecord.parse(data) |
|
|
id = request.header.id |
|
|
qname = request.q.qname |
|
|
qtype = request.q.qtype |
|
|
IP = r.get("IP:%s" % qname) |
|
|
TXT = r.get("TXT:%s" % qname) |
|
|
if not IP: |
|
|
_t, addrs = gevent.dns.resolve_ipv4(str(qname)) |
|
|
IP = socket.inet_ntoa(random.choice(addrs)) |
|
|
|
|
|
print "Request (%s): %r (%s) - Response: %s" % (str(peer), qname.label, QTYPE[qtype], IP) |
|
|
reply = DNSRecord(DNSHeader(id=id,qr=1,aa=1,ra=1),q=request.q) |
|
|
if qtype == QTYPE.A: |
|
|
reply.add_answer(RR(qname,qtype,rdata=A(IP))) |
|
|
elif qtype == QTYPE['*']: |
|
|
reply.add_answer(RR(qname,QTYPE.A,rdata=A(IP))) |
|
|
reply.add_answer(RR(qname,QTYPE.MX,rdata=MX(IP))) |
|
|
reply.add_answer(RR(qname,QTYPE.TXT,rdata=TXT(TXT))) |
|
|
else: |
|
|
reply.add_answer(RR(qname,QTYPE.CNAME,rdata=CNAME(TXT))) |
|
|
s.sendto(reply.pack(),peer) |
|
|
|
|
|
|
|
|
def main(): |
|
|
r = redis.Redis() |
|
|
while True: |
|
|
data,peer = s.recvfrom(8192) |
|
|
gevent.spawn(dns_handler, s, peer, data, r) |
|
|
|
|
|
if __name__ == '__main__': |
|
|
main() |