import http.server import socketserver import urllib.parse import dnslib import base64 import socket UPSTREAM_DNS = ("8.8.8.8", 53) try: def resolve(zone, qname, qtype): for record in zone: if record["name"] == qname and record["type"] == qtype and "value" in record: return record["value"] def resolve_recursive(raw_query): with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: sock.settimeout(5) sock.sendto(raw_query, UPSTREAM_DNS) data, _ = sock.recvfrom(4096) return data class DnsHttpRequestHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): try: with open("/dns/zone.json", "r") as f: import json zone = json.load(f) url = urllib.parse.urlparse(self.path) if url.path != "/dns-query": self.send_response(404) return query = urllib.parse.parse_qs(url.query) if "dns" not in query: self.send_response(400) return query_base64 = query["dns"][0] padded = query_base64 + "=" * (4 - len(query_base64) % 4) raw = base64.b64decode(padded) dns = dnslib.DNSRecord.parse(raw) response = dnslib.DNSRecord(dnslib.DNSHeader(id=dns.header.id, qr=1, aa=1, ra=1), q=dns.q) record = resolve(zone, dns.q.qname, dnslib.QTYPE[dns.q.qtype]) if record: if dns.q.qtype == dnslib.QTYPE.SRV: print("SRV record") reply = dnslib.SRV(record["priority"], record["weight"], record["port"], record["target"]) response.add_answer(dnslib.RR(dns.q.qname, dns.q.qtype, rdata=reply)) pack = response.pack() else: print(f"Recursively resolving {dns.q.qname}") pack = resolve_recursive(raw) print(response) self.send_response(200) self.send_header("Content-type", "application/dns-message") self.end_headers() self.wfile.write(pack) return except Exception as e: print(f"Error: {e}") self.send_response(500) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write(b"Internal Server Error") handler_object = DnsHttpRequestHandler PORT = 8053 my_server = socketserver.TCPServer(("", PORT), handler_object) # Start the server print(f"Starting server on port {PORT}") my_server.serve_forever() except Exception as e: print(f"Error: {e}")