Create a gist now

Instantly share code, notes, and snippets.

Embed
Answer AAAA DNS queries on behalf of a DNS server
#!/usr/bin/env python3
import socket
import struct
import traceback
import subprocess
import time
import signal
import dnslib
from dnslib import DNSRecord
from netfilterqueue import NetfilterQueue
AAAA = dnslib.QTYPE.reverse['AAAA']
udpsock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
PORT = 53
def handle_packet(pkt):
s = time.time()
try:
ip = pkt.get_payload()
# 28 = 20B IPv4 header + 8B UDP header
dns = DNSRecord.parse(ip[28:])
if dns.q.qtype == AAAA:
ret = dns.reply()
src = socket.inet_ntoa(ip[12:16])
sport = struct.unpack('!H', ip[20:22])[0]
p = ret.pack()
# print(ret, p)
checksum = 0
p = struct.pack('!HHHH', PORT, sport, len(p) + 8, checksum) + p
udpsock.sendto(p, (src, sport))
pkt.drop()
else:
pkt.accept()
except KeyboardInterrupt:
pkt.accept()
raise
except Exception:
traceback.print_exc()
pkt.accept()
e = time.time()
print('%.3fms' % ((e - s) * 1000))
def main():
nfqueue = NetfilterQueue()
nfqueue.bind(1, handle_packet)
try:
nfqueue.run()
except KeyboardInterrupt:
print()
def quit(signum, sigframe):
raise KeyboardInterrupt
if __name__ == '__main__':
signal.signal(signal.SIGTERM, quit)
signal.signal(signal.SIGQUIT, quit)
signal.signal(signal.SIGHUP, quit)
subprocess.check_call(['iptables', '-I', 'INPUT', '-p', 'udp', '-m', 'udp', '--dport', str(PORT), '-j', 'NFQUEUE', '--queue-num', '1'])
try:
main()
finally:
subprocess.check_call(['iptables', '-D', 'INPUT', '-p', 'udp', '-m', 'udp', '--dport', str(PORT), '-j', 'NFQUEUE', '--queue-num', '1'])
@lilydjwg

This comment has been minimized.

Show comment
Hide comment
Owner

lilydjwg commented Apr 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment