def resolve(self, request, handler): global TXT_RECORDS reply = request.reply() name = request.q.qname logger.info("query %s", request.q.qname) # handle the main domain if (name == confs.BASE_DOMAIN or name == '_acme-challenge.' + confs.BASE_DOMAIN): r = RR(rname=request.q.qname, rdata=dns.A(confs.LOCAL_IPV4), rtype=QTYPE.A, ttl=60 * 60) reply.add_answer(r) if self.SOA: r = RR(rname=request.q.qname, rdata=self.SOA, rtype=QTYPE.SOA, ttl=60 * 60) reply.add_answer(r) if len(self.NS): for i in self.NS: r = RR(rname=request.q.qname, rdata=i, rtype=QTYPE.NS, ttl=60 * 60) reply.add_answer(r) if confs.LOCAL_IPV6: r = RR(rname=request.q.qname, rdata=dns.AAAA(confs.LOCAL_IPV6), rtype=QTYPE.AAAA, ttl=60 * 60) reply.add_answer(r) if len(TXT_RECORDS): r = RR(rname=request.q.qname, rdata=dns.TXT([ '{1}'.format(k, v) for k, v in TXT_RECORDS.items() ]), rtype=QTYPE.TXT) reply.add_answer(r) return reply # handle subdomains elif name.matchSuffix(confs.BASE_DOMAIN): # fnmatch labelstr = str(request.q.qname) logger.info("request: %s", labelstr) mv4 = re.match( '^([0-9]{1,3}-[0-9]{1,3}-[0-9]{1,3}-[0-9]{1,3})\.' + confs.BASE_DOMAIN + '\.$', labelstr) if mv4: ipv4 = mv4.group(1).replace('-', '.') # check if valid ip ipv4parts = [int(x) for x in ipv4.split('.')] if ((ipv4parts[0] == 192 and ipv4parts[1] == 168 and ipv4parts[2] == 0 and ipv4parts[3] <= 255) or (ipv4parts[0] == 172 and 0 <= ipv4parts[1] <= 31 and ipv4parts[2] <= 255 and ipv4parts[3] <= 255) or (ipv4parts[0] == 10 and 0 <= ipv4parts[1] <= 255 and ipv4parts[2] <= 255 and ipv4parts[3] <= 255)): logger.info("ip is %s", ipv4) r = RR(rname=request.q.qname, rdata=dns.A(ipv4), rtype=QTYPE.A, ttl=24 * 60 * 60) reply.add_answer(r) else: logger.info('invalid ipv4 %s', labelstr) else: mv6 = re.match( '^(fe80-[0-9a-f\-]{0,41})\.' + confs.BASE_DOMAIN + '\.$', labelstr) if mv6: ipv6 = mv6.group(1).replace('-', ':') try: ipaddress.ip_address(ipv6) # validate IP r = RR(rname=request.q.qname, rdata=dns.AAAA(ipv6), rtype=QTYPE.AAAA, ttl=24 * 60 * 60) reply.add_answer(r) except: # invalid ip logger.info('invalid ipv6 %s', labelstr) pass logger.info('found zone for %s, %d replies', request.q.qname, len(reply.rr)) return reply return super().resolve(request, handler)
def resolve(self, request, handler): global TXT_RECORDS reply = request.reply() name = request.q.qname logger.info("query %s", request.q.qname) # handle the main domain if (name == confs.BASE_DOMAIN or name == '_acme-challenge.' + confs.BASE_DOMAIN): r = RR(rname=request.q.qname, rdata=dns.A(confs.LOCAL_IPV4), rtype=QTYPE.A, ttl=60 * 60) reply.add_answer(r) if self.SOA: r = RR(rname=request.q.qname, rdata=self.SOA, rtype=QTYPE.SOA, ttl=60 * 60) reply.add_answer(r) if len(self.NS): for i in self.NS: r = RR(rname=request.q.qname, rdata=i, rtype=QTYPE.NS, ttl=60 * 60) reply.add_answer(r) if confs.LOCAL_IPV6: r = RR(rname=request.q.qname, rdata=dns.AAAA(confs.LOCAL_IPV6), rtype=QTYPE.AAAA, ttl=60 * 60) reply.add_answer(r) if len(TXT_RECORDS): r = RR(rname=request.q.qname, rdata=dns.TXT([ '{1}'.format(k, v) for k, v in TXT_RECORDS.items() ]), rtype=QTYPE.TXT) reply.add_answer(r) return reply # handle subdomains elif name.matchSuffix(confs.BASE_DOMAIN): # fnmatch labelstr = str(request.q.qname) logger.info("requestx: %s, %s", labelstr, confs.ONLY_PRIVATE_IPS) subdomains = labelstr.split('.') if len(subdomains) == 4: # TODO: dynamic ip = None try: ip = ipaddress.ip_address(subdomains[0].replace('-', '.')) except: pass try: if ip == None: ip = ipaddress.ip_address(subdomains[0].replace( '-', ':')) except: logger.info('invalid ip %s', labelstr) return reply # check if we only want private ips if not ip.is_private and confs.ONLY_PRIVATE_IPS: return reply if ip.is_reserved and confs.NO_RESERVED_IPS: return reply # check if it's a valid ip for a machine if ip.is_multicast or ip.is_unspecified: return reply if type(ip) == ipaddress.IPv4Address: ipv4 = subdomains[0].replace('-', '.') logger.info("ip is ipv4 %s", ipv4) r = RR(rname=request.q.qname, rdata=dns.A(ipv4), rtype=QTYPE.A, ttl=24 * 60 * 60) reply.add_answer(r) elif type(ip) == ipaddress.IPv6Address: ipv6 = subdomains[0].replace('-', ':') logger.info("ip is ipv6 %s", ipv6) r = RR(rname=request.q.qname, rdata=dns.AAAA(ipv6), rtype=QTYPE.AAAA, ttl=24 * 60 * 60) reply.add_answer(r) else: return reply logger.info('found zone for %s, %d replies', request.q.qname, len(reply.rr)) return reply elif self.address == "": return reply return super().resolve(request, handler)
def resolve(self, request, handler): domain_request = self.DOMAIN_REGEX.findall(str(request.q.qname)) type_name = QTYPE[request.q.qtype] if not domain_request: return super().resolve(request, handler) domain_request = domain_request[0] packet_type = domain_request[0] db = sqlite3.connect('users.db') result = "" if packet_type == '0': cursor = db.cursor() cursor.execute(GET_MIN_ID) min_id = cursor.fetchone()[0] cursor.execute('''INSERT INTO users VALUES (?, ?, 'KEY')''', (min_id, domain_request[8:-1])) db.commit() result = "{}{}".format(str(min_id).zfill(2), "KEY") elif packet_type == '1': id = domain_request[-3:-1] handler_client = proxy_handler.handlers[id] if handler_client['buffer'] is None: result = id + 'ND' else: b64 = base64.b64encode( handler_client['buffer']).decode('utf-8') result = "{}{}:{}:{}".format(id, handler_client['target_ip'], handler_client['target_port'], b64) proxy_handler.handlers[id]['buffer'] = None elif packet_type == '2': req = self.PACKET_REGEX.findall(domain_request) if req: req = req[0] handler_client = proxy_handler.handlers[req[0]] handler_client['upstream_buffer'] += req[2].encode('utf-8') if req[1] != '000': result = '{}{}:OK'.format(req[0], req[1]) else: handler_client['socket'].send( base64.b64decode(handler_client['upstream_buffer'])) handler_client['upstream_buffer'] = b'' result = "ENDBLOCK" else: result = 'Error' elif packet_type == '3': id = domain_request[-3:-1] cursor = db.cursor() cursor.execute('''DELETE FROM users WHERE user_id = ?''', (id, )) db.commit() result = "{}REMOVED".format(id) reply = request.reply() reply.add_answer( RR(rname=DNSLabel(str(request.q.qname)), rtype=QTYPE.TXT, rdata=dns.TXT(wrap(result, 255)), ttl=300)) db.close() if reply.rr: return reply