Python UDP DNS to TCP DNS converter

I’m trying to use NFQUEUE and Scapy to convert any UDP DNS request to TCP DNS requests and then respond the UDP DNS request with a crafted UDP packet based on TCP DNS resonse. This is the script that I wrote so far:

#! /usr/bin/env python2.7
from scapy.all import *
from netfilterqueue import NetfilterQueue
import os
import dns.resolver

myResolver = dns.resolver.Resolver()

def resolv_dns(payload):
udp_query_pkt = IP(payload.get_payload())
domain = udp_query_pkt[DNS].qd.qname
ip_addrs = myResolver.query(domain, “A”, tcp=True)

if not udp_query_pkt.haslayer(DNSQR):
    if domain in udp_query_pkt[DNS].qd.qname:
        print str(ip_addrs[0])
        udp_resp_pkt = IP(dst=udp_query_pkt[IP].src, src=udp_query_pkt[IP].dst)/\\
                      UDP(dport=udp_query_pkt[UDP].sport, sport=udp_query_pkt[UDP].dport)/\\
                      DNS(id=udp_query_pkt[DNS].id, qr=1, aa=1, qd=udp_query_pkt[DNS].qd,\\
                      an=DNSRR(rrname=udp_query_pkt[DNS].qd.qname, ttl=10, rdata=str(ip_addrs[0])))

nfqueue = NetfilterQueue()
nfqueue.bind(1, resolv_dns)

os.system(“iptables -A OUTPUT -p udp --dport 53 -j NFQUEUE --queue-num 1”)
print “[*] waiting for data”
except KeyboardInterrupt:
os.system(“iptables -D OUTPUT -p udp --dport 53 -j NFQUEUE --queue-num 1”)
The problem with the script is that it doesn’t work!

Actually I can see the correponding DNS packets in the wireshark and they seems okay: enter image description here

But I can’t open any website! Actually the UDP DNS request timed out:

ebrahim@ebrahim:~$ dig

; <<>> DiG 9.10.3-P4-Ubuntu <<>>
;; global options: +cmd
;; connection timed out; no servers could be reached
What’s wrong?


After @Pierre’s answer, I changed the IPTable rule to send the received UDP DNS responses to the NFQUEUE (instead of sent DNS queries) and then I modified resolv_dns function as below(to replace IP address in the UDP DNS response with the new IP address which I received using TCP DNS query):

def resolv_dns(packet):
pkt = IP(packet.get_payload())
domain = pkt[DNS].qd.qname
ip_addrs = myResolver.query(domain, “A”, tcp=True)
pkt[DNS].an.rdata = str(ip_addrs[0])
But still it doesn’t work!