-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbackend.py
executable file
·138 lines (114 loc) · 4.65 KB
/
backend.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
import sys
from pymongo import MongoClient
# Config
mongo_host = "127.0.0.1"
mongo_port = 27017
mongo_db = "dns"
mongo_collation = "records"
class Lookup(object):
ttl = 30
def __init__(self, query):
(_type, qname, qclass, qtype, _id, ip) = query
self.has_result = False
qname_lower = qname.lower()
self.results = []
client = MongoClient(mongo_host, mongo_port, connect=False)
db = client[mongo_db]
coll = db[mongo_collation]
if qtype == "ANY":
records = coll.find({"name": qname_lower})
else:
records = coll.find({"type": qtype, "name": qname_lower})
if records:
for record in records:
if record['type'] == "SOA":
"""
{
"name":"example.org",
"type":"SOA",
"content":"",
"ttl": 300,
"primary": "ns1.example.org",
"mail": "admin.example.org",
"serial": 2018030311,
"refresh": 86400,
"retry": 7200,
"expire": 3600000,
"nttl": 3600
}
"""
try:
self.results.append(
'DATA\t%s\t%s\t%s\t%s\t-1\t%s\t%s\t%s\t%s\t%s\t%s\t%s' % ( qname_lower,
qclass,
qtype,
record['ttl'],
record['primary'],
record['mail'],
record['serial'],
record['refresh'],
record['retry'],
record['expire'],
record['nttl']
))
self.has_result = True
except:
self.results.append('LOG\t %s SOA Record currupt maybe fields are missing.' % qname_lower)
else:
"""
{
"name":"www.example.org",
"type":"A",
"ttl": 300,
"content": "1.1.1.1"
}
"""
self.results.append('DATA\t%s\t%s\t%s\t%d\t-1\t%s' % (
qname_lower, qclass, record['type'], record['ttl'], record['content']))
self.has_result = True
def str_result(self):
if self.has_result:
return '\n'.join(self.results)
else:
return ''
class DNSbackend(object):
def __init__(self, filein, fileout):
self.filein = filein
self.fileout = fileout
self._process_requests()
def _fprint(self, message):
self.fileout.write(message + '\n')
self.fileout.flush()
def _process_requests(self):
first_time = True
while 1:
rawline = self.filein.readline()
if rawline == '':
return
line = rawline.rstrip()
if first_time:
if line == 'HELO\t1':
self._fprint('OK\tPython backend ready.')
else:
rawline = self.filein.readline()
sys.exit(1)
first_time = False
else:
query = line.split('\t')
if len(query) != 6:
self._fprint('LOG\tPowerDNS sent unparseable line')
self._fprint('FAIL')
else:
lookup = Lookup(query)
if lookup.has_result:
pdns_result = lookup.str_result()
self._fprint(pdns_result)
self._fprint('END')
if __name__ == "__main__":
infile = sys.stdin
outfile = sys.stdout
try:
DNSbackend(infile, outfile)
except:
raise