TCPMSS 引发的 PPTP VPN 问题

文/for you 2014-12-31 23:20:00

问题描述

在云主机上配置了 PPTP VPN 之后,发现客户端在连接 VPN 的状态下,可以访问淘宝,但是无法访问百度等网站,具体表现为浏览器请求页面的过程中连接被重置。

最初怀疑是 DNS 的问题,但是经过检查发现 DNS 可以返回正确的结果。然后尝试在客户端侧检查浏览器的获得的响应结果,发现浏览器没有接收到任何的响应数据,于是尝试着云主机上请求百度,发现可以得到正确的响应。

初步排查之后没有能够发现问题所在,所以尝试抓包做进一步分析。(此处插入用户提供截图或者自己重新从云主机上截图) PCAP_RESULT

抓包的结果如上图所示,我们可以关注到一个特别的 ICMP 报文 Destination unreachable (fragmentation need),通常情况下这个报文暗示了报文超出 MTU 的限制,需要在 IP 报文上进行分片,但一般系统发送 TCP 报文时会将 IP header 的 DF (Don't Fragmentation) 位设置成1,所以 VPN 服务器发现报文超出 ppp0 端口的 MTU 之后会给百度的服务器返回 Destinatiojn unreachable (fragmentation need) 的错误。


问题原因

首先需要说明的是 PPP 协议的 MTU 是1396,算上 IP header 和 TCP header 各20个字节,最大的 TCP MSS 值应为1356。而我们可以从上面的抓包结果中看到客户端在和 Web 服务器在协商 TCP MSS 的时候选择的值是1360,按照这个结果加上 IP 和 TCP 的 header,那么最终报文的大小就超过了 ppp0 的 MTU.

在转发的报文超出 MTU 的情况下,VPN 服务器通过 ICMP 报文给百度的 Web 服务器返回 Destination unreachable (fragmentation need) 信息,告知对方发送的报文太大,同时告知下一跳的 MTU 应为 1396,但是在多数情况下,服务器端的会过滤这类 ICMP (type 3, subtype 4) 报文,导致服务器会一直发送 MTU 过大的报文。

最后,在客户端看来,Web 请求发送之后,能够接收到相对回应报文(这类报文的大小没有超过 ppp0 的 MTU),但是对于超过 ppp0 的 MTU 的报文,则永远都不会接收到了,因此出现了连接被重置的情况。 MTU-Sq


解决方法

在确定下造成这个问题的原因之后,我们可以有两种方式来解决这个问题,第一,增大 ppp0 的 MTU;第二,减小客户端和 Web 服务器之间协商的 TCP MSS 值的大小。

1. 增大 MTU
ifconfig ppp0 mtu 1500
2. 减小 TCP MSS
iptables -A FORWARD -p tcp --syn -s CLIENT_IP_RANGE -j TCPMSS --set-mss 1356
知识共享许可协议
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

最新文章 全部