![通过 iptables 阻止 DNS 放大攻击](https://linux22.com/image/674526/%E9%80%9A%E8%BF%87%20iptables%20%E9%98%BB%E6%AD%A2%20DNS%20%E6%94%BE%E5%A4%A7%E6%94%BB%E5%87%BB.png)
上次我收到了来自 NFOservers.com DDoS 通知程序的有关 DNS 放大攻击的警告
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]
详细信息
my.dns.ip.addr.53 - 我的 VIP - 外部 IP DNS 地址
63.251.20.x.18150 - 不知道这个 IP 地址范围是什么
我的服务器必须为我在 bind9 部分配置的内部公司网络提供递归查询:
acl "trusted" {
172.16.0.0/16;
localhost;
localnets;
};
options {
...
allow-query { any; };
allow-recursion { trusted; };
allow-query-cache { trusted; };
...
}
我还配置了 RRL – 响应率限制:
rate-limit {
responses-per-second 5;
window 5;
};
看起来我的 DNS 服务器(bind9)拒绝了错误查询,如日志中所示: http://pastebin.com/A3XGwh04
但我想通过 iptables 阻止此类查询。我做了一些研究,发现可以通过 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
但是当我使用命令从测试机测试我的服务器时: dig +nocmd @my.ip.dsn.addr domain.com any +multiline +noall +answer我没有从 DNS 获得任何答案,此外日志仍然充满了查询美国消费品安全委员会所以我决定恢复我的默认 iptables 配置
下一步研究我发现 conntrack 会解决问题,但可能会导致 NAT 问题。我的 DNS 被 NAT 了
当使用在此处关于其他主题上发现的另一个灵魂时:
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
遇到了 nagios 问题 - SOA 同步问题、找不到域 SLAVE 等
我的下一次尝试:
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
但日志中仍有查询
我仍在研究解决方案,但也许这里的任何人都对此类攻击有丰富的经验,并且可以帮助我阻止以下查询: 美国消费品安全委员会
query-errors: info: client 93.48.40.139#54822 (cpsc.gov): rate limit drop REFUSED error response to 93.48.40.0/24
任何帮助都将受到赞赏。
很重要: 即使我禁用所有递归,我的日志仍然充满类似速率限制下降 REFUSED 错误响应这就是为什么我想用 iptables 来阻止它。
答案1
老实说,看起来你的 ACL 正在按预期运行:
查询错误:信息:客户端 93.48.40.139#54822 (cpsc.gov):速率限制下降拒绝错误响应 93.48.40.0/24
您仍在接收查询,但拒绝提供答案。速率限制代码被调用,因为查询仍然大量涌入,并且必须被名称服务器拒绝。
至于其余的,有几件事:
- 不要
rate-limit
与递归名称服务器一起使用。它不适用于递归名称服务器,并且会生成那些不必要的日志消息。这解决了日志垃圾邮件问题。 iptables
对此并没有真正的帮助。如果你的目标是让软件永远看不到查询,即使它们将被拒绝并给出REFUSED
无论如何的响应,那么这是善意的但却是错误的。无论哪种方式,你的服务器都必须处理查询。一种是让内核丢弃流量,另一种是让软件丢弃流量。
阻止软件看到虚假查询的价值主要是美观。大多数 DNS 管理员不会浪费内核周期去做软件已经在做的事情。无论您是使用防火墙丢弃流量还是发回 REFUSED 数据包,您的服务器都已被放入开放解析器列表中,僵尸网络不太可能停止向您发送流量。
如果你真的想让这些流量消失,强烈建议你不要在只为你的设备提供服务的递归服务器上提供面向互联网的侦听器。这样你的 DNS 服务器就不会有浪费用户空间 CPU 来拒绝流量或内核 CPU 来丢弃流量。
即使你将其作为学习练习或以不发送任何回复数据包为目标,这也是一个无法扩展的解决方案。这些攻击中使用的 DNS 记录每天都在变化,经常被欺骗的 IP 地址也是如此。
您曾向“经历过此类攻击”的人寻求建议,对于面向互联网的 DNS 服务器来说,不断拒绝未经请求的流量是很正常的。对于以前是开放解析器的 DNS 服务器来说更是如此。这些管理员通常会采用这种解决方案不是尽管我仍然祝你一切顺利。
答案2
如果您想探索 iptables DNS 速率限制和过滤,您可能会研究做这样的事情。
有关根任何/所有查询过滤器字符串匹配的详细信息如下:
https://forums.centos.org/viewtopic.php?f=51&t=62148&sid=3687bf227875a582ba08964fca178dd2
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DNS_DROP - [0:0]
:DYN_DROP - [0:0]
-A PREROUTING -i lo -j ACCEPT
-A PREROUTING -i eth0 -s <our.net.work.space>/21 -j ACCEPT
-A PREROUTING -m recent --rsource --update --seconds 86400 --name DYN_DROP_LIST -j DROP
-A PREROUTING -p udp -m udp --dport 53 -j DNS_DROP
-A PREROUTING -p tcp -m tcp --dport 53 -j DNS_DROP
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth0 -d <our.net.work.space>/21 -j ACCEPT
-A OUTPUT -m recent --rdest --update --seconds 86400 --name DYN_DROP_LIST -j DROP
## Permanent DNS drop list (ipset)
-A DNS_DROP -m set --match-set PERM_DNS_DROP src -j DROP
## DNS - UDP progressive rate limit
-A DNS_DROP -p udp -m hashlimit --hashlimit-above 1/sec --hashlimit-burst 5 --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-htable-expire 10000 --hashlimit-name DNS_LIMIT_UDP -j DROP
-A DNS_DROP -p udp -m hashlimit --hashlimit-above 10/min --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-htable-expire 120000 --hashlimit-name DNS_LIMIT_UDP2 -j DROP
-A DNS_DROP -p udp -m hashlimit --hashlimit-above 4/min --hashlimit-burst 15 --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-htable-expire 240000 --hashlimit-name DNS_LIMIT_UDP3 -j DROP
## DNS - TCP progressive rate limit
-A DNS_DROP -p tcp -m hashlimit --hashlimit-above 6/sec --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-htable-expire 10000 --hashlimit-name DNS_LIMIT_TCP -j DROP
-A DNS_DROP -p tcp -m hashlimit --hashlimit-above 60/min --hashlimit-burst 60 --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-htable-expire 120000 --hashlimit-name DNS_LIMIT_TCP2 -j DROP
-A DNS_DROP -p tcp -m hashlimit --hashlimit-above 24/min --hashlimit-burst 90 --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-htable-expire 240000 --hashlimit-name DNS_LIMIT_TCP3 -j DROP
## DNS - UDP & TCP root any/all query filter
-A DNS_DROP -p udp -m string --hex-string "|0000ff0001|" --algo bm --from 40 -j DYN_DROP
-A DNS_DROP -p tcp -m string --hex-string "|0000ff0001|" --algo bm --from 52 -j DYN_DROP
## Dynamic Drop List
-A DYN_DROP -m recent --rsource --set --name DYN_DROP_LIST -j DROP