Instantly share code, notes, and snippets.

Embed
What would you like to do?
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.

Copy link
Owner Author

lilydjwg commented Apr 17, 2016

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