我正在尝试从 Win 10 主机 ping 一台 Linux 虚拟机。IPv4 运行正常,但尝试使用本地 IPv6 地址会按照以下模式周期性地丢弃数据包。
有人能解释这里发生的事情吗?
ping -6 -t fe80::dead:beef
Request timed out.
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Reply from fe80::dead:beef: time<1ms
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
答案1
总结
很久以前,我无意中在Block all incoming connections
公共网络上设置了与 IPv6 连接有关的“陷阱”,即告诉 Windows 防火墙。这阻碍了 IPv6 连接,因为只允许 IPv6 的“邻居检测/可达性”机制的一个方向按预期工作,导致观察到“仅在短时间内工作”模式(对于 ping 请求)。同时,IPv4 连接从未受到影响,因为等效的 ARP 协议从未被 Win 10 防火墙阻止(由于位于第 2 层)。所以多年来一切都运行良好,我甚至忘记设置“全部阻止”,直到有一天我决定最终开始研究在我的计算机上使用 IPv6。
解释:
IPv6 邻居可达性检测
由于 ARP 一直都是“刚好能满足我的需求”的东西,所以我犯了一个错误,跳过了 MAC 解析和邻居可达性机制在 IPv6 中的工作方式。事实证明,两种类型的 ICMPv6 协议(135,“邻居请求”和 136“邻居通告”)与 ARP 请求/回复起着同等的作用。而且由于 ICMPv6 协议位于 IPv6 之上,因此它像所有其他 IPv6 数据包一样受防火墙过滤规则的约束。
Win 10 和 Linux VM 都有 IPv6“邻居表”(相当于 IPv4 ARP 表)。在 Win 10 上,可以使用 显示netsh interface ipv6 show neighbors
,在 Linux 上,可以使用 显示ip -6 neighbor
。每个条目都有少数几种状态之一(INCOMPLETE、REACHABLE、STALE、DELAY、PROBE 等)。
我没有仔细阅读 RFC(参见https://www.rfc-editor.org/rfc/rfc4861),但根据以下文章(https://www.ccexpert.us/routing-tcp-ip-2/neighbor-unreachability-detection.html,https://mrncciew.com/2019/10/03/ipv6-neighbor-discovry/)结合邻居表和wireshark数据包转储的实时观察,我得出以下结论:
对于基于 TCP 的连接,邻居表条目在 30 秒不活动后会变为“STALE”。对于无连接 UDP/ICMP(v6) 数据包,无论是否有活动,条目在 30 秒后都会变得陈旧,因此主机会发送 NS(在 IPv6 上)或 ARP 请求(IPv4)数据包来查询其对应方,如果收到响应,则状态在接下来的 30 秒内设置为“REACHABLE”,依此类推。
Win 10 和 Linux 似乎实现了不同数量的(中间)状态。
由于两个主机之间的邻居表条目可能处于不同的状态,并且 Win 10 防火墙仅允许 Win 10 -> VM 邻居请求数据包得到应答,而不允许 VM -> Win 10 NS 数据包得到应答,因此可能会发生非平凡的交互。
例如,观察到成功传送的回显回复包与丢弃的回显回复包的“爆发”现象,这是 Linux VM 的邻居表条目在收到第一个 ping 请求时处于“FAILED”状态的副产品,由于其 NS 数据包未得到答复,将返回此状态,并且不会发送回显回复。另一方面,在 Win 10 发送 NS 以刷新其自己的 STALE 邻居表条目(并收到 NA 答复)后,Linux VM 的相应邻居表条目现在也将暂时处于 DELAYED 状态,从此状态它可以答复回显回复,直到它发出的 NA 探测(总共三个)超时并且其状态返回到 FAILED 状态。
或者,直飞忙碌的TCP 连接还会使 Linux VM 邻居表条目始终处于“可访问”状态,以便所有 ping 请求都会得到答复。
防火墙
如上所述,主要问题是:
了解“类似 ARP 的功能”是通过 IPv6 中的 ICMPv6 实现的
记得几年前曾设定过一个不明显的设置。
忘记已经设置了上述不太明显的设置,并得出结论“这不可能是防火墙”,因为“我已经将所有 ICMPv6 数据包列入白名单,但它仍然不起作用......”