Hash: SHA256

Response Rate Limiting will help you mitigate dns amplification attacks

A little preview of what is going to be available on the next bind stable release.

If you ever operated a DNS server (what I am going to say is even more the case if your server is a resolver), you certainly encountered a time where your DNS server starts behaving nuts by sending a huge load of DNS responses. And if you do monitor the answers your server is sending out, you most likely have noticed that it was responding to ANY queries. This is one sign that your server is currently being used against your will to attack somebody.

I will not tell you how amplification attacks work; even though it is nothing more than spoofing the source IP address in the UDP packet and querying over and over the largest possible RRSET. There is plenty of articles out there.

What I will show here is a preview of what is going to be available in the next stable release (9.9.4) and is already available in the current 9.9.3 version if you have a Subscription version, namely Response Rate Limiting (RRL). I used the version 9.9.4-rc2 that I configured using the –enable-rrl switch and did built it by hand on a CentOS 6.4 using my CentOS 6.3 secured appliance, that I configured as an Authoritative nameserver.

All of the options are not yet clearly enough -imho- documented into the 9.9.4-rc2 Administration Reference Manual. But anyway here’s what you need to know:

You can define the rate-limit clause within an view or in the option clause. How the mecanism does work is the following:

Response rate limiting uses a ”credit” or ”token bucket” scheme. Each combination of identical response and client has a conceptual account that earns a specified number of credits every second. A prospective response debits its account by one. Responses are dropped or truncated while the account is negative. Responses are tracked within a rolling window of time which defaults to 15 seconds, but can be configured with the window option to any value from 1 to 3600 seconds (1 hour). The account cannot become more positive than the per-second limit or more negative than window times the per-second limit. When the specified number of credits for a class of responses is set to 0, those responses are not rate limited.
The notions of ”identical response” and ”DNS client” for rate limiting are not simplistic. All responses to an address block are counted as if to a single client. The prefix lengths of addresses blocks are specified with ipv4-prefix-length (default 24) and ipv6-prefix-length (default 56).
All non-empty responses for a valid domain name (qname) and record type (qtype) are identical and have a limit specified with responses-per-second (default 0 or no limit). All empty (NODATA) responses for a valid domain, regardless of query type, are identical. Responses in the NODATA class are limited by nodata-per-second (default responses-per-second). Requests for any and all undefined subdomains of a given valid domain result in NXDOMAIN errors, and are identical regardless of query type. They are limited by nxdomain-per-second (default responses-per-second). This controls some attacks using random names, but can be relaxed or turned off (set to 0) on servers that expect many legitimate NXDOMAIN responses, such as from anti-spam blacklists. Referrals or delegations to the server of a given domain are identical and are limited by referrals-per-second (default responses-per-second).
All requests that result in DNS errors other than NXDOMAIN, such as SERVFAIL and FORMERR, are identical regardless of requested name (qname) or record type (qtype). This controls attacks using invalid requests or distant, broken authoritative servers. By default the limit on errors is the same as the responses-per-second value, but it can be set separately with errors-per-second.
Many attacks using DNS involve UDP requests with forged source addresses. Rate limiting prevents the use of BIND 9 to flood a network with responses to requests with forged source addresses, but could let a third party block responses to legitimate requests. There is a mechanism that can answer some legitimate requests from a client whose address is being forged in a flood. Setting slip to 2 (its default) causes every other UDP request to be answered with a small truncated (TC=1) response. The small size and reduced frequency, and so lack of amplification, of ”slipped” responses make them unattractive for reflection DoS attacks. slip must be between 0 and 10. A value of 0 does not ”slip”; no truncated responses are sent due to rate limiting. Some error responses including REFUSED and SERVFAIL cannot be replaced with truncated responses and are instead leaked at the slip rate.
When the approximate query per second rate exceeds the qps-scale value, then the responses-per-second, errors-per-second, nxdomains-per-second and all-per-second values are reduced by the ratio of the current rate to the qps-scale value. This feature can tighten defenses during attacks. For example, with qps-scale 250; responses-per-second 20; and a total query rate of 1000 queries/second for all queries from all DNS clients including via TCP, then the effective responses/second limit changes to (250/1000)*20 or 5. Responses sent via TCP are not limited but are counted to compute the query per second rate.

What did I tell you, it’s no so clear. Let’s see how it works :

options {
	listen-on port 53 { any; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
	statistics-file "/var/named/data/named_stats.txt";
	memstatistics-file "/var/named/data/named_mem_stats.txt";
	allow-query { any; };
	recursion yes;
	version "[Secured]";
	rate-limit {
	    responses-per-second 5;
		nodata-per-second 1;
		ipv4-prefix-length 24;
		#log-only yes;

zone "." IN {
	type hint;
	file "named.ca";

zone "myzone.tld" {
	type master;
	file "myzone.tld.zone";

Let’s send some queries to the server and see how it behaves:

while true;do  dig +short www.myzone.tld @;sleep 0.1 ;done
	;; Truncated, retrying in TCP mode.
	;; Truncated, retrying in TCP mode.
	^C;; Truncated, retrying in TCP mode.
	^C;; Truncated, retrying in TCP mode.

We then see that our client has been slow down. Fine ! And here’s what is shown on the server side:

Sep  8 00:02:04 localhost named[1449]: client (www.myzone.tld): rate limit slip response to for www.myzone.tld IN A  (00a0aeef)
Sep  8 00:02:04 localhost named[1449]: client (www.myzone.tld): rate limit drop response to for www.myzone.tld IN A  (00a0aeef)
Sep  8 00:02:07 localhost named[1449]: client (www.myzone.tld): rate limit slip response to for www.myzone.tld IN A  (00a0aeef)
Sep  8 00:02:07 localhost named[1449]: client (www.myzone.tld): rate limit drop response to for www.myzone.tld IN A  (00a0aeef)
Sep  8 00:02:07 localhost named[1449]: client (www.myzone.tld): rate limit slip response to for www.myzone.tld IN A  (00a0aeef)
Sep  8 00:02:08 localhost named[1449]: client (www.myzone.tld): rate limit drop response to for www.myzone.tld IN A  (00a0aeef)

You now have a preview of what is possible to do, but I think setting up all the parameters will be a though thing as values would need to be continuously adapted depending on the usage of your server.

Comment: GPGTools - http://gpgtools.org


Hint: To validate signature, please view page source and copy html code between BEGIN PGP Signed message and END PGP Signature anchors.

Created the 2013-09-08

Share this


10 last articles

blog comments powered by Disqus