I’ve been seeing the DNS ANY attack against my DNS servers. I’m using PDNS but this should work with BIND or any DNS server. My DNS servers are not recursive, but they are attacking me anyway. I guess I’m the DDOS amplifier.

If you think the same thing is happening to you you can detect the attack as follows:

tcpdump -n udp dst port 53|grep ANY

If you are being attacked you will see something like this:

07:32:20.736483 IP 95.130.170.57.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:20.744356 IP 203.217.178.77.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:20.884926 IP 95.130.170.57.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:20.932583 IP 80.241.214.70.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:20.975589 IP 203.217.178.77.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:20.991550 IP 95.130.170.57.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.207135 IP 203.217.178.77.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.349899 IP 95.130.170.57.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.399836 IP 85.25.119.152.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.432679 IP 203.217.178.77.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.454784 IP 95.130.170.57.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.605888 IP 80.241.214.70.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.663643 IP 203.217.178.77.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.884477 IP 85.25.119.152.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)
07:32:21.895233 IP 203.217.178.77.25345 > 184.105.182.241.domain: 10809+ [1au] ANY? isc.org. (36)

After hunting around on the internet I found some code that actually blocks it. This code works:

iptables -v -I INPUT 1 -p udp –dport 53 -m string –from 50 –algo bm –hex-string ‘|0000FF0001|’ -m recent –set –name dnsanyquery

iptables -v -I INPUT 2 -p udp –dport 53 -m string –from 50 –algo bm –hex-string ‘|0000FF0001|’ -m recent –name dnsanyquery –rcheck –seconds 10 –hitcount 3 -j DROP

This allows two ANY queries from an IP over 10 seconds. You can adjust it any way you want. The above code inserts these rules into the first 2. You might also want to just use append and put these in early in the list.

iptables -v -A INPUT -p udp –dport 53 -m string –from 50 –algo bm –hex-string ‘|0000FF0001|’ -m recent –set –name dnsanyquery

iptables -v -A INPUT -p udp –dport 53 -m string –from 50 –algo bm –hex-string ‘|0000FF0001|’ -m recent –name dnsanyquery –rcheck –seconds 10 –hitcount 3 -j DROP

 Is it working? You can test it as follows:

dig @dns.yourdomain.com isc.org ANY

It should word 2 times in a row and fail on the 3rd try. This will allow some diagnostic ANY queries but block the high volume DDOS attacks.

I also have some recursive name servers and I use them heavilly internally. But I also use them lightly externally. These name servers are still open to the world but I threw some rate limiting on them for external use. That way they can be open and yet not abused.

First you have to allow your own network full access:

iptables -v -A INPUT -t filter -s 192.168.1.0/24 -j ACCEPT

Then you rate limit other addresses:

iptables -v -A INPUT -p udp –dport 53 -m recent –set –name dnsanyquery
iptables -v -A INPUT -p udp –dport 53 -m recent –name dnsanyquery –rcheck –seconds 1 –hitcount 10 -j DROP

Here’s I’m allowing 10 hits per second which is far less than an attacker would send.