If you are managing a Linux server, you’ve probably heard about DNS amplification attacks which make use of misconfigured DNS servers. DNS amplification is a DDoS technique which uses a large reply by DNS resolving the target. This is accomplished by spoofing the query with the source IP of the target victim to ask for a large DNS record, such as an ANY reply of the ROOT record or isc.org, which is most commonly found. The request itself is usually around 60-70 bytes, while the reply is as much as 2-3K. That’s why it’s called amplification. It will not only make your network participate in the attack, but it will also consume your bandwidth. More details can be found here.
Blocking these kinds of attacks can be tricky. However, there are some basic iptables rules that block most of it, using them in combination with fail2ban. As usual, your mileage might vary.
The commands below were tested and executed on Ubuntu Server 16.04 LTS 64-bit using fail2ban 0.10.
First, add this IPtables rule to your /etc/network/interfaces.tail so it’s automatically loaded each time your network interface(s) restart and/or your server (re)boots.
post-up iptables -A INPUT -p udp -m udp --dport 53 -m limit --limit 5/sec -j LOG --log-prefix "fw-dns " --log-level 7 post-up iptables -A INPUT -p udp --dport 53 -m string --from 50 --algo bm --hex-string '|0000FF0001|' -m recent --set --name dnsanyquery --mask 255.255.255.0 post-up iptables -A INPUT -p udp --dport 53 -m string --from 50 --algo bm --hex-string '|0000FF0001|' -m recent --name dnsanyquery --rcheck --seconds 1 --hitcount 1 -j DROP --mask 255.255.255.0
Note: –mask depends on your network configuration. Type ifconfig to find your mask.
The first iptables rule is for use with fail2ban. The second and third rule are used in conjunction with each other:
The second iptables rule looks for the incoming udp packets on port 53 and searches the first 50 of packet for hex string “0000FF0001” (which is equivalent to an ANY query) and saves it under dnsanyquery (under /proc/net/ipt_recent/dnsanyquery) with a timestamp.
The third iptables rule drops the packet if the source ip and query type (in this case “ANY”) matches and occurred more than one time in the past second.
Next, create the file /etc/fail2ban/filter.d/iptables-dns.conf with the following contents:
[Definition] failregex = fw-dns.*SRC=<HOST> DST ^.* security: info: client #.*: query \(cache\) './(NS|A|AAAA|MX|CNAME)/IN' denied ignoreregex =
And add the following to /etc/fail2ban/jail.local to ban the IP for 1 day (No jail.local file? Shame on you! Don’t edit the jail.conf file directly, It will be overwritten during updates. Instead, make & edit a copy like so: cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local)
[iptables-dns] # see https://freek.ws for more info enabled = true ignoreip = 127.0.0.1 filter = iptables-dns action = iptables-multiport[name=iptables-dns, port="53", protocol=udp] logpath = /var/log/kern.log bantime = 86400 findtime = 120 maxretry = 1
Finally, restart fail2ban and your network interface(s) or server to enable the rules. After doing so, check using fail2ban-client status if you see the ‘iptables-dns’ jail listed. If fail2ban refuses to start, check your regex for typos using fail2ban-regex /var/log/kern.log /etc/fail2ban/filter.d/iptables-dns.conf
That’s all folks! Comments or suggestions? Let me know in the comments!
Source: A Realistic Approach and Mitigation Techniques for Amplifying DDOS Attack on DNS in Proceedings of 10th Global Engineering, Science and Technology Conference 2-3 January, 2015, BIAM Foundation, Dhaka, Bangladesh, ISBN: 978-1-922069-69-6 by Muhammad Yeasir Arafat, Muhammad Morshed Alam and Feroz Ahmed.