首页 » Linux » 正文

解决连接PPTP后部分网页打不开的问题

问题描述:

CentOS 7.8.2003搭建pptp VPN环境,客户端Windows设备连接后出现部分网页打不开的问题

解决方法:

[root@Linux191 ~]# netstat -i
Kernel Interface table
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0             1500    21034      0      0 0         14942      0      0      0 BMRU
eth0:0           1500      - no statistics available -                        BMRU
lo              65536    23469      0      0 0         23469      0      0      0 LRU
ppp0             1396     4522      0      0 0          4829      0      0      0 MOPRU

### firewalld 防火墙配置工具
###参考链接 https://github.com/firewalld/firewalld/issues/493
firewall-cmd --permanent --direct --add-passthrough ipv4 -t mangle -I FORWARD -p tcp --syn -j TCPMSS --clamp-mss-to-pmtu
firewall-cmd --reload

### iptabales 防火墙配置工具(重启后会丢失,需要禁用firewalld安装iptables-services工具,加入启动项并保存配置,或者将下面命令加入rc.local等文件也可以。)
###参考链接 http://www.361way.com/pptpd-vpn/5012.html
iptables -I FORWARD -p tcp --syn -i ppp0 -j TCPMSS --set-mss 1356或iptables -A FORWARD -p tcp --syn -s 192.168.0.0/24 -j TCPMSS --set-mss 1356
在pptp server端,每新增加一个连接,本地就多一个pppX的接口,而我们iptables上的规则只是针对ppp0的,将iptables规则做了简单的修改后,所有人都可以正常上网了:
#-A FORWARD -i ppp0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --set-mss 1356
-A FORWARD  -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --set-mss 1356
#-A FORWARD  -p tcp -m tcp --syn -j TCPMSS --clamp-mss-to-pmtu
将流释的行改为第二行,或第三行都OK的。
以下内容转自:http://www.361way.com/pptp-mtu-mss/5173.html
在上一篇 centos下使用pptp搭建vpn代理服务器 中有提到通过pptp 配置VPN 上网,其中也提到一个情况,如果不设置mtu值会出现能ping通,但无法正常访问很多页面的情况,当时也给出了解决方法:
iptables -I FORWARD -p tcp --syn -i ppp0 -j TCPMSS --set-mss 1356
或iptables -A FORWARD -p tcp --syn -s 192.168.0.0/24 -j TCPMSS --set-mss 1356
本篇就基于前一篇,做一些原理性的说明。

一、几个概念

先认识几个理论概念:MTU、MMS、1500、1396、1356
MTU: 最大传输单元(Maximum Transmission Unit,MTU),是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。在以太网中默认为1500字节(FDDI协议:4352字节、PPPoE(ADSL)协议:1492字节、X.25协议(Dial Up/Modem):576字节、Point-to-Point:4470字节)。该值也可以修改,但一般不会超过9000 。
MMS:最大报文长度 。
先来看看建立PPTP连接后,在VPN 服务端查看到的MTU信息:
[root@itohost ~]# netstat -i
Kernel Interface tableIface       MTU Met    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500   0 505456169      0      0      0 502871203      0      0      0 BMRU
eth1       1500   0  6240518      0      0      0  3827401      0      0      0 BMRU
lo        65536   0    37856      0      0      0    37856      0      0      0 LRU
ppp0       1396   0    56154      0      0      0    77684      0      0      0 MOPRU
可以看到eth0、eth1网卡的mtu为1500,ppp0的mtu为1396 。既然如此,iptables中为什么设置mss的值为1356呢?这里写一个简式来表达mtu与mss之间的关系:
MTU(1397) = mss +20字节的IP头部+20字节的TCP 头部
通过上面的表达式计算,可以了解到mss的值为1356,所以上面的iptabls中设置的大小为1356 。

二、解决理论

这里假设连接vpn 进行上面的一台主机为A主机,提供VPN服务的主机为B主机。能过 tcpdump抓包会发现会有unreachable -need to frag (mtu 1396)这样的提示。主机B返回了一个ICMP不可达的差错报文。其含义是VPN主机收到了一个需要分片才能通过的数据包,而这个数据包在其IP头部又设置了不能分片(DF)的标志。所以该数据包不能通过VPN主机。
根据TCP/IP协议,在建立TCP连接时,传输双方都要指明自己的mss(最大报文长度)大小,然后选取双方之中最小的那个mss,以避免在随后的数据传送过程中出现数据包分片传输的情况。通过抓包分析,主机B的mss为1460字节,主机A的mss为1357字节。两者取小所以双方协商的结果确定 mss为1357字节,也就是说以后进行TCP数据传输时,数据包的最大传输单元MTU不能超过1397(mss+20字节的IP头部+20字节的TCP 头部),同时在IP头部设置了不能分片(DF)的标志。
能过netstat -i查看时,可以看到ppp0接口的路径MTU为1396字节,也就是说如果一个数据包想要通过这个接口的话,一定不能大于1396字节,如果大于这个值,会出现两种结果:
1、如果这个数据包的IP头部没有设置不能分片(DF)的标志,那么VPN主机就把这个数据包分片,使其数据包大小小于1396字节,然后允许其通过。
2、反之,如果这个数据包的IP头部设置不能分片(DF)的标志,那么VPN主机就会返回一个ICMP不可达的差错报文。同时丢弃这个数据包。
问题就出在这里,主机A和主机B协商的mss为1357字节,也就是说其TCP数据包的MTU为1397,而ppp0允许的路径MTU却为1396,主机 A的MTU居然大于ppp0的路径MTU!当主机B向主机A发送了一个1397字节的数据包时,自然不能通过ppp0接口了。回到发现问题的那个情况,首页之所以能够显示成功,是因为首页包含的数据较小,传输时只需要一个没有超过1396字节的IP数据包就可以了,所以能够显示出来,而登陆成功后的页面包含的数据较大,需要分为多个IP数据包进行传输。这里可以假设一下,开头的一个IP数据包因为没有超过1396字节因而通过,而随后的IP数据包因为其大小为1397字节,超过了路径MTU,所以不予通过。反映到页面,就是登陆页面下面的大部分内容无法显示了。

三、iptables结合mss原理

因为mss是在TCP连接建立开始时,通过带有syn标志的IP数据包进行传输的,所以我们在iptables里面规定,在转发数据时,只要发现带有 syn标志并且源地址为主机B的IP数据包时,将其mss设定为1356字节,这样就与ppp0接口的路径MTU相匹配了,数据自然就可以畅通无阻啦。
我们还可以做一个简单的ping测试

1、断开VPN的情况下

pptp-mtu-mss
一步一步测试(-l 后面的为发送缓冲区大小,即MTU大小,可以从1500开始,逐渐减小,直到可以ping通)我们可以得到可以ping通的MTU最大为1472,超出该值会提示需要拆分数据包。

2、连接VPN的情况下

C:\Users\thinkpad>ping -f -l 1396 www.baidu.com
正在 Ping www.a.shifen.com [111.13.100.92] 具有 1396 字节的数据:
需要拆分数据包但是设置 DF。
需要拆分数据包但是设置 DF。
需要拆分数据包但是设置 DF。
111.13.100.92 的 Ping 统计信息:
    数据包: 已发送 = 3,已接收 = 0,丢失 = 3 (100% 丢失),
C:\Users\thinkpad>ping -f -l 1356 www.baidu.com
正在 Ping www.a.shifen.com [111.13.100.92] 具有 1356 字节的数据:
请求超时。
请求超时。
一步一步测试(XXXX为MTU大小,可以从1500开始,逐渐减小,直到可以ping通)我们可以得到可以ping通的MTU最大为1372 。需要注意的是,这个测试尽量还是找内容的主机进行ping 测试,上面对baidu进行测试时,非正常ping包,其会不回包,直接拦截掉的。
不过最终iptables中 mss 的设置还是要以服务端的默认配置为准,通过netstat -i 查看得到ppp0口的mtu值 ,再做mtu-20字节的IP头部-20字节的TCP 头部= 1356 ,计算出iptables中需要设置的mss的值。

发表评论