我无法根据目标地址字段(在这种类型的数据包中称为“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 个字节,因此icmpv6
以8800 8f7a e000 0000
icmpv6 主体紧随其后fe80 0000 0000 0000 02ff ffff feff fffe
。最后一部分根据 RFC是目标地址或tgt
。
现在让我们看看如何使用 过滤这些数据包ip6tables
。我发现了两个有趣的 netfilter 模块,string
和u32
。我没有弄清楚如何使用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
。