I'm running my own authoritative DNS server for my own domains, and I've been dealing with an ongoing problem of DNS amplification attacks using the ANY query type. Considering the world should never have to do ANY queries against my server, I want to filter this out.

However: BIND doesn't have a mechanism for that. (I'm running BIND on Windows for this, on a multi-purpose server - the amount of queries doesn't require a fine-tuned O.S.)

I've now set up the following to work around this: A local installation of Linux in a VM to have access to iptables (which seems to be the only thing able to filter on strings in any packet) running debian (console) using a bridged eth0 interface in the same subnet as the host server.

My question: How do I setup this Linux by using iptables to filter the incoming UDP packets by string ("*") and redirect the allowed packets to the ip address of the host server?

Or, is there a (Windows server 2003) native Windows solution to achieve this? (one could hope...)

Thanks in advance!


EDIT: ANY records are a request for "*", would that be too generic?

  • Um, not really. ANY is mostly used to get many information in one go. For example, suppose someone is trying to resolve www.example.com. "www.example.com" can be an actual hostname or an alias. In the first case, requesting "A" will return the address. In the latter case, requesting "A" will not get a reply, and the requester would have to request "CNAME", followed by another "A" for the actual canonical name. By requesting for "ANY", the requester can quickly see if the name is an actual hostname or an alias.
    – pepoluan
    Feb 23, 2012 at 6:43
  • I'm sorry, but I think you are mistaken. unless the alias is external, the dns server will dutifully return an IP address if an A record is requested on an alias. Requesting ANY will always give back more records than is required for normal operation. And even in your scenario, it's not required (and blocking them would prevent abuse by doing ANY requests on example.com and have a really large response of all records in that domain)
    – Mark
    Feb 23, 2012 at 11:32
  • I correct myself, you were right, actually. CNAME will trigger a second lookup, regardless. But still: I hardly use CNAME records and 2 minimal requests is still better than getting the entire zone file response, pretty much. And how would a large ANY response be any better for a resolver? it would then have to do a recursive internal check to find out CNAME IPs
    – Mark
    Feb 23, 2012 at 11:55
  • Well, my example was with "www.example.com", not "example.com", so there should be no arbitrary information like SOA, NS, TXT, etc. Without ANY, the resolver will ask for A, upon failure, it will then ask for CNAME, followed by a recursive A. With ANY, it will either get an A or a CNAME. If the latter, then it will recursively query for the A. As you can see, the resolver ends up with at most 2 queries, instead of 3 had the resolver not use ANY.
    – pepoluan
    Feb 23, 2012 at 15:03
  • I noticed you've edited your question by specifying the QNAME of "". If that's your situation (ANY for ""), I can see how that's a problem. I'll think of something; the problem is that DNS queries are binary messages, and the QNAME can be anywhere. But yours is an interesting problem nonetheless. I'll do done research and hopefully can provide you with an answer tomorrow.
    – pepoluan
    Feb 23, 2012 at 15:06

2 Answers 2


Allegedly, the reason you are asking is that you do not want to have DNS amplification attacks use your infrastructure.

An approach using netfilter/iptables has actually been discussed on different DNS-related mailing lists and newsgroups at the time of writing of the question. The consensus here is mainly that disabling certain query types altogether is not a good solution for DNS amplification attack prevention. It is usually sufficient to disable recursion for public clients which has been the default BIND configuration since BIND 9.4.1-P1.

If you can't disable recursion, one of the possible solutions presented by Stephane Bortzmeier is using a python script to construct netfilter rules which can subsequently be used for rate-limiting certain types of queries for specific DNS labels:

You can do it outside of the name server, also. For instance, on Linux, if the QNAME is fixed, let's say 'bad.example':

1) Get http://www.bortzmeyer.org/files/generate-netfilter-u32-dns-rule.py

2) Run it with the proper options:

rule=$(python generate-netfilter-u32-dns-rule.py --qname bad.example --qtype ANY) 

3) Use the output in a Netfilter rule:

iptables -A INPUT -p udp --dport 53 --match u32 --u32 "$rule" -j RATELIMITER 

4) Rate-limit:

iptables -A RATELIMITER -m hashlimit \ 
   --hashlimit-name DNS --hashlimit-above 20/second --hashlimit-mode srcip \ 
   --hashlimit-burst 100 --hashlimit-srcmask 28 -j DROP 

I use these set of rules to drop the most frequent DNS amplification attack queries:

# isc.org
iptables -A INPUT -i eth0 -p udp --dport 53 -m string --algo bm --hex-string '|697363036f7267|' -j DROP

# NS? .
iptables -A INPUT -i eth0 -p udp --dport 53 -m string --algo bm --hex-string '|010000010000000000000000020001|' -j DROP

# ripe.net
iptables -A INPUT -i eth0 -p udp --dport 53 -m string --algo bm --hex-string '|0472697065036e6574|' -j DROP

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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