大家好,现在是人静时分,我公司人员都已溜光,只有我还在面对computer, 在经过不解、迷惑、结论之后,现与大家分享结果,感谢朋友Zyliday,见贤思齐的实验帮助。
在研究技术原理之前,让我们先了解几个基本的概念。我们要了解NAT技术,这个就不用多说了吧!我们的主机大部分存在于一个内部网络中,有一个私有ip地址,所以所有去往Internet的数据包,都要将其源ip与端口转换,来实现数据通信。让我们感到幸运的是,我们对于互联网的服务应用,大部分用tcp与udp协议来传输,由于tcp与udp协议中含有端口,所以往返的数据包很容易找到归宿。但难免会有特殊出现,pptp协议,协议,ftp 协议,ipsec 协议等,根据其各自协议特殊原因,均无法顺利通过nat,俗话说兵来将挡水来土掩,nat该怎么办?
今天重点我们放到pptp协议身上。pptp是什么?pptp是其隧道协议中的一种,加以其它协议的配合,成功实现了身份验证、加密数据和协议配置等问题,为远程用户创建了一条穿越公网的安全连接,下面让我们去了解PPTP协议。
PPTP流量由两条连接产生:
• PPTP控制连接
这是一个逻辑连接,表示必须通过一系列PPTP消息创建、维持和终止的PPTP隧道。 PPTP控制连接流量使用PPTP客户端上动态分配的TCP端口,以及PPTP服务器上由IANA保留的TCP端口1723。
• PPTP数据连接
当数据通过PPTP连接发送时,PPP帧将使用通用路由封装(Generic Routing Encapsulation,GRE)报头进行封装,报头包含用于识别该数据包的特定PPTP隧道的信息。
现在来分析下,由于控制连接用了端口1723,所以这条连接我们就大可放心了,根据nat发送原则,会成功将数据包转发到pptp 服务器,如果你的 服务器建立于内网中,在路由上映射其1723端口到服务器就OK.
让我们看下数据连接,我们发现以经没有了tcp协议参与,反而成了GRE协议包与PPP协议包,为什么它无法通过nat呢?来看下GRE协议格式:
每个字段的详解:
我们发现根本没有发现有端口这个字段,怎么映射?没有就不做端口映射呗~~~就转换ip不就得了。哈哈其实远远不是这样的,这种非常理的数据包格式,对于nat是个问题,对于防火墙也是个问题。今天我们先论nat:先来分析如果一个位于内部网络中( 公网IP 2.2.2.2)的主机A 192.168.1.2与pptp服务器5.5.5.5建立连接,控制连接成功建立,数据连接于由没有端口,nat只做其ip的转换,于是在2.2.2.2这个网络的nat设备上有这样的一个nat表:
源ip |
源port |
协议 |
公网ip |
公网port |
目标ip |
目标port |
192.168.1.2 |
|
GRE |
2.2.2.2 |
|
5.5.5.5 |
|
192.168.1.3 |
|
GRE |
2.2.2.2 |
|
5.5.5.5 |
|
当2.2.2.2这个网络收到来自于pptp服务器的数据流包时,2.2.2.2网络的nat设备发现来自于网络5.5.5.5的gre协议数据包,是给内部主机192.168.1.2的,所以成功通信。分析如果位于2.2.2.2这个网络中的主机B 192.168.1.3 也与5.5.5.5网络中的pptp服务器通信,结果就不太理想了~~如果在nat表中还有一条到达主机192.168.1.3的gre通信,到收到一个gre协议数据包时,2.2.2.2网络中的nat设备犹豫了,这个包给谁呢?192.168.1.2?还是192.168.1.3呢?在此大家也不要忘了,我们的实验环境是只有一个公网ip,内部主机A与B出去的时候,源ip都转换成了公网的ip 2.2.2.2,所以收到的数据包都是目标ip为2.2.2.2,然后nat设备根据端口的不同转发到不同的主机。有两个客户端就无法通信,这就是网上说的位于内部的主机只能与同一服务器之间建立一个会话,不能有第二个客户端。
技术的流行,但技术上有约束,人们想办法开发能穿透nat的设备,实现多路复用。在细分析gre协议后,人们发现gre协议中有一个字段,可以拿来利用,那就是这个call id值,这个值并不固定,可以改变。这个值是怎么回事呢?用来标识唯一会话的。这个值最早出现在控制连接中,客户端与服务器互相通告彼此的call id值,然后在其数据连接中,服务器call id值写上客户端的,客户端写上服务器的call id值。nat引入了一种技术nat编辑器,大家可以去看下我们的路由器,大部分自动开启了对ipsec隧道与pptp隧道协议的支持。路由器对pptp隧道的建立实施全程监控,并在每一台PPTP客户机的私有IP地址、CALL ID和公共IP地址以及PPTP服务器接收的CALL ID之间建立单独的映射关系。我可以把call id值当做端口来看,然后添加到nat表中。
让大家看一个今天做的一个实例图(pptp客户端路由器NAT表):pptp数据连接我们可以认为它有两条nat映射记录,一个用于数据包的发送,一个用于数据包的接收。
源ip |
源port |
协议 |
公网ip |
公网port |
目标ip |
目标port |
192.168.1.10 |
5000 |
TCP |
59.173.163.119 |
50001 |
221.217.151.68 |
1723 |
192.168.1.10 |
30061 |
GRE |
59.173.163.119 |
32769 |
221.217.151.68 |
进 |
192.168.1.10 |
256 |
GRE |
59.173.163.119 |
256 |
221.217.151.68 |
出 |
192.168.1.11 |
10000 |
TCP |
59.173.163.119 |
50002 |
221.217.151.68 |
1723 |
192.168.1.11 |
5868 |
GRE |
59.173.163.119 |
32770 |
221.217.151.68 |
进 |
192.168.1.11 |
512 |
GRE |
59.173.163.119 |
512 |
221.217.151.68 |
出 |
nat把客户端的call id值当做源端口,然后告诉服务器一个假的call id(应该叫转换后的call id,客户端跟端口转换一样)来充当转换后的端口。这个修改是在控制连接中修改的,然后做nat记录后发送给服务器。(说到此我说下,前两天在弯曲评论上看到了一文章,作者写到nat对其服务器的call id也转换)我认为不转换服务器的call id值。
在我们实验的时候,一开始我让多个不同外网的朋友建立连接,连接我这边内部服务器主机,抓包发现服务器通告的call id都一样,不解?如果在同一个内部网络中,有两个客户端连接进来,服务器通告的call id不改变,通信将出故障?今天又与见贤思齐做了一个同一内部网络中,多个客户端连接情况,抓包发现服务器对于同一个ip多个客户机的连接分配了不同的call id值,所以直接修改其客户端call id便可实现流量多路复用,服务器自动解决了这个同一ip不同call id值问题。
客户端192.168.1.10的连接:
服务器方抓包分析如下:
上图:客户端在控制连接中,告诉服务器它的call id值为32769。
上图:服务器控制连接中告诉客户端它的call id值为256。
客户端抓包分析如下:
上面客户端告诉服务器它的call id为30061。
服务器告诉客户端它的call id值为256。
看了以后大家知道nat做数据包做了什么处理了吧,客户端12的连接我就不贴图了,道理一样。这样的端口改变还可以避免不同的客户端告诉服务器相同的call id,因为它无法意识到另一个主机也用了此call id ,如果nat不加转换,将出现问题。
好了不说了,明天是十一,祝大家玩的愉快。
看了感觉有用,所以顶一下。
哈哈
嘿嘿 注意到一个小地方没 request包的call id是变化的 reply包的call id是不变的