我有一台服务器,运行 Oracle Linux 8.4,在 2 个网卡上有 2 个 IP 地址:
link/ether 34:48:ed:f6:d3:5c brd ff:ff:ff:ff:ff:ff
inet 10.154.224.252/24 brd 10.154.224.255 scope global noprefixroute eno1
valid_lft forever preferred_lft forever
inet6 fe80::3648:edff:fef6:d35c/64 scope link
valid_lft forever preferred_lft forever
3: ens2f0np0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether bc:97:e1:7a:41:e0 brd ff:ff:ff:ff:ff:ff
inet 10.154.226.252/24 brd 10.154.226.255 scope global noprefixroute ens2f0np0
valid_lft forever preferred_lft forever
inet6 fe80::be97:e1ff:fe7a:41e0/64 scope link
valid_lft forever preferred_lft forever
/etc/iproute2/rt_tables
db and app
所以我在脚本中创建了 2 个表路由
#!/bin/sh
ip route add 10.154.226.0/24 dev ens2f0np0 src 10.154.226.252 table db
ip route add default via 10.154.226.1 dev ens2f0np0 table db
ip rule add from 10.154.226.252/24 table db
ip rule add to 10.154.226.252/24 table db
ip route add 10.154.224.0/24 dev eno1 src 10.154.224.252 table app
ip route add default via 10.154.224.1 dev eno1 table app
ip rule add from 10.154.224.252/24 table app
ip rule add to 10.154.224.252/24 table app
ip r command show:
10.154.224.0/24 dev eno1 proto kernel scope link src 10.154.224.252 metric 100
10.154.226.0/24 dev ens2f0np0 proto kernel scope link src 10.154.226.252 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
我可以通过 ssh 连接到任何接口的机器,但我无法从服务器连接到互联网、其他子网。
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.154.224.0 0.0.0.0 255.255.255.0 U 100 0 0 eno1
10.154.226.0 0.0.0.0 255.255.255.0 U 100 0 0 ens2f0np0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
我想念什么吗?我该如何解决这个问题?
答案1
无法访问互联网的原因是主要的路由表没有默认路由。
因此,例如,当创建并连接(使用)未绑定的 TCP 套接字(即:绑定到 INADDR_ANY)时connect(2)
,将使用路由查找来确定要分配给套接字的本地 IP 地址。此路由使用 INADDR_ANY 本地地址,因为套接字未绑定以确定结果是什么。因此,它不会将策略规则与特定源地址相匹配,因为比较的值是 0.0.0.0,并且不会与主要的路由表。
可以使用以下方法检查ip route get
:
# ip route get 8.8.8.8
RTNETLINK answers: Network is unreachable
但如果客户端应用程序绑定地址(示例:curl --interface=10.154.226.252 ifconfig.co
但由于 DNS 也受到影响,因此可能还需要将其添加到此示例中:--dns-interface=10.154.226.252
如果 DNS 服务器不在可访问的 LAN 中),则策略规则匹配并应用备用路由,允许连接发生:
# ip route get from 10.154.226.252 104.21.25.86
104.21.25.86 from 10.154.226.252 via 10.154.226.1 dev ens2f0np0 table db uid 0
cache
# ip route get from 10.154.224.252 104.21.25.86
104.21.25.86 from 10.154.224.252 via 10.154.224.1 dev eno1 table app uid 0
cache
所以仍然需要一个“default”默认路由主要的如果客户端应用程序不会显式绑定到属于主机的 IP 地址,则必须做出选择。让我们把应用程序选择边:
ip route add default via 10.154.224.1
所以现在:
# ip route
default via 10.154.224.1 dev eno1
10.154.224.0/24 dev eno1 proto kernel scope link src 10.154.224.252
10.154.226.0/24 dev ens2f0np0 proto kernel scope link src 10.154.226.252
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
# ip route get 8.8.8.8
8.8.8.8 via 10.154.224.1 dev eno1 src 10.154.224.252 uid 0
cache
如果一个真的不想添加默认路由,可以用ip rule
精心设计的命令替换它,以便从 INADDR_ANY 成功进行路由查找:
ip route del default
ip rule add from 0.0.0.0/32 lookup app
相同的结果,除了它使用的是应用程序表而不是主要的桌子:
# ip route get 8.8.8.8
8.8.8.8 via 10.154.224.1 dev eno1 table app src 10.154.224.252 uid 0
cache
如果不关心哪个接口并且想要负载平衡,可以使用上面的默认路由来代替多路径路线:
ip route del default # was already done
ip rule del from 0.0.0.0/32 lookup app
ip route add default nexthop via 10.154.224.1 dev eno1 nexthop via 10.154.226.1 dev ens2f0np0
将“随机”选择传出地址(实际上根据源和目标遵循某种哈希算法,获得稳定的路由),选择要绑定到的所选接口上的暗示源地址,并在此连接中设置任何进一步的传出数据包将使用策略路由(但即使没有策略路由,哈希也会将其保留在同一接口上,它不是循环)。
示例(在其他系统上可能有所不同,请尝试至少 4 个连续的 IP 地址):
# ip route get 8.8.8.9
8.8.8.9 via 10.154.224.1 dev eno1 src 10.154.224.252 uid 0
cache
# ip route get 8.8.8.10
8.8.8.10 via 10.154.226.1 dev ens2f0np0 src 10.154.226.252 uid 0
cache
按原样使用多路径可能存在各种警告:在某些地方仍然需要适当的 SNAT/MASQUERADE(但应该正常工作),如果接口的路由失败,则尝试的客户端无绑定连接的一半将失败,而无需任何恢复机制,而在此之前它要么是 100%,要么是 0%。
答案2
一台 Linux 计算机上不能有两个默认网关。仅为您要访问互联网的接口设置默认网关。