为什么这个命令会破坏网络?从 0.0.0.0/8 添加的 ip 规则无法访问

为什么这个命令会破坏网络?从 0.0.0.0/8 添加的 ip 规则无法访问

一次偶然的机会,我发现这ip rule add from 0.0.0.0/8 unreachable会破坏网络。即使在同一个 LAN 上 ping 也不起作用。我不明白为什么。

我记得0.0.0.0/8IPv4 地址块是保留的,只能由使用 DHCP 等的机器使用,以查找其真实 IP。这不是我的情况,所有主机都是静态配置的。我根本没想到会看到地址0.0.0.0。即使使用 DHCP,此类数据包也仅限于当前 LAN,不会被路由。

那么为什么该规则会阻止正常交通呢?

答案1

当套接字连接时(即:connect(2)使用系统调用)到 IPv4 目的地,它可以:

  • 任何一个bind(2)连接前到特定地址

  • 或不绑定,这与绑定到相同INADDR_ANY又名 0.0.0.0 用作占位符,直到确定要使用的实际源地址为止。

通常,各种路由条目决定源地址最终会变成什么,因为它不能保持 0.0.0.0:或者是暗示的源代码路由条目中的参数,或为此路由选择的接口上的主地址。

但由于额外的路由规则(这可能只是得到from 0.0.0.0/32 unreachable相同的结果)表中的初始路由查找主要的永远不会发生:

$ ip rule
0:  from all lookup local
32765:  from 0.0.0.0/8 unreachable
32766:  from all lookup main
32767:  from all lookup default

路由规则遍历将在条目优先级 32765 处停止,并且永远不会到达查找该条目的下一个条目。主要的路由表。在添加此路由规则之前,只有绑定套接字(包括已建立的连接)在未绑定套接字的情况下启动,因为源地址随后更新为实际地址,并且它们正在进行的流量仍然可以正常工作。


例如,假设系统接口上的地址为 192.0.2.2/24以太网0,然后尝试在侦听 5555/tcp 的服务上连接到 192.0.2.1:

socat tcp4:192.0.2.1:5555 -

将失败,因为此路由查找现在失败:

$ ip route get to 192.0.2.1
RTNETLINK answers: Network is unreachable

(与 相同ip route get from 0.0.0.0 to 192.0.2.1

尽管存在虚假路由规则,但首先显式绑定到 192.0.2.2 将会成功:

socat tcp4:192.0.2.1:5555,bind=192.0.2.2 -

出于同样的原因,此路由查找仍然成功:

$ ip route get from 192.0.2.2 to 192.0.2.1
192.0.2.1 from 192.0.2.2 dev eth0 uid 1000 
    cache 

源将与附加路由规则不匹配。

如果最初不存在虚假路由规则,则第一个示例将成功,并且如果稍后添加,连接的套接字将不再受到虚假路由规则的影响:0.0.0.0 地址将不再出现在任何查找中这个连接。


内核源代码中存在一些明确的答案,但这有点超出了我彻底遵循这一点的能力。对于connect(2)没有的情况,我可以说的是bind(2)

相关内容