![不同接口上的子网之间的连接无需 IP 转发](https://linux22.com/image/1608746/%E4%B8%8D%E5%90%8C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E7%9A%84%E5%AD%90%E7%BD%91%E4%B9%8B%E9%97%B4%E7%9A%84%E8%BF%9E%E6%8E%A5%E6%97%A0%E9%9C%80%20IP%20%E8%BD%AC%E5%8F%91.png)
这是我关于超级用户的第一个问题,因此如果它没有达到标准,我深感抱歉。
我正在运行 pop!_OS 19.10(基于 Ubuntu 19.10),并试图了解其网络行为。给定网络接口eth0
,我添加了以下子网:
ip addr add dev eth0 192.168.2.18/24
ip addr add dev eth0 192.168.3.18/24
接口现在如下所示(MAC 地址已更改)
1: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.18/24 scope global enp0s31f6
valid_lft forever preferred_lft forever
inet 192.168.3.18/24 scope global enp0s31f6
valid_lft forever preferred_lft forever
使用nc
,我可以在 IP 地址192.168.2.18
和之间发送数据192.168.3.18
。
##################################################################################
# nc -v -l 192.168.2.18 8080
Listening on [pop-os] (family 2, port 8080)
Listening on pop-os 8080
Connection received on pop-os 55361
Hello World!
##################################################################################
# nc -v -s 192.168.3.18 192.168.2.18 8080
Connection to 192.168.2.18 8080 port [tcp/http-alt] succeeded!
Hello World!
##################################################################################
# ss -4 -n
tcp ESTAB 0 0 192.168.3.18:55361 192.168.2.18:8080
tcp ESTAB 0 0 192.168.2.18:8080 192.168.3.18:55361
问题 1:我是否正确地假设单独的子网在相同接口是否始终可以相互通信(除非被防火墙阻止)?这是因为内核查看路由表并发现它可以简单地在本地连接两个网络吗?即:
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
现在我测试了这个,因为我正在研究内核 IP 转发,并且读到这里:
但是,如果关闭了转发,内核会先检查数据包来自哪个接口。如果不是来自同一个接口,内核就会丢弃它。
192.168.2.18
但是,我也可以通过我的其他接口wlan0
使用地址连接到192.168.1.73
。我已禁用 IP 转发。
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 192.168.2.18:8080 192.168.1.73:40405
tcp ESTAB 0 0 192.168.1.73:40405 192.168.2.18:8080
问题2:为什么不同子网和接口上的 IP 地址可以在不启用 IP 转发的情况下进行通信?是因为它们属于同一主机吗?这种行为在哪里定义?也就是说,只有当数据包开始离开主机时,IP 转发规则才会生效吗?
答案1
问题 1:我是否可以假设同一接口上不同子网内的地址始终可以相互通信(除非被防火墙阻止)?这是因为内核查看了路由表并发现它可以简单地在本地连接两个网络吗?即:
是的。这不是由您找到的“子网”条目引起的,而是由位于单独路由表(“本地”表)中的“本地地址”条目引起的。旧的“路由”工具很可能故意隐藏了这些条目,但它也已过时,无法完全显示现代 Linux 内核保存的路由信息,因此请使用:
ip -4 route show table local
ip -6 ro ls tab local
(注意:这是 Linux 特有的。在 BSD 中,通常只有一个路由表,并netstat -rn
会显示l
设置了标志的特殊路由。在其他操作系统中,它甚至可能只是内置行为,而不一定作为路由公开。)
此外,地址甚至不必位于同一接口上,因为数据包从未真正使用过物理接口内核的行为就像是自己的地址只是通过回送接口‘lo’。
问题 #2:为什么不同子网和接口上的 IP 地址可以在不启用 IP 转发的情况下进行通信?是因为它们属于同一主机吗?这种行为在哪里定义?也就是说,只有当数据包开始离开主机时,IP 转发规则才会生效吗?
是的,因为它们属于同一主机。(在 Linux 上,它们还需要位于同一网络命名空间中,例如同一容器。)
当数据包已收到通过非环回接口(例如,它通过以太网到达本地 MAC 地址),但其目标 IP 不被识别为属于主机。
根据定义,本地生成的数据包不会被“转发”(由于它们具有本地源 IP 地址,因此它们是“输出”),因此转发规则不适用。