我有一台带有两个接口(eth0 和 eth1)的 ubuntu 机器。 Eth0 接口具有 dhcp 地址,eth1 具有 apipa (169.254.xx) 地址。 eth1 未连接,eth0 连接到本地网络。从我的桌面(也连接到同一网络)我可以 ping 169.254.xx 地址并可以执行 scp 等。
这怎么可能?没有启用路由。
答案1
只是为了澄清:APIPA是 Microsoft 的原始命名,已标准化为IPv4 链路本地地址的动态配置(IPv4LL)。
以下是可能发生的情况:
桌面本身有一条通往 IPv4LL LAN 的路由,可能除了通过 Ubuntu 使用的相同 DHCP 获得的更“经典”路由之外,例如专用 LAN 192.168.1.0/24。
Ubuntu 本身有一个 IPv4LL 地址以太网1,比方说 169.254.5.6
当 Desktop 自联机(可直接访问)起寻找 169.254.5.6 时,它会以广播形式发送 169.254.5.6 的 ARP 请求,
Ubuntu 接收广播。作为 Linux 主机,它遵循弱宿主模型:添加到其接口的 IP 地址属于主机而不是其接口。对于 IPv4 来说都是如此和对于 ARP,如文档中所述
arp_filter
环境:
arp_filter
- 布尔值[...]
0
-(默认)内核可以用来自其他接口的地址响应 arp 请求。这看起来可能是错误的,但通常是有道理的,因为它增加了成功沟通的机会。 IP 地址由 Linux 上的整个主机拥有,而不是由特定接口拥有。仅对于负载平衡等更复杂的设置,此行为才会导致问题。
所以它回答分配给 169.254.5.6 的 ARP 请求以太网1,但是在以太网0在被问到的地方,使用以太网0的以太网 MAC 地址。
桌面现在已解析第 2 层以太网地址,更新其 ARP 表并向 Ubuntu 的 169.254.5.6 发送 IPv4 ICMP 回显请求数据包,其中目标 MAC 地址为 Ubuntu 的 eth0 MAC 地址,
Ubuntu,遵循弱主机模型,使用 IPv4 ICMP 回显回复请求。由于 OP 告诉它正在工作,这进一步意味着:
桌面源地址也是 IPv4LL,Ubuntu 上也有 169.254.0.0/16 路由以太网0具有较低的度量(或者如果相等的话首先使用),所以回复出现在右侧,
或者更可能的是,桌面没有使用 IPv4LL 源来查询 IPv4LL 地址 169.254.5.6,因此它与 Ubuntu 的 IP 地址位于同一 IP 网络(由 DHCP 设置)中以太网0Ubuntu 也在右侧回答(因为它的路由表在 eth0 上有一个类似 192.168.1.0/24 的条目)。这种情况(不使用 IPv4LL 源)是由RFC:
当 IPv4 链路本地地址和可路由地址在同一接口上可用时,应优先选择可路由地址作为
新通信的源地址,但从 IPv4 链路本地地址发送或发送到
IPv4 链路本地地址的数据包仍按预期传送。
假设我的解释中没有遗漏任何内容,那么是哪种情况?
当然,这种行为并不完全正确。因为每个广播域都应该有自己的私有 IPv4LL LAN,并且不能将地址泄露给其他域。
这在实践中意味着,如果具有默认配置的 Linux 主机参与多个此类 IPv4LL 网络(每个接口一个),它可能(不确定,见下文)不允许任何其他系统使用其自己的任何 IPv4LL 地址,或者即使它们不在同一侧,也无需切换自己的 IPv4LL 地址,因为碰撞检测。但在实际应用中,仍然因为Weak Host Model的原因,默认情况下会有多条到169.254.0.0/16的路由进入该地多宿主(错误)配置。通常只有一条路线可以正常工作:第一个路线等于显示的ip route show 169.254.0.0/16
。其他人可能有有效的 ARP,但可能没有有效的 IP 路由。这需要正确配置主机以实现多宿主(在这种情况下,它可能会停止应答发送到上面“错误”接口的 ARP,并且不会触发此问题),并且与 IPv4LL 集成也无济于事。大多数情况下,IPv6 不会发生这种情况,因为任何链路本地地址的使用都必须包含接口。