Linux双网卡路由和PMTU问题
2 min read

Linux双网卡路由和PMTU问题

双网卡(单网卡通过VLAN实现)

Ubuntu 
| ---eth0(100.3) ----------------------------|
                                                                                                        *                                            |router2|(MTU 1416)>>
                                             
|----eth0.2(199.3)--(199.1)|router1|(100.224)-| 

问题1:

Ubuntu :  ping 100.1    100.3 <-->100.1  OK

router2 : ping 199.3    199.3 <-->100.1  Fail

原因是Ubuntu从eth0.2收到100.1的icmp包时,发现这不是其默认路径,直接忽略了,根本没有任何回应。

问题2:

设置route1为Ubuntu的默认网关,在ubuntu上docker pull失败!原因是router1的MTU设置小于常见的1500,因此会在返回ICMP包通知。

@ubuntu:~$ sudo tcpdump -ni any icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
14:32:10.979982 IP 192.168.100.1 > 192.168.199.3: ICMP 54.175.214.89 unreachable - need to frag (mtu 1416), length 556

可是ubuntu机器似乎并没有理会,继续发送超过MTU的包

14:29:05.173457 IP 192.168.199.3.36479 > 54.175.214.89.443: Flags [.], seq 2092810032:2092811480, ack 4206115311, win 274, options [nop,nop,TS val 3165856 ecr 226068501], length 1448

1448 + 20(ip header) = 1468 已经超过 1416

跟问题1一样,ubuntu又忽略了这个ICMP包,认为其来源有问题,直接忽略。

跟常见的PMTU问题不一样,一般都是客户端发的包比较小,而服务端回复的包比较大,所以ICMP包都是发给服务器的。另外,常见的PMTU问题还可以通过路由器的MSS Clamping让服务器收到较小的MSS设置,从而基本基本避免收到这个ICMP包。 而这里,我们看到的是客户端发出的包比较大,所以MSS Clamping没起作用!这个ICMP发向了客户端了!

这一切的原因,都是因为Ubuntu和router2之间有两条路由。普通的tcp/udp包没有问题(syn,syn+ack都正常),但是icmp包会出问题(ping以及need to frag)

这其实是因为Reverse Path Filtering导致的,这本是为了防止伪造IP攻击的,
关闭就好

sudo sysctl net.ipv4.conf.eth0.rp_filter=0
sudo sysctl net.ipv4.conf.all.rp_filter=0

如此设置,就一切正常了,问题1和2不复存在!