我有以下 IP 配置(省略了一些输出):
# ip ad sh
1: lo:
inet 127.0.0.1/8 scope host lo
2: eth0:
inet 11.224.79.54/28 brd 11.224.79.63 scope global eth0
3: eth1:
inet 11.224.79.4/28 brd 11.224.79.15 scope global eth1
# ip ru sh
0: from all lookup local
666: from 11.224.79.54 to 52.219.72.0/22 iif lo lookup 1
# ip ro sh tab 1
default via 11.224.79.49 dev eth0
11.224.79.48/28 dev eth0 scope link
当我尝试 pingto
规则范围内的某个地址时666
,我得到:
# ping 52.219.74.137
connect: Network is unreachable
当我这样做时ping -I eth0
,它有效:
# ping -I eth0 52.219.74.137
PING 52.219.74.137 (52.219.74.137) from 11.224.79.54 eth0: 56(84) bytes of data.
^C
--- 52.219.74.137 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
(icmp 被阻止,但这是预料之中的)
无论如何,当我将规则修改666
为:
[root@ip-11-224-79-54 centos]# ip ru sh
0: from all lookup local
666: from all to 52.219.72.0/22 iif lo lookup 1
ping
即使没有,也能完美运行-I eth0
,并tcpdump
显示11.224.79.54
为数据包的源 IP。
在第一种情况下,使用 eth1 的 SRC IP 进行 ping 应该无法正常工作,但实际上它可以工作:
# ping -I eth1 52.219.74.137
PING 52.219.74.137 (52.219.74.137) from 11.224.79.4 eth1: 56(84) bytes of data.
(我认为应该是connect: Network is unreachable
)
我做错了什么?这对我来说毫无意义。
答案1
“源 IP 地址”与“源接口”不同。ping ICMP 数据包在所有情况下仍然是本地生成的 - 它们不是实际上是通过 eth0 或 eth1 接收的,它们仅仅使用了这些接口的地址。
从技术上来说,这些传出的数据包并不有一个输入接口,但出于规则匹配的目的,Linux 内核认为所有本地生成的流量都来自“lo”(LOOPBACK_IFINDEX)。
(可能不相关,但源代码也有一条注释:“[...] 我们被允许使用另一个 iface 的 saddr 发送数据包。”)