Linux 上的 IPv6 NDP 欺骗预防

Linux 上的 IPv6 NDP 欺骗预防

我无法根据目标地址字段(在这种类型的数据包中称为“tgt”字段)过滤邻居通告数据包。

aa:bb:cc:dd:ee:ff当某些具有 MAC 地址的设备尝试使用该地址时2001:ffff:1002:51::,Wireshark 中将显示如下消息:

源码:fe80::aabb:ccff:fedd:eeff 夏令时:ff02::1 原始:ICMPv6(类型 136) 信息:邻居通告 2001:ffff:1002:51::(rtr)位于 aa:bb:cc:dd:ee:ff

tcpdump 中的相同数据包:

16:57:40.303118 IP6 fe80::aabb:ccff:fedd:eeff > ff02::1: ICMP6, neighbor advertisement, tgt is 2001:ffff:1002:51::, length 32

事实证明,没有办法用 ip6tables 过滤这些,因为它没有提供tgt在协议中指定字段的选项icmpv6。缺少这样的选项使得在基于 Linux 的路由器上防止 NDP 中毒攻击变得困难。早在 2010 年,netfilter 邮件列表中就有一个人做出了假设关于可能存在一种名为 ndptables 的工具作为用于 IPv4 的 arptables 的替代品,但是这个想法失败了。

我知道 SEcure Neighbor Discovery (SEND) 可以用于此,但我找不到有关如何在 Debian 或 Ubuntu 上配置它的任何有用信息。

在运行 Linux 的路由器上应该使用什么来过滤这些数据包?

答案1

我个人使用ipv6双栈ipv4,但你总是可以使用例如来ipv6 icmpv6阻止。firehol

ipv6 interface any v6interop proto icmpv6
  policy drop

如果你不想使用,firehol请尝试检查ip6tables此助手生成的规则是什么。更多信息Firehol 文档

根据评论进行编辑

我明白你的意思,并做了一些研究,让我与你分享:

如何根据目标地址 (tgt) 阻止 icmpv6 流量

首先让我们捕获一个我们想要阻止的数据包(136 = 邻居通告数据icmpv6包)

tcpdump -ttt -vvv -xx -n -i eno1 "icmp6 && ip6[40] == 136"

结果我得到了这个数据包

 00:00:05.054822 IP6 (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::2ff:ffff:feff:fffe > fe80::ec4:7aff:fed9:7d0e: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::2ff:ffff:feff:fffe, Flags [router, solicited, override]
          destination link-address option (2), length 8 (1): 00:ff:ff:ff:ff:fe
        0x0000:  00ff ffff fffe
        0x0000:  0cc4 7ad9 7d0e 00ff ffff fffe 86dd 6e00
        0x0010:  0000 0020 3aff fe80 0000 0000 0000 02ff
        0x0020:  ffff feff fffe fe80 0000 0000 0000 0ec4
        0x0030:  7aff fed9 7d0e 8800 8f7a e000 0000 fe80
        0x0040:  0000 0000 0000 02ff ffff feff fffe 0201
        0x0050:  00ff ffff fffe

IPv6 地址长度为 40 个字节,因此icmpv68800 8f7a e000 0000icmpv6 主体紧随其后fe80 0000 0000 0000 02ff ffff feff fffe。最后一部分根据 RFC是目标地址或tgt

现在让我们看看如何使用 过滤这些数据包ip6tables。我发现了两个有趣的 netfilter 模块,stringu32。我没有弄清楚如何使用string模块进行过滤,但u32效果很好。

假设tgt你想阻止的fe80::2ff:ffff:feff:fffe ip6tables规则是这样的

ip6tables -I INPUT 1 -p icmpv6 --icmpv6-type neighbor-advertisement -m u32 --u32 "48=0xfe800000 && 52=0x00000000 && 56=0x02ffffff && 60=0xfefffffe" -j LOG --log-prefix "Bad neighbor-advertisement tgt:"

请注意,我不想阻止它,只是记录给定的数据包以查看规则是否匹配。

Aug 20 09:45:24 squanchy kernel: Bad neighbor-advertisement tgIN=eno1 OUT= MAC=0c:c4:7a:d9:7d:0e:00:ff:ff:ff:ff:fe:86:dd SRC=fe80:0000:0000:0000:02ff:ffff:feff:fffe DST=fe80:0000:0000:0000:0ec4:7aff:fed9:7d0e LEN=72 TC=224 HOPLIMIT=255 FLOWLBL=0 PROTO=ICMPv6 TYPE=136 CODE=0

我再次firehol在服务器上运行,因此日志与原始日志略有不同ip6tables

PS 请注意这里的规则是基于tgt而不是看起来与字段相同的源地址tgt

相关内容