我在 Scaleway 上有几个 Linux 测试箱,每个都有 2 个 NIC,它们都连接到同一个网络10.0.0.0/8
,但每个都有自己的网关。
我希望能够同时使用 NIC(eth0/eth1)及其 IP 进行通信。因此,如果应用程序绑定到 IP .187,则应使用 dev eth0。如果应用程序绑定到 IP .189,则应使用 eth1。
目前,只有 IP 为 .187 的接口 eth0 响应请求。任何请求。(这就是我使用 ping 和 ssh 进行测试的原因)。但是,如果我将默认路由从 eth0 更改为 eth1(ip .189),则传出流量将正确通过 eth1 路由,在这种情况下 eth0 将不可用。
那么如何配置盒子,以便两个接口都可以使用。
鉴于
Box 1:
eth0_ip = 10.5.68.187/31
eth0_gw = 10.5.68.186
eth1_ip = 10.5.68.189/31
eth1_gw = 10.5.68.188
方法
根据我的研究,这里,这里我创建了一个 bash 脚本,它应该添加带有表的静态路由,以便可以同时使用两个网卡。
#/bin/bash
# My Vars with IP and GW for eth0
eth0_ip=$(ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
eth0_gw=$(ip route list dev eth0 | awk '{print $1}' | tail -1 | cut -d'/' -f1)
eth1_ip=$(ip -o -4 addr list eth1 | awk '{print $4}' | cut -d/ -f1)
eth1_gw=$(ip route list dev eth1 | awk '{print $1}' | tail -1 | cut -d'/' -f1)
#ip route add 10.0.0.0/8 dev eth0 table 1 priority 100
#ip route add ${eth0_ip} dev eth0 table 1
ip route add default via ${eth0_gw} dev eth0 table 1
ip rule add from ${eth0_ip}/32 table 1
#ip route add 10.0.0.0/8 dev eth1 table 2 priority 110
#ip route add ${eth1_ip} dev eth1 table 2
ip route add default via ${eth1_gw} dev eth1 table 2
ip rule add from ${eth1_ip}/32 table 2
ip 路由刷新缓存
我对脚本做了一些修改,但都没有起作用
输出
[node]# ip route
default via 10.1.229.186 dev eth0
10.1.229.186/31 dev eth0 proto kernel scope link src 10.1.229.187
10.1.229.188/31 dev eth1 proto kernel scope link src 10.1.229.189
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev docker_gwbridge proto kernel scope link src 172.18.0.1
[node]# ip route show table 1
10.1.229.187 dev eth0 scope link
[node]# ip route show table 2
10.1.229.189 dev eth1 scope link
测试
[]]# ip route get 10.5.68.187 from 10.1.229.187
10.5.68.187 from 10.1.229.187 via 10.1.229.186 dev eth0
cache
[]# ip route get 10.5.68.187 from 10.1.229.189
10.5.68.187 from 10.1.229.189 via 10.1.229.188 dev eth1
cache
来自另一台机器。
ping 10.1.229.187 # OK
ping 10.1.229.189 # NOK
nmap 10.1.229.187 -p 22 # OK
nmap 10.1.229.189 -p 22 # NOK
那么我该如何设置路由以使其正常工作,并同时与 .187 和 .189 通信。
更新 2:
通过这种设置我能够取得某种成功。
eth0_ip=$(ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
eth0_gw=$(ip route list dev eth0 | awk '{print $1}' | tail -1 | cut -d'/' -f1)
eth1_ip=$(ip -o -4 addr list eth1 | awk '{print $4}' | cut -d/ -f1)
eth1_gw=$(ip route list dev eth1 | awk '{print $1}' | tail -1 | cut -d'/' -f1)
ip route add default via ${eth0_gw} dev eth0 table 1
ip rule add from ${eth0_ip} table 1
ip route add default via ${eth1_gw} dev eth1 table 2
ip rule add from ${eth1_ip} table 2
应用上述脚本后,我修改了默认路由,切换到 eth1 然后再切换回来,之后我就能 ping 到 .187 和 .189。(在另一个例子中,我也将其完全删除)我不确定这里的问题是什么。
# remove and add route
ip route change default via ${eth1_gw} dev eth1
ip route change default via ${eth0_gw} dev eth0
ip route flush cache
更新 3:
从各种尝试来看,我觉得表 2 完全被忽略了。由于 ISP 有一个自定义内核,是否可以在内核中禁用路由表?我该如何测试?
更新 4:
我又取得了一点进展,但距离可行的解决方案仍然很远。在尝试不同的选项时,我偶然发现了这种奇怪的情况。为了看到 eth1 正常工作,我需要先使用相关接口一次,例如
我需要从 IP .189(节点 1) ping 到网络上的另一个节点,例如:示例:节点1->节点2: ping -I 10.1.229.189 10.5.68.187
这有效,然后突然返回来自节点 2 -> 节点 1 ping 10.1.229.189
正在工作。如果我不从(节点 1 -> 节点 2)进行初始连接/ping,则(节点 2 -> 节点 1)将无法工作。
然而,这里的问题是,如果我重新启动机器或等待一段时间(10-60 分钟),它就会回到初始状态。
部分工作的最小设置是这样的,(我随后删除了所有内容,但没有什么区别)
eth1_ip=$(ip -o -4 addr list eth1 | awk '{print $4}' | cut -d/ -f1)
eth1_gw=$(ip route list dev eth1 | awk '{print $1}' | tail -1 | cut -d'/' -f1)
ip route add default via ${eth1_gw} dev eth1 table 2
ip rule add from ${eth1_ip} lookup 2
这是@Anton Danilov 要求的输出
[root@cluser-node-1 ~]# ip -4 r ls table all
default via 10.1.229.188 dev eth1 table 2
default via 10.1.229.186 dev eth0
10.1.229.186/31 dev eth0 proto kernel scope link src 10.1.229.187
10.1.229.188/31 dev eth1 proto kernel scope link src 10.1.229.189
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev docker_gwbridge proto kernel scope link src 172.18.0.1
local 10.1.229.187 dev eth0 table local proto kernel scope host src 10.1.229.187
broadcast 10.1.229.187 dev eth0 table local proto kernel scope link src 10.1.229.187
local 10.1.229.189 dev eth1 table local proto kernel scope host src 10.1.229.189
broadcast 10.1.229.189 dev eth1 table local proto kernel scope link src 10.1.229.189
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
broadcast 172.17.0.0 dev docker0 table local proto kernel scope link src 172.17.0.1
local 172.17.0.1 dev docker0 table local proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 table local proto kernel scope link src 172.17.0.1
broadcast 172.18.0.0 dev docker_gwbridge table local proto kernel scope link src 172.18.0.1
local 172.18.0.1 dev docker_gwbridge table local proto kernel scope host src 172.18.0.1
broadcast 172.18.255.255 dev docker_gwbridge table local proto kernel scope link src 172.18.0.1
[root@cluser-node-1 ~]# ip rule list
0: from all lookup local
32765: from 10.1.229.189 lookup 2
32766: from all lookup main
32767: from all lookup default
[root@cluser-node-1 ~]# ip n ls dev eth1
10.1.229.188 lladdr 00:07:cb:0b:0d:93 REACHABLE
[root@cluser-node-1 ~]# tcpdump -ni eth1 arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
16:36:17.237182 ARP, Request who-has 10.1.229.188 tell 10.1.229.189, length 28
16:36:17.237369 ARP, Reply 10.1.229.188 is-at 00:07:cb:0b:0d:93, length 46
2 packets captured
4 packets received by filter
0 packets dropped by kernel
这是系统重启后或 15-30 分钟超时后的另一个输出。
[root@cluser-node-1 ~]# tcpdump -ni eth1 arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
[root@cluser-node-1 ~]# ip n ls dev eth1
10.1.229.188 lladdr 00:07:cb:0b:0d:93 REACHABLE
答案1
检查是否有回复(也许回复是通过其他界面发出的)或者缺少回复。
检查反向路径过滤器的设置(检查“nstat -az”或“netstat -S”输出中的计数器 - rp_filter 丢弃的数据包有 TcpExtIPReversePathFilter)。禁用它或将其设置为松散模式(请参阅sysctl 设置说明)。查找传入数据包的反向路由以确认该假设。
我认为您应该将直接连接网络的路由添加到路由表中,因为它是对应网关的 arp 解析以及与直接连接网络中的其他主机通信所必需的。这些设置应该足以解决您的情况:
ip 路由添加 10.5.68.186/31 dev eth0 表 1 ip 路由 0/0 通过 10.5.68.186 dev eth0 表 1 ip 路由添加 10.5.68.188/31 dev eth1 表 2 ip 路由 0/0 通过 10.5.68.188 dev eth1 表 2 ip 规则从 10.5.68.187 添加查找 1 ip 规则从 10.5.68.189 添加查找 2
此外,您应该知道,此设置仅适用于这些接口上的 IP 地址重叠的情况。否则,您应该使用更复杂的方案,使用 CONNMARK 和防火墙标记的 pbr。
如果您尝试从主机本身 ping 主机,您应该使用以下命令:
ip 路由添加本地 10.5.68.187 dev eth0 表 1 ip 路由添加 10.5.68.186/31 dev eth0 表 1 ip 路由 0/0 通过 10.5.68.186 dev eth0 表 1 ip 路由添加本地 10.5.68.189 dev eth1 表 2 ip 路由添加 10.5.68.188/31 dev eth1 表 2 ip 路由 0/0 通过 10.5.68.188 dev eth1 表 2 ip 规则添加 iif eth0 查找 1 首选项 101 ip 规则添加 iif eth1 查找 2 首选项 102 ip 规则从 10.5.68.187 添加查找 1 首选项 201 ip 规则从 10.5.68.189 添加查找 2 首选项 202 ip 规则从所有查找本地首选项 300 添加 ip 规则 del pref 0