This NFQUEUE function captures fragmented UDP DNS response and replaces it with TC=1 responses. DNS clients will retry DNS query in TCP mode.
iptables -t raw -A PREROUTING -p udp --sport 53 -j NFQUEUE --queue-num 1 --queue-bypass
./dnsfrag2tc.py 1
Without dnsfrag2tc
, we get large fragmented UDP response.
$ dig @199.6.0.30 isc.org MX +dnssec +ignore +bufsize=4096 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3710 ;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 6, ADDITIONAL: 27 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @199.6.0.30 isc.org MX +dnssec +ignore ;; MSG SIZE rcvd: 3251
If dnsfrag2tc
enabled, dig
does query in TCP mode.
$ dig @199.6.0.30 isc.org MX +dnssec +bufsize=4096 ;; Truncated, retrying in TCP mode. ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @199.6.0.30 isc.org MX +dnssec ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28547 ;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 6, ADDITIONAL: 27 ;; MSG SIZE rcvd: 3251
... This is because we got TC=1 response which dnsfrag2tc generated.
$ dig @199.6.0.30 isc.org MX +dnssec +ignore +bufsize=4096 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @199.6.0.30 isc.org MX +dnssec +ignore ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38868 ;; flags: qr tc rd; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; MSG SIZE rcvd: 12
dnsfrag2tc
doesn't touch non-fragmented responses.
$ dig @8.8.8.8 www.google.com ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @8.8.8.8 www.google.com ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29815 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; MSG SIZE rcvd: 59