我有几个系统,它们的行为方式相同。每个系统在两个不同的子网上都有一个接口,每个子网都可以访问互联网,但我只能在其中一个接口上成功使用 ping -I。例如,运行 Debian 8.11 的 Linux 机器
这是 /etc/network/interfaces:
# The primary network interface
allow-hotplug eth0
iface eth0 inet static
address 192.168.0.94
netmask 255.255.255.0
gateway 192.168.0.1
# VLAN 782 'PUB', Public
auto eth0.782
iface eth0.782 inet static
address 192.168.2.94
netmask 255.255.255.0
和我的路由表:
netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0.782
我可以:
root@pbx3:~# ping google.com
PING google.com (172.217.2.78) 56(84) bytes of data.
64 bytes from mia09s01-in-f14.1e100.net (172.217.2.78): icmp_seq=1 ttl=48 time=63.6 ms
我可以:
ping -I eth0 google.com
PING google.com (172.217.2.78) from 192.168.0.94 eth0: 56(84) bytes of data.
64 bytes from ord08s13-in-f14.1e100.net (172.217.2.78): icmp_seq=1 ttl=48 time=70.2 ms
但我不能:
ping -I eth0.782 google.com
PING google.com (172.217.2.78) from 192.168.2.94 eth0.782: 56(84) bytes of data.
From 192.168.2.94 icmp_seq=1 Destination Host Unreachable
虽然我可以对该子网上的设备进行 nmap 和 ping 操作:
ping -I eth0.782 192.168.2.1
PING 192.168.2.1 (192.168.2.1) from 192.168.2.94 eth0.782: 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.385 ms
(另一个系统也存在同样的问题,Centos 6.8 使用 eth0 和 eth1)
我的好朋友 Google 似乎暗示这与我的路由表有关,但我似乎无法发现到底出了什么问题,或者如何修复它。我尝试将 192.168.2.1 网关添加到 eth0.782 网络,但随后 eth0 网络消失了,所以显然只能有一个网关...
提前感谢任何提示!
答案1
部分答案:
首先,您需要子网的网关。如果您无法让 DHCP 工作,请暂时手动执行:
ip route add 192.168.2.0/24 via 192.168.2.1 dev eth0.782
(您可能必须先删除没有网关的路线;我从未尝试过更新没有网关的路线。使用ip route
获取所有路线,然后ip route del ...
使用上一步的信息将其删除。)
然后使用ip route
(或netstat -rn
)验证网关是否设置正确。
接下来再试ping
一次。我实际上不确定绑定到接口是否会使其忽略主路由表。如果这不起作用,您可以使用策略路由设置两条以源地址区分的默认规则。
如果您计划使用此设置通过两个不同的接口访问互联网:这将不起作用(这是一个常见问题解答,每周左右都会有人尝试这种变体)。
所以如果这是一个XY 问题,其中您的 X 是“我想通过两种不同的方式访问互联网”,而您的 Y 是“我想在没有默认路由的情况下进行 ping”,您需要详细说明您的 X(例如“您使用的所有应用程序是否都可以绑定到特定接口?”与例如“为什么不使用网络命名空间”?)
编辑
因此,如果用例“检查其他 LAN 中的连接,根据结果执行某些操作”,最简单的方法可能是创建一个不同的网络命名空间,在 中对其进行配置/etc/netns/your_namespace/network/interfaces
(这是 的功能ip netns exec
,请阅读),使用inet dynamic
而不是inet static
来确保它获取 DHCP 地址和默认路由,然后ping
使用 在此命名空间中运行ip netns exec
。
您不再有冲突的默认路由,问题解决了。您必须阅读有关网络命名空间的内容,例如这里和 unix.stackexchange 上有很多问题。
您还可以尝试将策略路由与ping -I
绑定结合起来,但这可能会更加困难,特别是当您想为第二个接口配置 DHCP 时。
答案2
好的,所以我让它基本正常工作了,感谢 dirkt 的提示,不幸的是我没有足够的声誉来标记你的答案有用,唉。首先,我先更新了另一台机器(运行 Debian 9.9 的 Raspberry Pi),然后按照以下说明操作https://www.sbprojects.net/projects/raspberrypi/vlan.php现在我可以(例如)
ping -I eth0.3750 google.com
或者
traceroute -i eth0.3750 google.com
不幸的是,如果我设置静态 IP,它就会停止工作,但如果我使用 eth0.3750,我就不需要知道 IP 地址,所以我想这已经足够接近了。FWIW,我的其他机器比较旧,没有所有正确的软件,因此升级/更新它们比使用 Raspberry Pi 更麻烦。8*)
答案3
rp_filter
也许与(有关https://www.theurbanpenguin.com/rp_filter-and-lpic-3-linux-security/)。如果源地址不可路由(假设传出接口没有默认规则),此设置可能会丢弃传入消息(假设 ping 回复)。这对我来说有效:
时间变化:
echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter
永久更改:编辑/etc/sysctl.conf
:
net.ipv4.conf.all.rp_filter=2