iptables:建立一套防止滥用 DNS 放大攻击的规则

Tif*_*ker 6 security domain-name-system linux firewall iptables

我一直致力于构建规则集来检测和阻止 DNS 放大攻击。

我被卡住了,希望能在这里找到帮助。

我将在这里发布我所拥有的(bash 脚本,与 DNS 相关的部分):

IPTABLES='/sbin/iptables -v' 
SERVERIP=a.b.c.d

echo '################ Previously initiated and accepted exchanges bypass rule checking #'
$IPTABLES --append INPUT  -m state --state ESTABLISHED,RELATED     --jump ACCEPT
echo '################################################ Allow unlimited outbound traffic #'
$IPTABLES --append OUTPUT -m state --state NEW,ESTABLISHED,RELATED --jump ACCEPT

echo '################################################################## Rules for DNS #'
# DIG ANY ISC.ORG attack preventer.
# QUESTION1: this one does not work, why!?!?
$IPTABLES --append INPUT --proto udp --dport 53 -m string --string "isc.org" --algo bm --to 65535 --jump LOG --log-prefix "iptables: UDP ISC0 "

$IPTABLES --append INPUT --proto udp --dport 53 -m string --hex-string "|03697363036f726700|" --algo bm --to 65535 --jump LOG --log-prefix "iptables: UDP ISC "
$IPTABLES --append INPUT --proto udp --dport 53 -m string --hex-string "|03697363036f726700|" --algo bm --to 65535 --jump DROP

# DNS DNSIPSOK list
$IPTABLES --new DNSFLOODRULES
$IPTABLES --append DNSFLOODRULES --source 127.0.0.1 --jump RETURN
$IPTABLES --append DNSFLOODRULES --source $SERVERIP --jump RETURN
$IPTABLES --append DNSFLOODRULES --jump LOG --log-prefix "iptables: UDP BLOCK "
$IPTABLES --append DNSFLOODRULES --jump ACCEPT
#$IPTABLES --append DNSFLOODRULES --jump DROP
# I have it turned off right now, because 

echo '# S & D port rules'
# DNS limit rule for standard acceptance
# QUESTION2: can't get the connbytes to work properly :(
$IPTABLES --append INPUT --proto udp --source 0/0 --dport 53 \
    -m state --state NEW \
    -m connbytes --connbytes 75 --connbytes-dir reply --connbytes-mode bytes
    -m limit --limit 1/s --limit-burst 10 --jump ACCEPT 
# DNS log / drop the abusers EXEPT the whitelisted IP numbers
$IPTABLES --append INPUT --proto udp --source 0/0 --dport 53 -m state --state NEW --jump DNSFLOODRULES
$IPTABLES --append INPUT --proto udp --source 0/0 --sport 53 -m state --state NEW --jump DNSFLOODRULES
# DNS allow the whitelisted IP numbers
$IPTABLES --append INPUT --proto udp --source 0/0 --dport 53 -m state --state NEW --jump ACCEPT
$IPTABLES --append INPUT --proto udp --source 0/0 --sport 53 -m state --state NEW --jump ACCEPT
Run Code Online (Sandbox Code Playgroud)

QUESTION1:为什么它需要是十六进制字符串,普通的会更容易维护,但那个不会字节,你能告诉我为什么吗?

问题 2:通过 TCPdump 我可以看到大多数答案都很小,因此需要将它们列入白名单。还有本地主机(以及我自己的一些服务器,我广泛地查询名称服务器(DNSFLOODRULES)。DNS 放大攻击是“大”答案的持续激增,我想限制这些答案。问题是我无法获得 ' connbytes 的部分工作。我一直在摸索它,也认为它应该是 OUTPUT 的艺术,因为它与答案的大小有关,而不是问题。我还尝试了“允许无限出站”交通的部分,但这是非常错误的。

非常感谢您的想法和帮助。

Seb*_*ger 1

问题一:

该字符串不匹配,因为“.” 不包含在数据包中。DNS 数据包不包含“主机名”本身,而是包含“标签”。在数据包中,域名的每个部分都是一个标签,前缀为标签的字节数。

所以“isc.org”翻译为:

isc: 03 69 73 63
org: 03 6f 72 67
Run Code Online (Sandbox Code Playgroud)

或者在数据包中:

03697363036f7267
Run Code Online (Sandbox Code Playgroud)

每个标签限制为 63 个字节,整个名称限制为 255 个字节。

DNS RFC 中对此进行了解释:

https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4

https://www.rfc-editor.org/rfc/rfc1035#section-4.1.2

问题2:

您需要启用 net.netfilter.nf_conntrack_acct 标志才能使用 conntrack 选项(请参阅iptables联机帮助页)。但我认为这样使用它并不明智。总会有大数据包的合法答案。

也许您最好使用 hashlimit 扩展。已经提到过:

https://lists.dns-oarc.net/pipermail/dns-operations/2012-October/009321.html