首页 > 学技术 > 技术网文 > VPN > 正文

[精彩] WindowsXP VPN 拨号器的一个重要缺陷导致无法访问新浪网


来源 chinaunix.net 酷勤网整理

近期在linux上作了一个vpn服务器,利用windows的自带的拨号程序可以顺利拨入,并可上网,但随后发现一个重要问题,直接影响了客户端的上网功能。问题如下:
利用windowsXP PC机拨号后,无法访问[url=http://www.sina.com.cn]新浪网,除新浪网之外,还发现几个其它不太重要的网站也是无法访问。但利用windows2000 PC机拨号后,访问所有网站均正常。为了最后验证这个这个现象,我还在一台机器上反复安装了2000及XP。



 woooo_111 回复于:2006-01-28 08:56:30

后来在服务器上发现,windows2000拨号端口的mtu为1496,而windowsxp拨号端口的mtu为1396。
然后到处搜寻问题的答案,在本论坛也搜寻了半天,没有查到问题的解决方案,后来查到一篇文章[url=http://fanqiang.chinaunix.net/app/other/2005-09-13/3655.shtml]《使用Windows XP连接VPN成功后,在传输“大块”数据时会出现数据堵塞,导致数据传输失败》,按照作者tjyihui的建议修改我的iptables脚本,在数据包通过ppp端口前将mtu值变大,但后来又将发现的其它一些网站放进去后,又出现其它问题。由于是人手工向脚本里添加,解决方案不完美,于是我又找其它解决方案:

[ 本帖最后由 woooo_111 于 2006-1-28 08:58 编辑 ]


 woooo_111 回复于:2006-01-28 10:28:56

在linux VPN服务器主机上,为了解决手工添加特殊网站地址iptables脚本的不方便的问题,可以通过以下命令手工修改windowsXP拨号端口的mtu值:

ifconfig ppp0 mtu 1496

但不可能手工修改每一个随机拨号上来而在服务器上建立的端口ppp*,所以需要创建一个自动执行的脚本,在每一个成功拨号后自动运行,将ppp*端口的mtu值修改为1496,解决过程如下:
在/etc/ppp/下创建ip-up.local脚本,创建后就会在每一个拨号建立后自动运行,从而将每一个ppp*端口的mtu修改为稍大一些,脚本内容如下:

#!/bin/bash

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH
ifconfig $1 mtu 1496


引用:
注:本主题创建后发现本论坛的一篇文章谈过此问题,此文章的主题为[url=http://bbs.chinaunix.net/viewthread.php?tid=455705&extra=page%3D1]《Fedora core 2下建立Poptop服务器以及常见问题 》,但没有提供自动脚本的解决方案,本文算是个补充吧。



[ 本帖最后由 woooo_111 于 2006-1-28 10:53 编辑 ]


 wenzk 回复于:2006-02-05 16:15:46

呵呵,我也碰到同样的问题,多谢大侠的奉献


 phpman 回复于:2006-02-07 15:01:16

$man pppd
发现有如下,可以在options.pptp中定义mru和mtu的大小。

       mru n  Set the MRU [Maximum Receive Unit] value to n. Pppd will ask the peer to send packets of  no  more  than  n
              bytes.   The  value  of n must be between 128 and 16384; the default is 1500.  A value of 296 works well on
              very slow links (40 bytes for TCP/IP header + 256 bytes of data).  Note that for the IPv6 protocol, the MRU
              must be at least 1280.

       mtu n  Set  the MTU [Maximum Transmit Unit] value to n.  Unless the peer requests a smaller value via MRU negotia-
              tion, pppd will request that the kernel networking code send data packets of no more than n  bytes  through
              the PPP network interface.  Note that for the IPv6 protocol, the MTU must be at least 1280.


 xlcc 回复于:2006-02-09 10:27:01

我也碰到了,具体解决方法是: 选择 -----VPN拔号属性---->网络------>TCP/IP---->属性---->高级------>常规
把"在远程网络上使用默认网关"前面的勾去掉.


 phpman 回复于:2006-02-10 09:46:03

引用:原帖由 xlcc 于 2006-2-9 10:27 发表
我也碰到了,具体解决方法是: 选择 -----VPN拔号属性---->网络------>TCP/IP---->属性---->高级------>常规
把"在远程网络上使用默认网关"前面的勾去掉. 


这个方法不可取,除非一些特殊情况~~
详细情况清google,或者
c:\> route print
仔细看看就明白了~~:mrgreen::mrgreen:


 woooo_111 回复于:2006-02-14 07:46:34

引用:原帖由 phpman 于 2006-2-7 15:01 发表
$man pppd
发现有如下,可以在options.pptp中定义mru和mtu的大小。

       mru n  Set the MRU [Maximum Receive Unit] value to n. Pppd will ask the peer to send packets of  no  more  than  n
        ... 


我试验过这个选项,但一直没有解决问题,如果将options.ppt文件中的mru及mtu值变大,要么拔不上,要么拔号端口的mtu值就是还是原来的,好象此参数不是用来解决这个问题的,至于实际用途还未碰到,不是太明白。


 woooo_111 回复于:2006-02-14 07:52:26

引用:原帖由 xlcc 于 2006-2-9 10:27 发表
我也碰到了,具体解决方法是: 选择 -----VPN拔号属性---->网络------>TCP/IP---->属性---->高级------>常规
把"在远程网络上使用默认网关"前面的勾去掉. 


我遇到的问题与你谈到的问题不是同一个问题,你的问题似乎是缺省网关要保持拔号前的网关,而不能改成拔号服务器所给的,否则将无法上网。
而我所遇到的问题是,我需要将缺省网关改成拔号服务器所给的,否则将无法上网,但一切正常之后(几乎所有上网功能均正常了),仍有极少数网站由于mtu值的大小问题而致丢包,从而导致这部分网站无法正常访问。


 soway 回复于:2006-02-14 08:41:42

mtu引起的问题是很讨厌的.
不过你这里居然是1396不能访问.按理说应该是大的MTU包通过某些设备才会导致问题的.
如果1396通过不了,那么1496更加通过不了才对.

所以,我经常修改防火墙上面的MTU为比较小的值.


 woooo_111 回复于:2006-02-14 12:57:22

引用:原帖由 soway 于 2006-2-14 08:41 发表
mtu引起的问题是很讨厌的.
不过你这里居然是1396不能访问.按理说应该是大的MTU包通过某些设备才会导致问题的.
如果1396通过不了,那么1496更加通过不了才对.

所以,我经常修改防火墙上面的MTU为比较小的值. 


不好意思,怪我说的太不详细,我的问题是:windowsXP客户机拔号上去之后,在vpn服务器上创建的ppp*端口的mtu值为1396,而客户机与新浪网等特殊网站握手协商的数据mtu值正好是1397,稍大于端口mtu值,就好比管道(端口)太细,水流(数据)太粗,所以无法通过.


 recoilest 回复于:2006-04-11 18:49:11

原文:
http://www.slack.cable.nu/blog/p/mtu.html.php

这是一个比较复杂的问题。首先,发现问题的过程是这样的:使用一台WinXP的电脑(简称主机A)连接公司的VPN成功后,访问内网的一个基于 B/S的CRM系统(简称主机B)时,发现首页可以显示(页面比较简单,包含的数据量较小),输入账号密码登陆后,发现只能显示页面顶部的一点点内容,而下面大部分内容无法显示。而换一台Win2000的电脑登陆,内容就可以完全显示出来。登陆到Linux VPN主机上,利用tcpdump对数据传输过程进行抓包分析,发现:每当B向A传输大于1396字节的数据时,VPN主机就会反馈B如下信息 
注意: 
10.87.0.200:VPN主机的内网网卡的IP地址 
10.87.200.1:主机A的IP地址 
10.87.200.6:主机B通过VPN获取的IP地址 
21:54:21.953848 IP 10.87.0.200 > 10.100.0.100: icmp 556: 10.100.0.203 unreachable - 
need to frag (mtu 1396) 
可以看到VPN主机向提供web服务的主机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)的标志。 
然后在VPN主机上执行netstat –i,观察各个网络接口的路径MTU值为多少。观察结果如下: 
Iface MTU 
eth0 1500 //外网网卡接口 
eth1 1500 //内网网卡接口 
lo 16436 //本机回环接口 
ppp0 1396 //WinXP VPN接入通道接口 
可以看到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,所以不予通过。反映到页面,就是登陆页面下面的大部分内容无法显示了。 
我们再来看看用安装了Win2000主机C连接VPN又是什么状况呢?通过抓包发现,主机C提出的mss为1360(可以推算出其MTU为1400),而执行netstat –i,发现此时的ppp0的MTU为1496,路径MTU大于主机C的MTU,这个结果是正常的。 
大家一定会问,何主机B提出的MTU小于路径MTU,这个问题只能问问微软了,我查了一些英文资料,说这是WinXP本身系统的一个问题。 
知道了问题的原理,那让我们来看看如何进行解决吧。解决方法很简单,就是借助iptalbes,设定主机B进行协商时提出的mss为1356。即在iptables里面加入一条规则: 
代码 
iptables -A FORWARD -p tcp --syn -s 10.87.200.0/31 -j TCPMSS --set-mss 1356  

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

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

[ 本帖最后由 recoilest 于 2006-4-11 18:51 编辑 ]


 woooo_111 回复于:2006-05-03 18:48:23

楼上提供的方案,我在本帖前文中已经提到,就是利用iptalbes修改所有经过ppp的数据包,但是有问题,而且必须手工将发现的网站添加进iptables脚本中,不算完美。


 fleerzh 回复于:2006-09-18 13:32:23

我也碰到了这个问题,发现qq登陆,ping这些都没问题,就是访问网页时错误,用tcpdump抓包发现vpn服务器会向要访问的网站发送如下的信息
icmp: 192.168.0.22 unreachable - need to frag (mtu 1396) [tos 0xc0]
采用楼主方法后解决了,谢谢


 platinum 回复于:2006-09-18 20:05:53

引用:原帖由 woooo_111 于 2006-2-14 12:57 发表
不好意思,怪我说的太不详细,我的问题是:windowsXP客户机拔号上去之后,在 vpn服务器上创建的ppp*端口的mtu值为1396,而客户机与新浪网等特殊网站握手协商的数据mtu值正好是1397,稍大于端口mtu值,就好比管道(端口)太细,水流(数据)太粗,所以无法通过.


MTU 小于 WEB SERVER 还不能访问?
你的解释让我感到有些费解。。。。


 woooo_111 回复于:2006-09-20 13:44:29

引用:原帖由 platinum 于 2006-9-18 20:05 发表

MTU 小于 WEB SERVER 还不能访问?
你的解释让我感到有些费解。。。。 



请注意,你所引用的我所说的上文是PPP端口mtu值小于数据mtu值,就好比管子细,水流粗,过不去。


 i770880 回复于:2007-01-07 18:24:32

引用:原帖由 woooo_111 于 2006-5-3 18:48 发表
楼上提供的方案,我在本帖前文中已经提到,就是利用iptalbes修改所有经过ppp的数据包,但是有问题,而且必须手工将发现的网站添加进iptables脚本中,不算完美。 



我刚开始弄这个pptp,就出现这样代的问题,只有google可以用,其他的网站都是找到地址后就打不开,网易popo是可以用的。要怎么配置才能使所有网站都可以呢?

ps:刚才在linux建立连接后,和在winxp下表现一致,看样子不能算在winxp的拨号问题上。
很奇怪的是,就google打得开,其他的都打开到一半时候没反应。

[ 本帖最后由 i770880 于 2007-1-7 20:51 编辑 ]


 ttvast 回复于:2007-01-07 22:23:41

引用:原帖由 i770880 于 2007-1-7 18:24 发表


我刚开始弄这个pptp,就出现这样代的问题,只有google可以用,其他的网站都是找到地址后就打不开,网易popo是可以用的。要怎么配置才能使所有网站都可以呢?

ps:刚才在linux建立连接后,和在winxp下表现一 ... 



我只要加上那一句iptables就可以了阿,不需要手工再添加其他的网站阿。因为那一句rule是针对所有网站生效的

那些无法访问到的服务器,我估计主要原因是防火墙将这个数据包屏蔽掉了,这个也算是防火墙配制错误吧。
icmp: 192.168.0.22 unreachable - need to frag (mtu 1396) [tos 0xc0]




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=694733
转载请注明作者名及原文出处



收藏本页到: