强制网络流量通过特定的非默认接口进行路由

net*_*ama 6 linux routing route

我有一堆带有多个(3)网卡和相关网络接口的 Linux 服务器。我被一个奇怪的路由问题绊倒了,应该使用默认路由的流量不是,结果路由失败。这是我的路由表的样子:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.31.96.1      0.0.0.0         UG    0      0        0 em3
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 em1
10.31.96.0      0.0.0.0         255.255.252.0   U     0      0        0 em3
10.31.96.0      0.0.0.0         255.255.252.0   U     0      0        0 em4
# ip route list
default via 10.31.96.1 dev em3  proto static 
10.0.0.0/8 dev em1  proto kernel  scope link  src 10.0.0.100 
10.31.96.0/22 dev em3  proto kernel  scope link  src 10.31.97.100 
10.31.96.0/22 dev em4  proto kernel  scope link  src 10.31.96.61
Run Code Online (Sandbox Code Playgroud)

10.31.96.1 是我所有流量都应该使用的默认路由(em# 的东西是 Fedora 的东西,你可以放心地在任何你看到 'em' 的地方用 'eth' 替换它,如果它更容易遵循)。这是 ifconfig 输出:

em1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 10.0.0.100  netmask 255.0.0.0  broadcast 10.255.255.255
    inet6 fe80::b6b5:2fff:fe5b:9e7c  prefixlen 64  scopeid 0x20<link>
    ether b4:b5:2f:5b:9e:7c  txqueuelen 1000  (Ethernet)
    RX packets 283922868  bytes 44297545348 (41.2 GiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 538064680  bytes 108980632740 (101.4 GiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    device memory 0xfeb60000-feb80000

em3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 10.31.97.100  netmask 255.255.252.0  broadcast 10.31.99.255
    inet6 fe80::b6b5:2fff:fe5b:9e7e  prefixlen 64  scopeid 0x20<link>
    ether b4:b5:2f:5b:9e:7e  txqueuelen 1000  (Ethernet)
    RX packets 3733210  bytes 1042607750 (994.3 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 1401537  bytes 114335537 (109.0 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    device memory 0xfea60000-fea80000

em4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 10.31.96.61  netmask 255.255.252.0  broadcast 10.31.99.255
    inet6 fe80::b6b5:2fff:fe5b:9e7f  prefixlen 64  scopeid 0x20<link>
    ether b4:b5:2f:5b:9e:7f  txqueuelen 1000  (Ethernet)
    RX packets 2416588  bytes 196633917 (187.5 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 205038  bytes 19363499 (18.4 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    device memory 0xfeae0000-feb00000
Run Code Online (Sandbox Code Playgroud)

em1/10.0.0.100 转到连接到同一机架中的服务器的交换机。它仅用于该机架中的服务器之间进行通信。em3 和 em4 都路由到同一个子网。它们之间的唯一区别是 em3 并不总是启动(它与基于当前处于“主”角色的服务器的浮动 IP 地址相关联)。基本上所有流量都应该通过 em3 出去,除非它的目的地是本地 10.0.0.1/8 子网上的其他东西,在这种情况下,它应该通过 em1 出去。然而,事实并非如此。10.31.96.1/16、10.31.97.1/16 和 10.31.99.1/16 流量正在通过 em3,但发往 10.31.45.1/16 的流量正在尝试通过 em1,并且由于无法路由而超时交通有效。

这也用以下命令说明:# tcptraceroute cuda-linux traceroute to cuda-linux (10.31.45.106),最多 30 跳,60 字节数据包 1 cuda-fs1a-internal (10.0.0.100) 3006.650 ms !H! 2406 ms H 3006.619 毫秒 !H

然而,当从与上述框相同网络上的系统运行时,只有一个网络接口,它可以工作:# tcptraceroute cuda-linux traceroute to cuda-linux (10.31.45.106), 30 hops max, 40 byte packets 1 10.31 .96.2 (10.31.96.2) 0.345 毫秒 0.403 毫秒 0.474 毫秒 2 cuda-linux (10.31.45.106) 0.209 毫秒 0.208 毫秒 0.201 毫秒

我以为我可以通过为 em3 添加到 10.31.45.1 的路由来解决这个问题,但是失败了:

# route add default gw 10.31.45.1 em3
SIOCADDRT: Network is unreachable
Run Code Online (Sandbox Code Playgroud)

在这一点上,我不知道还有什么可尝试的。帮助?

Zor*_*che 13

路由从最具体的路由到最不具体的(又名默认)路由进行处理。

default via 10.31.96.1 dev em3  proto static 
10.0.0.0/8 dev em1  proto kernel  scope link  src 10.0.0.100 
10.31.96.0/22 dev em3  proto kernel  scope link  src 10.31.97.100 
10.31.96.0/22 dev em4  proto kernel  scope link  src 10.31.96.61
Run Code Online (Sandbox Code Playgroud)

你说你要should be going out through em3 unless its destined for something else on the local 10.0.0.1/8 subnet。这正是正在发生的事情。IP 地址10.31.45.1在内部10.0.0.0/8,因此它通过 em1 离开。该10.0.0.0/8路由匹配该地址是更具体的,则默认路由。地址与10.31.96.0/22路线不匹配。因此选择了 em1 路由。

您真正的问题是您在该 em1 接口上的子网掩码对于您可能需要的来说太大了,并且与其他网络冲突。任何以 10.0.0.1-10.255.255.254 范围内的 IP 地址为目标的内容都将尝试使用 em1,就好像它是本地的一样,但 10.31.96.0/22 中的地址除外,它将通过 em3/em4 离开。

您的解决方案是修复 em1 子网/网络,使其不与您的其他网络冲突,或者添加大量路由。

类似的东西ip route add 10.31.45.0/24 via 10.31.96.1可能会做你想做的事。