Prevent DNS attacks

Recently, our network suffered from heavy DNS attack, udp flood, reflection attack..etc.

After a lots of tcpdump, capturing data from the network, and we found there are a lot of IPs from China, resolving IP from our public DNS server (actually just open for all clients only).

And because of this, they flood our international circuit. DNS reflection attack work in the way as normal name service lookup, but attacker continuously send request to DNS server, and because return IP packet contain information that make the packet size 3-5 times larger than what attacker sent us.

To prevent this happen again, we have to restrict DNS server to reply recursion request only for known networks/hosts.

# cat /etc/named.conf
include "/etc/named.networks.acl"
options {
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; };
allow-recursion { localhost; authorized_net; }
recursion yes;
};

And I have create an acl contain those subnet managed by our company.

# cat /etc/named.networks.acl
acl "authorized_net" { 1.2.3.4/24, 1.2.3.5/24 }

On the other hand, limit the request rate from attacker is also needed. I have created follow firewall rules


iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -m recent --set --name HIGHF --rsource
iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -m recent --update --seconds 1 --hitcount 15 --name HIGHF --rsource -j LOG --log-prefix "DNS abuse 15/1s: "
iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -m recent --update --seconds 1 --hitcount 15 --name HIGHF --rsource -j DROP
iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -m recent --set --name LOWF--rsource
iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -m recent --update --seconds 7 --hitcount 35 --name LOWF --rsource -j LOG --log-prefix "DNS abuse 35/7s: "
iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -m recent --update --seconds 7 --hitcount 35 --name LOWF --rsource -j DROP

If you know about iptables command, you know what I did. Anyway, pretty straight forward, when high frequency query (attack) comes in more than 15hit/seconds, from a single source IP, the first rule trapped and packet DROP after log into /var/log/messages. LOWF handle 35hit per 7 seconds, and behalves same, DROP after log.


# iptables -L INPUT -vn
Chain INPUT (policy ACCEPT 598M packets, 40G bytes)
pkts bytes target prot opt in out source destination
15M 869M udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW recent: SET name: HIGHF side: source
11M 617M LOG udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW recent: UPDATE seconds: 1 hit_count: 15 name: HIGHF side: source LOG flags 0 level 4 prefix `DNS abuse 15/1s: '
11M 617M DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW recent: UPDATE seconds: 1 hit_count: 15 name: HIGHF side: source
4253K 252M udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW recent: SET name: LOWF side: source
0 0 LOG udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW recent: UPDATE seconds: 7 hit_count: 35 name: LOWF side: source LOG flags 0 level 4 prefix `DNS abuse 35/7s: '
0 0 DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW recent: UPDATE seconds: 7 hit_count: 35 name: LOWF side: source

Although iptables has dropped 11 million packets, but no client complains anymore.

Another alternative is built BIND 9.9.2 enable rate-limit feature, but I think above work-a-round is good enough at this moment.

Leave a Reply

Your email address will not be published. Required fields are marked *