Preventing abuse of your DNS server
by ZetaGecko | 4 Comments | Server Administration
If you are running BIND on your server, here's a tip I discovered the hard way for reducing the probability of your server being abused. A few days ago, I started seeing major explosions in the amount of bandwidth running through my server. I scoured my Apache and email logs, looked at what processes were running, and tried a million other things to try to figure out where all that traffic was coming from. I ran tcptrack, and even in the midst of a major traffic burst, didn't see any unusual TCP activity.
Then I spent a little time figuring out how to use tcpdump, and quickly zeroed in on the source of the problem. I was see a huge amount of traffic on UDP port 53--the port used for most DNS queries. A slightly closer look revealed that most of that traffic was going to one IP address. A yet closer look suggested that the DNS queries were all for the same domain name, and it wasn't one of mine.
Here's what I think was happening: sombody was sending DNS query packets with a forged source address to my DNS server, which was sending much larger packets to the apparent source address. My server had probably been recruited to participate in a DDoS attack on that other server. They were abusing my server for this purpose because the responses it was sending back were much larger than the requests they were sending, enabling them to multiply the amount of traffic aimed at the target server. The solution? Block recursive queries from external sources.
What does that mean? A recursive query occurs when someone asks a DNS server for the IP address of a domain name that the DNS server isn't authoritative for. The DNS server finds the IP address from the authoritative server and sends it back to the requesting server. I want my server to do recursive queries for programs running on my server that need to be able to resolve domain names to IP addresses. However, there is no reason for my server to perform recursive queries for anyone else--or in other words, there's no reason for anyone to be asking my server for the IP addresses of domain names that my server is not authoritative for.
So, I want to allow programs on my server to ask my copy of BIND to perform recursive queries, but I don't want it performing them for anyone else. How did I configure that? It's very simple--it only takes a line in each of two configuration files. First, my resolv.conf file contains this line:
nameserver 127.0.0.1
That means that programs on my server should send DNS queries to the DNS server at IP address 127.0.0.1 (which as you may know is the "localhost" address--on every computer, it's an IP address used by that computer). That line was already there, so I didn't have to change that.
Second, I added one line to named.conf. The "allow-recursion" line in the "options" section specifies which IP addresses can request recursive queries from this server.
options {
allow-recursion { 127.0.0.1/32; };
// etc.
};
This means that recursive DNS requests coming from 127.0.0.1 (with all 32 bits being significant) are allowed. All other recursive requests are blocked.
As soon as I'd made that change and restarted BIND, my bandwidth consumption plummeted. It still wasn't all the way down to where it would normally be, because somebody was still sending me lots and lots of DNS requests. But since BIND wasn't responding to them anymore, the amount of bandwidth being consumed was pretty small.
November 3rd, 2005 at 5:16 am
Hey, I was just researching a similar problem.. I was trying to figure out why the domain port was using up so much traffic.. Thanks for the tip!
June 9th, 2010 at 4:31 am
brilliant one.I've used it and some improvement for sure
December 14th, 2011 at 3:36 pm
Great tip! Just set up my own name servers to serve around 100 domains and this was just what I was looking for. ;-)
February 19th, 2013 at 12:01 pm
You can also use rate limiting. There is a patch for BIND 9 here:
http://www.redbarn.org/dns/ratelimits