通过 linux 路由 table Ping 不工作 [或] 这是怎么回事?

Ping via linux routing table not working [OR] how is this expected?

长题简而言之:

Ping over r1-r4-r2 path works using 10.0.1.* or 10.0.2.* IP addresses, but fails if we alter the path to r1-r3-r2 using 1.0.0.* or 1.0.1.* IP addresses for the exactly same packets (except for the fact that packets' src and dst IP fields are changed from 10.* to 1.* and vice-versa at s1 and s2 respectively). Why?


问题详细:

我有一个小拓扑如下

 h1 -- s1 -- r1 -- r4 -- r2 -- s2 -- h2
              \         /
               \       /
                \     /
                  r3

s 是 OpenvSwitch 实例,而 r 是 Ubuntu 16 Linux 台机器。

IP 地址是:

h1-eth0 - 10.0.1.10/24
s1      - 10.0.1.50/24
h2-eth0 - 10.0.2.10/24
s2      - 10.0.2.50/24
r1-eth0 - 10.0.1.1/24
r1-eth1 - 10.0.11.2/24
r1-eth2 - 10.0.12.2/24
r2-eth0 - 10.0.2.1/24
r2-eth1 - 10.0.13.1/24
r2-eth2 - 10.0.5.1/24
r3-eth0 - 10.0.12.1/24
r3-eth1 - 10.0.5.2/24
r4-eth0 - 10.0.11.1/24
r4-eth1 - 10.0.13.2/24

可以看到,r1和r2之间有两条相似的路径。我添加以下静态条目。

r1

sudo ip route add 10.0.2.0/24 via 10.0.11.1

r2

sudo ip route add 10.0.1.0/24 via 10.0.13.2

r4

sudo ip route add 10.0.1.0/24 via 10.0.11.2
sudo ip route add 10.0.2.0/24 via 10.0.13.1

h1 和 h2 之间的 ping 正常。现在,由于交换机是 OVS(因此启用了 OpenFlow),我在 s1 中安装条目以 将目标 IP 映射到不同的子网 .

i.e. the IP 10.0.1.10 would be mapped to 1.0.0.10 while the IP 10.0.2.10 would be mapped to 1.0.1.10 when such a packet is received at s1, while the destination IPs would be mapped back to original at s2.

(我检查过这些条目确实正确并且按预期工作。另外我添加此条目只是为了匹配 ICMP 数据包)。当 h1 发送 ping 回复时,将执行类似的过程。

除此之外,我还在路由器中安装了静态路由来路由这些 IP。

r1

sudo ip route add 1.0.0.0/24 via 10.0.1.50
sudo ip route add 1.0.1.0/24 via 10.0.12.1

r2

sudo ip route add 1.0.0.0/24 via 10.0.5.2
sudo ip route add 1.0.1.0/24 via 10.0.2.50

r3

sudo ip route add 1.0.0.0/24 via 10.0.12.2
sudo ip route add 1.0.1.0/24 via 10.0.5.1

现在,如果我从 h2 ping h1,数据包以目标 IP 10.0.1.10 开始,在 s2 映射到 1.0.0.10,r2 路由它并将其发送到 r3,r3 路由它并发送到 r1。 但是 r1,即使在一个接口接收到数据包并在 Linux 路由 table 中具有匹配条目后,也不会路由和转发数据包。

甚至 ip route get 输出数据包应该转发到的正确端口。 ip tables 中也没有防火墙条目。


一些附加信息:

可能需要的详细信息:

最终路由table如下:

r1

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.11.1       0.0.0.0         UG    0      0        0 eth1
1.0.0.0         10.0.1.10       255.255.255.0   UG    0      0        0 eth0
1.0.1.0         10.0.12.1       255.255.255.0   UG    0      0        0 eth2
10.0.1.0        0.0.0.0         255.255.255.0   U     1      0        0 eth0
10.0.2.0        10.0.11.1       255.255.255.0   UG    0      0        0 eth1
10.0.11.0       0.0.0.0         255.255.255.0   U     1      0        0 eth1
10.0.12.0       0.0.0.0         255.255.255.0   U     1      0        0 eth2

r2

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.13.2       0.0.0.0         UG    0      0        0 eth1
1.0.0.0         10.0.5.2        255.255.255.0   UG    0      0        0 eth1
1.0.1.0         10.0.2.50       255.255.255.0   UG    0      0        0 eth0
10.0.1.0        10.0.13.2       255.255.255.0   UG    0      0        0 eth1
10.0.2.0        0.0.0.0         255.255.255.0   U     1      0        0 eth0
10.0.5.0        0.0.0.0         255.255.255.0   U     1      0        0 eth2
10.0.13.0       0.0.0.0         255.255.255.0   U     1      0        0 eth1

r3

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.5.1        0.0.0.0         UG    0      0        0 eth1
1.0.0.0         10.0.12.2       255.255.255.0   UG    0      0        0 eth0
1.0.1.0         10.0.5.1        255.255.255.0   UG    0      0        0 eth1
10.0.1.0        10.0.12.2       255.255.255.0   UG    0      0        0 eth0
10.0.2.0        10.0.5.1        255.255.255.0   U     1      0       0 eth1
10.0.5.0        0.0.0.0         255.255.255.0   U     1      0        0 eth1
10.0.12.0       0.0.0.0         255.255.255.0   U     1      0        0 eth0

r4

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth4
1.0.0.0         10.0.11.2       255.255.255.0   UG    0      0        0 eth0
1.0.1.0         10.0.13.1       255.255.255.0   UG    0      0        0 eth1
10.0.1.0        10.0.11.2       255.255.255.0   UG    0      0        0 eth0
10.0.2.0        10.0.13.1       255.255.255.0   UG    0      0        0 eth1
10.0.11.0       0.0.0.0         255.255.255.0   U     1      0        0 eth0
10.0.13.0       0.0.0.0         255.255.255.0   U     1      0        0 eth1
192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth4

注意:192.168.0.* 是连接到外部 Internet 的子网。

你觉得问题出在哪里?看着这个问题我完全莫名其妙。

首先,您的拓扑详细信息不完整,您缺少 r3 和 r4 详细信息,但可以推断出它们。

我不会尝试解决您的问题,而是会尝试解释需要发生的事情。但是,如果您只使用像 OSPF 这样的路由协议,它会更容易,因为它旨在使这变得容易,所以您不必手动完成。

每个正在路由的设备都需要知道如何到达每个其他子网,如果它是可访问的。所以这意味着您可以添加默认路由(即匹配 0.0.0.0/0 的路由),或者您可以在每个子网中输入相应的 next-ip 到每个路由器(见下文)。通常你不需要为连接的子网添加路由(即你在那个子网的那个路由器上有一个 ip)

R1 路线

10.0.13.0/24 -> 10.0.11.1
10.0.5.0/24 -> 10.0.11.1
10.0.2.0/24 -> 10.0.11.1

R2 路线

10.0.1.0/24 -> 10.0.13.2
10.0.12.0/24 -> 10.0.13.2
10.0.11.0/24 -> 10.0.13.2

R3 路线

10.0.1.0/24 -> 10.0.12.2
10.0.11.0/24 -> 10.0.12.2
10.0.13.0/24 -> 10.0.5.1
10.0.2.0/24 -> 10.0.5.1

R4 路线

10.0.1.0/24 -> 10.0.11.2
10.0.12.0/24 -> 10.0.11.2
10.0.2.0/24 -> 10.0.13.1
10.0.5.0/24 -> 10.0.13.1

对于设备 H1、S1、H2 和 S2,它们应该有一个指向网关 10.0.1.1 和 10.0.2.1 的默认路由。

此处 Linux 路由的行为符合预期。

反向路径过滤器的标志
即默认情况下 /proc/sys/net/ipv4/conf/<interfacename>/rp_filter 已打开(通过将值设置为 1)。

反向路径过滤器作为 Linux 内核的一项安全功能提供。 一个常见的例子是私有 IP space 逃逸到互联网上。如果您有一个路由为 195.96.96.0/24 的接口,您不希望来自 212.64.94.1 的数据包到达那里。因此,如果标志设置为 1,内核将丢弃这样的数据包。

更正式地说,

Reverse path filtering is a mechanism adopted by the Linux kernel to check whether the source IP address of the packet that is been received is routable.

So in other words, when a machine with reverse path filtering enabled receives a packet, the machine will first check whether the source of the received packet is reachable through the interface it came in.

  • If it is routable through the interface which it came, then the machine will accept the packet.
  • If it is not routable through the interface, which it came, then the machine will drop that packet.

Latest kernels provide one more option value of 2. This option is slightly more liberal in terms of accepting traffic.

If the received packet's source address is routable through any of the interfaces on the machine, the machine will accept the packet.

要让它工作,请在所有机器上使用它:

# for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
>  echo 0 > $i 
> done

或者在您的 /etc/sysctl.conf

中输入以下内容
net.ipv4.conf.all.rp_filter = 0

rp_filter 将以三种模式过滤数据包:0 禁用、1 严格和 2 松散。

例子

Client A - 192.168.2.10 - connected to router via eth0

Router
   eth0   - 192.168.2.150
    routes - 192.168.2.0/24
   eth1   - 10.42.43.1
    routes - 10.42.43.0/24

注:无默认路由

Client C - 10.42.43.50 - connected to router via eth1

使用此设置并将路由器上的 rp_filter 设置为“松散模式”(2) eth0 上从 1.2.3.4 到 10.42.43.50 的数据包将被阻止。

路由器上的 rp_filter 设置为“严格模式”(1) 来自源地址 10.42.43.2 的 eth0 上的数据包将被阻止。

当设置为“禁用”(0) 时,两个数据包都会通过。