Iptables – block DNS Amplification Attack by iptables

bindblockdomain-name-systemiptables

Last time I've got warings about DNS Amplification Attack from NFOservers.com DDoS notifier

2015-12-30 23:28:52.609178 IP (tos 0x0, ttl 54, id 42635, offset 0, flags [+], proto UDP (17), length 1500) my.dns.ip.addr.53 > 63.251.20.x.18150: 41159| 20/0/1 cpsc.gov. MX hormel.cpsc.gov. 5, cpsc.gov.[|domain]                                    
2015-12-30 23:28:52.609632 IP (tos 0x0, ttl 54, id 42636, offset 0, flags [+], proto UDP (17), length 1500) my.dns.ip.addr.53 > 63.251.20.x.18150: 41159| 20/0/1 cpsc.gov. MX stagg.cpsc.gov. 5, cpsc.gov.[|domain]                                 ..
2015-12-30 23:28:52.610109 IP (tos 0x0, ttl 54, id 42637, offset 0, flags [+], proto UDP (17), length 1500) my.dns.ip.addr.53 > 63.251.20.x.18150: 41159| 20/0/1 cpsc.gov. MX hormel.cpsc.gov. 5, cpsc.gov.[|domain]

For info

my.dns.ip.addr.53 – my VIP – external IP DNS address

63.251.20.x.18150 – dont know what this IP address range is

My server have to offer recursive queries for internal company network
I have configured in bind9 section:

 acl "trusted" {
 172.16.0.0/16;
 localhost;
 localnets;
 };
options {
...
allow-query { any; };
allow-recursion { trusted; };
allow-query-cache { trusted; };
...
}

I configured also RRL – Response Rate Limit:

rate-limit {
responses-per-second 5;
window 5;
};

Looks like my DNS server (bind9) refused bad queries like in the log:
http://pastebin.com/A3XGwh04

but I would like block such queries by iptables.
I'd do some research and found block by IPTABLES:

iptables -A INPUT  -p udp -m udp --dport 53 -m string --from 50 --algo bm --hex-string '|0000FF0001|' -m recent --set --name dnsanyquery --rsource
iptables -A INPUT  -p udp -m udp --dport 53 -m string --from 50 --algo bm --hex-string "|0000FF0001|" -m recent --name dnsanyquery --rcheck --seconds 10 --hitcount 1 -j DROP

but when I test my server from test machine with command:
dig +nocmd @my.ip.dsn.addr domain.com any +multiline +noall +answer I'm getting no answer from dns and in addition logs still are full of queries with cpsc.gov so I decided to back my default iptables configuration

Next research i've found that soultions made by conntrack but it may cause NAT problems. My DNS is NAT'ed

When used another soultion found here on other topics:

iptables -A INPUT -p udp --port 53 -m hashlimit --hashlimit 1/minute --hashlimit-burst 5 -j ACCEPT
iptables -A INPUT -p udp --port 53 -j DROP

got nagios warrings – SOA sync problem, domain SLAVE not found etc

My next try:

iptables --insert INPUT -p udp --dport 53 -m string --from 40 --to 56 --algo bm --hex-string '|637073632e676f76|' -j DROP -m comment --comment "DROP DNS Q cpsc.gov"
iptables --insert INPUT -p udp --dport 53 -m string --from 40 --to 50 --algo bm --hex-string '|6370736303676f763f|' -j DROP -m comment --comment "DROP DNS Q cpsc.gov"
-A INPUT -p udp -m udp --dport 53 -m string --string "cpsc.gov" --algo bm --from 40 --to 50 -m comment --comment "DROP DNS Q cpsc.gov" -j DROP

but still queries in logs

I'm still researching solution but maybe anyone here is much experienced with such attacks and can help me block queries like: cpsc.gov

query-errors: info: client 93.48.40.139#54822 (cpsc.gov): rate limit drop REFUSED error response to 93.48.40.0/24

Any help is appreciated.

VERY Important:
Even if I disable recursion for ALL, my logs are full of warings like rate limit drop REFUSED error response to thats why I want block it by iptables.

Best Answer

Honestly, it looks like your ACL is working as intended:

query-errors: info: client 93.48.40.139#54822 (cpsc.gov): rate limit drop REFUSED error response to 93.48.40.0/24

You're still getting the queries, but you're refusing to provide an answer to them. The rate limiting code is being invoked because the queries are still coming in volume and having to be refused by the nameserver.

As for the rest, a few things:

  • Don't use rate-limit with a recursive nameserver. It's not intended for use with recursive nameservers and generates those unnecessary log messages. That solves the log spam.
  • iptables isn't really going to help with this. If your goal is to make it to where the software never sees the queries, even if they're going to be rejected with a response of REFUSED anyway, that's well-intentioned but misguided. Either way your server is having to process the queries. One is having the kernel drop the traffic, the other is letting the software drop the traffic.

The value of preventing the software from seeing the bogus queries is mostly aesthetic. Most DNS admins aren't going to waste kernel cycles on doing something that the software is already doing. Whether you're dropping the traffic on the floor with a firewall or sending REFUSED packets back, your server has been put into a list of open resolvers and botnets are unlikely to stop sending you the traffic.

If you really want this traffic to go away, it's strongly recommended that you do not provide an internet facing listener on a recursive server that only services your devices. That way your DNS server doesn't have to waste userspace CPU rejecting the traffic or kernel CPU dropping the traffic.

Even if you go through with this as a learning exercise or with a goal of not sending any reply packets at all, this is a solution that doesn't scale. The DNS records being used in these attacks change every day, as does the IP address which is frequently spoofed.

You've asked for advice from people who "[have] experienced with such attacks", and constantly refusing unsolicited traffic is pretty normal for an internet facing DNS server. Doubly so for one that was formerly an open resolver. This type of solution is what those admins would usually not do, though I wish you well all the same.