Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How to drop incoming negative DNS responses in Linux? (I want a timeout instead) I'm thinking of creating an iptables rule:

iptables -I INPUT -p udp --sport 53 -m u32 ...

From wireshark:

000E start of IP Packet (fixed, at first, I wrote 0010)
0022 start of UDP Packet
002A start of DNS message
002C  Flags
        .... .... .... 0000 = Reply code: No error (0)
        .... .... .... 0011 = Reply code: No such name (3)

I think the offset for -m u32 is counted from the ip header. Also subtracting 2 to get a 32bit.

$ echo $(( 0x002C - 0x000E - 2 ))

The mask for the last 4 bits is 0xF
So the rule should be something like this:

iptables -I INPUT -p udp --sport 53 -m u32 --u32 "28&0xF=3" -j DROP
share|improve this question
out of curiosity - why? – pQd Feb 10 '13 at 7:27
The negative answer comes first and dnsmasq returns it. Then comes the positive answer from a slow server – basin Feb 10 '13 at 7:42
@user447503 You're getting two answers, with different data, to a single query? Why? – Shane Madden Feb 10 '13 at 7:59
@Shane One is my ISP DNS, the other is the VPN DNS. I want to have both. – basin Feb 10 '13 at 8:08
up vote 3 down vote accepted

Offset for DNS flags in ip packet is 28bytes and you need to check last 2 bits in 2byte field u32 rule for that is "28&0x000F=0x03"

My test rule is: iptables -A INPUT -m u32 -p udp --sport 53 --u32 "28&0x000F=0x03" -j LOG

BTW I like the idea to use this firewall rule for split horizon DNS, going to test it for some of my networks.

share|improve this answer
I understood, except for the offset. Why it's not 26? I thought that --u32 checks a 4-byte field and you need to subtract 2 – basin Feb 10 '13 at 8:16
real offset is 30 bytes, but it's a bit longer rule: "0x1e&0x30000=0x30000" – DukeLion Feb 10 '13 at 8:26
(Edited). The offset that works is still 28: "28&0x0000000F=3". Thanks anyway – basin Feb 10 '13 at 8:26
You're right, 0x0F mask is more correct. – DukeLion Feb 10 '13 at 8:46

This drops BIND9 "rejected" replies to the current spoofed UDP queries!

iptables -F OUTPUT 
#iptables -A OUTPUT -p udp --sport 53 -j LOG --log-prefix="OUT-UPD-RAW : "
#iptables -A OUTPUT -m u32 -p udp --sport 53 --u32 "28&0xFFFF=0x8105" -j LOG --log-prefix="STOPPED-DNS-REJECTED-REPLY "
iptables -A OUTPUT -m u32 -p udp --sport 53 --u32 "28&0xFFFF=0x8105" -j DROP
iptables -A OUTPUT -p udp --sport 53 -j LOG --log-prefix="OUT-UPD-SENT: "
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.