为什么我的 Linux 机器会对其子网之外的 IP 地址发出 ARP 请求?

为什么我的 Linux 机器会对其子网之外的 IP 地址发出 ARP 请求?

我的 Linux 服务器是一台连接了 1 个 nic(带有 ip 192.168.20.43)的虚拟机,使用以下ip a命令进行观察:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:f5:e5:67 brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.43/24 brd 192.168.20.255 scope global noprefixroute enp1s0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fef5:e567/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

其默认网关192.168.20.254如下ip route命令观察:

default via 192.168.20.254 dev enp1s0 proto static metric 100
192.168.20.0/24 dev enp1s0 proto kernel scope link src 192.168.20.43 metric 100

从上面我们还可以看出,网络掩码是合理的24位。

由此我们可以看出 IP​​v4 地址192.168.30.66外部定义的子网,因此只能通过默认网关访问。

那么为什么我可以在请求来自的流量时使用on并tcpdump观察enp1s0来自的 arp 请求?192.168.20.43192.168.30.66192.168.30.66

tcpdump 命令如下tcpdump -nnni enp1s0 host 192.168.30.66,我们观察到:

11:54:53.130897 IP 192.168.30.66.443 > 192.168.20.43.40862: Flags [.], seq 12922:14320, ack 917, win 227, options [nop,nop,TS val 3119187172 ecr 2528097971], length 1398
11:54:53.131013 IP 192.168.20.43.40862 > 192.168.30.66.443: Flags [.], ack 37962, win 835, options [nop,nop,TS val 2528101021 ecr 3119184135,nop,nop,sack 1 {12922:14320}], length 0
11:54:55.247778 ARP, Request who-has 192.168.30.66 tell 192.168.20.43, length 28
11:54:55.248505 ARP, Reply 192.168.30.66 is-at e0:db:55:70:db:75, length 46

我的印象是,不应对子网外的 IP 地址发出 ARP 请求,不管两个子网是否位于同一个第 2 层以太网段(这就是发生回复的原因)。

答案1

原因在于路由器。但是OPtcpdump的过滤器错过了要捕获的相关数据包:ICMP 重定向来自路由器,告诉每台主机它可以直接访问另一台主机。

由于路由器是单臂路由器,其在同一接口上具有 IP LAN 192.168.20.0/24 和 192.168.30.0/24,因此具有相同的以太网广播域,因此它正确推断出从使用 192.168.20.0/24 的主机到使用 192.168.30.0/24 的对等端的 IPv4 通信可以直接完成,不需要路由器工作。

考虑如下配置的Linux路由器:

# ip route
default via 192.0.2.1 dev wan0 metric 100 
192.0.2.0/24 dev wan0 proto kernel scope link src 192.0.2.2 metric 100 
192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.254 metric 100 
192.168.30.0/24 dev eth0 proto kernel scope link src 192.168.30.254 metric 100 

当两台主机之间通过路由器进行此类通信时,它会以缓慢的速率发送如下 ICMP 重定向:

17:35:35.317159 IP 192.168.30.254 > 192.168.30.66: ICMP redirect 192.168.20.43 to host 192.168.20.43, length 92

17:35:36.329965 IP 192.168.20.254 > 192.168.20.43: ICMP redirect 192.168.30.66 to host 192.168.30.66, length 92

当对等端收到此类信息时,它们将(懒惰地,可能在收到多个 ICMP 重定向后)安装临时路由缓存以覆盖正常路由(即使正常路由缓存在 Linux 3.6 中已经消失,特殊用途的路由缓存(如重定向或 PMTUD 相关路由)仍然存在)。可以这样找到它(在 192.168.20.43 主机上运行它已收到多个 ICMP 重定向):

# ip route show cache
192.168.30.66 via 192.168.30.66 dev eth0 
    cache <redirected> expires 296sec 

然后它只需按照这条路由,触发对 192.168.30.66 的 ARP 请求即可到达该主机。

相关内容