IPTables DNS query limiting with burst rate

Presents the same content as „DNS-Query Limits mit iptables und Burstrate“

Since two months, give or take, I’m running an OpenNIC name server which provides lookup services from hostname to IP for every person in the world (more on the name server here). Every person, but sadly also every virus infected computer. The massive requests for mail servers already brought my router to it’s knees twice and made my internet connection unuseable.

Query Flood! Now what?

Benny Baumann’s blog provides tips, which specifically drop certain requests with simple iptables rules. Sadly I can’t just drop requests for the root-servers (public name servers must answer such queries) and the problematic requests are not just for a single domain. The only thing coming into consideration was request limiting. In doing so the maximum count of requests per time time interval (such as per second) is limited.

I was able to determine 5 requests per second as average per IP through questioning other OpenNIC admins and analysis of anonymized log files. Those settings helped, but as a consequence some application took longer to start. Clearly the requests per second were too tightly limited. The solution to this problem, is what I’d like to share with you.

The count of packets per second of a source IP is not measured over the time interval of one second, but over a longer period. This would normally reduce the count of requests per second even more (five per second is trivially more than five per ten seconds), so the count of requests is multiplied with the seconds. Now it’s entirely possible, to send all allowed requests in the first second of the interval, which would lead to an overload of the connection. To put paid to this, the count of requests per second is limited too, but to a higher than targeted value.

I limited the requests per second to 5, which leads to 35 requests in 7 seconds.
To solve the first-second burst, I allowed for 15 requests to happen in each of the seven seconds.

Write a script instead of blocking manually!

Here is the resulting script:

#!/bin/bash
# This script limits the queries per second to 5/s
# with a burst rate of 15/s and does not require
# buffer space changes

# Requests per second
RQS="15"

# Requests per 7 seconds
RQH="35"

iptables --flush
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --set --name DNSQF --rsource
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --update --seconds 1 --hitcount ${RQS} --name DNSQF --rsource -j DROP
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --set --name DNSHF --rsource
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --update --seconds 7 --hitcount ${RQH} --name DNSHF --rsource -j DROP

Ein Kommentar

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.