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

前端之家收集整理的这篇文章主要介绍了linux – 强制网络流量通过特定的非默认接口进行路由前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一堆 Linux服务器,有多个(3)网卡和相关的网络接口.我正在绊倒一个奇怪的路由问题,那里应该使用默认路由的流量不会,并且因此无法路由.这是我的路由表的样子:
# 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

10.31.96.1是我所有流量应该使用的默认路由(em#stuff是Fedora的东西,你可以安心地用’eth’代替你看到’em’的所有地方,如果它更容易理解的话).这里的
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,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,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

em1 / 10.0.0.100转到仅连接到同一机架中的服务器的交换机.它仅用于该机架中的服务器之间进行通信. em3& em4都路由到同一个子网.它们之间的唯一区别是em3并不总是up(它与基于哪个服务器当前处于’master’角色的浮动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到cuda-linux(10.31.45.106),最多30个跃点,60个字节的数据包
1 cuda-fs1a-internal(10.0.0.100)3006.650 ms!H 3006.624 ms!H 3006.619 ms!H

然而,当从与上面的框相同的网络上的系统运行时,只有一个网络接口,它可以工作:
#tcptraceroute cuda-linux
traceroute到cuda-linux(10.31.45.106),40个字节的数据包
1 10.31.96.2(10.31.96.2)0.345 ms 0.403 ms 0.474 ms
2 cuda-linux(10.31.45.106)0.209 ms 0.208 ms 0.201 ms

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

# route add default gw 10.31.45.1 em3
SIOCADDRT: Network is unreachable

在这一点上,我迷失了还有什么可尝试的.救命?

解决方法

路由从最特定的路由处理到最不具体(也称为默认)路由.
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

你说你想要通过em3出去,除非它的目的是在本地10.0.0.1/8子网上的其他东西.这正是发生的事情. 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这样的东西通过10.31.96.1添加10.31.45.0/24可能会做你想要的.

猜你在找的Linux相关文章