一个双网卡导致的网络故障

内网有个机器有2个网卡,并且是不同的网段和网关。 network 其中的B服务器有2个网卡。这个时候我们就只有默认网关为10.1.1.1 那查看路由表就是如下

1
2
3
4
5
6
7
[root@localhost ~]# ip route show table all 
10.1.1.0/24 dev eth0 proto kernel scope link src 10.1.1.247
10.1.2.0/24 dev eth1 proto kernel scope link src 10.1.2.239
169.254.0.0/16 dev eth0 scope link metric 1002
169.254.0.0/16 dev eth1 scope link metric 1003
default via 10.1.1.1 dev eth0
[root@localhost ~]# ip rule show 0: from all lookup local 32766: from all lookup main 32767: from all lookup default

这个时候我们可以发现,从1网段到1网段来回都没有问题,2网段来回也没有问题。但是从server A到server B的2网段是不通的。 因为你去到2网段后,server B的默认路由是10.1.1.1。 所以我们需要设置server B上,来自哪个网卡的路由就从哪个网卡出去。这样server A到server B的2网段就没有问题了。 首先添加2个route table

1
2
$ cat /etc/iproute2/rt_tables
# # reserved values # 255    local 254    main 253    default 252 lan1 251 lan2 0    unspec

然后再添加ip route和ip rule

1
2
3
4
5
6
ip route flush table lan1
ip route add default via 10.1.1.1 dev eth0 src 10.1.1.247 table lan1
ip rule add from 10.1.1.247 table lan1
ip route flush table lan2
ip route add default via 10.1.2.1 dev eth1 src 10.1.2.239 table lan2
ip rule add from 10.1.2.239 table lan2

这个时候我们再查看路由表如下

1
2
3
4
5
6
7
[root@localhost ~]# ip route show all 
10.1.1.0/24 dev eth0 proto kernel scope link src 10.1.1.247
10.1.2.0/24 dev eth1 proto kernel scope link src 10.1.2.239
169.254.0.0/16 dev eth0 scope link metric 1002
169.254.0.0/16 dev eth1 scope link metric 1003
default via 10.1.1.1 dev eth0
[root@localhost ~]# ip rule show 0: from all lookup local 32764: from 10.1.2.239 lookup lan2 32765: from 10.1.1.247 lookup lan1 32766: from all lookup main 32767: from all lookup default

这个时候从表面上似乎解决了问题,从server A访问server B的2网段也能正常返回,从server C访问server B的1网段也可以正常返回。 但是我们发现,这个时候从server B访问server A的1网段的时候,一直网络状态在SYN的状态。 half-tcpdump 上面tcpdump的结果我们发现是有很多的TCP重传。 这个时候我们发现,上面的ip rule只是设定了,来自2网段的走lan2(又设定了src为自己), 来自1网段的走lan1(又设定了src 为自己的IP)。而没有设定如果主动出去是怎么样的。 因此我们把上面的ip rule加了2条.

1
2
3
4
5
6
7
8
ip route flush table lan1 
ip route add default via 10.1.1.1 dev eth0 src 10.1.1.247 table lan1
ip rule add from 10.1.1.247 table lan1
ip rule add from 10.1.1.247 to 10.1.1.0/24 table main
ip route flush table lan2
ip route add default via 10.1.2.1 dev eth1 src 10.1.2.239 table lan2
ip rule add from 10.1.2.239 table lan2
ip rule add from 10.1.2.239 to 10.1.2.0/24 table main

然后我们查看路由表如下:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~]# ip route show table all
default via 10.1.1.1 dev eth0  table lan1  src 10.1.1.247
10.1.1.0/24 dev eth0  proto kernel  scope link  src 10.1.1.247
10.1.2.0/24 dev eth1  proto kernel  scope link  src 10.1.2.239
169.254.0.0/16 dev eth0  scope link  metric 1002
169.254.0.0/16 dev eth1  scope link  metric 1003
default via 10.1.1.1 dev eth0 default via 10.1.2.1 dev eth1  table lan2  src 10.1.2.239
[root@localhost ~]# ip rule show 0:    
from all lookup local 32762:    from 10.1.2.239 to 10.1.2.0/24
lookup main 32763:    from 10.1.2.239 lookup lan2 32764:    from 10.1.1.247 to 10.1.1.0/24
lookup main 32765:    from 10.1.1.247 lookup lan1 32766:    from all
lookup main 32767:    from all lookup default

从上面这个例子中可以窥见,平时我们用netstat -rn这样来查看路由是没有问题的,但是当出现自定义route table的时候,我们需要注意的一些东西,一个是route table本身,还有是ip rule去定义使用哪个table。