DNS服务器自身极容易遭受攻击。由于DNS查询是UDP协议,没有握手过程,因此名字服务器难以识别请求的源地址是否真实有效。如果大量的假冒IP进行攻击,就造成服务器计算资源耗尽从而拒绝提供服务。
目前有效的全局预防方式是从源头制止这种攻击,即各ISP、IDC都严格执行BCP 38,拒绝非本网络的源IP对外发起请求。
除了直接攻击DNS服务外,还有一种情况是DNS服务器被利用来攻击别人,叫做反弹攻击。如果攻击者想攻击某个站点,他假冒这个站点的IP,对互联网上开放的DNS服务器发起查询,DNS服务器会将查询应答包返回给站点IP。由于开放的DNS服务器数量众多(比如运营商的递归服务器),攻击者只要同时往足够数量的DNS服务器发起查询,那么返回包到达后,巨大的流量就把目标站点淹没掉。
我们的一台公共解析NS服务器(用作Openstack的域名解析)就被人利用来进行了这种攻击。如下tcpdump截图:
上述请求的源IP是被攻击目标站点的IP(攻击方伪造),查询域名的类型是any,这种类型的查询会产生较大的响应包。数量众多的响应包返回到目标站点,导致目标站点被流量淹没。
为了避免DNS服务器被利用来进行反弹攻击,首先不要运行开放的递归查询服务器。对于递归服务器,可以设置防火墙,只允许自己的客户查询。如果必须面向公众,那么可以利用RRL、iptables来限制查询频率。
一个简单的iptables规则如下:
iptables -I INPUT -p udp --dport 53 -m state --state NEW -m recent --set iptables -I INPUT -p udp --dport 53 -m state --state NEW -m recent --update --seconds 60 --hitcount 1000 -j DROP
它的作用是,如果在1分钟内对DNS的查询频率超过1000次,就拦截掉该源IP。