PPTP有两个流,一个是控制流(RFC2637定义),另外一个数据流(GRE, RFC2784)。和一般的ALG不同的是(比如FTP),NAT遇到PPTP的时候,不是端口或 者IP惹的祸,而是PPTP里面callID(抛一个球给各位,为何PPTP把call ID整到 PPTP控制流里面?)。在PPTP协议里面,有一个call ID的概念,客户端向服务器 发起连接,会告诉服务端我的call ID是多少,服务端也会回应客户端它的call ID是多少,并且更重要的一点是,这个call ID在以后的某些(注意不是全部哦) 控制传输中需要用到,在所有的数据传输中(GRE)需要用到。而接下来我们从两 个方面一起来看一下问题是如何产生,以及如何去解决:
从内网向外网 发起PPTP连接请求
从外网向内网发起PPTP连接请求(俗称静态映射)
走,咱们去看看外面的世界
(注:下面的结构是1)提一下PPTP协 议;2)提一下GRE协议;3)如何搞定GRE数据流;4)如何搞定PPTP控制流。)
PPTP服务器是监听在TCP/1723端口。客户端发送的第一个携带call ID的 数据包是被称为Outgoing-Call-Request的数据包,一个示例如下图所示(忽略了 前面的以太网头,IP头,以及TCP头):
可以看到我们这边的示例客户端的call ID是16384(这个call ID是给自己分 配的),那我就以Client-Call-ID表示吧。
服务端收到这个数据包之后 ,然后会回应一个称为Outgoing-Call-Reply的数据包,示例如下:
这个说明服务端自己的call ID是107(这个服务端是给自己分配的,我就以 Server-Call-ID表示), 同时也把Client-Call-ID返回给客户端。咦,这样看来 好像没有什么问题嘛,反正这个call ID改不改,对于这一条连接都没有影响, NAT也可以正常运作。但是,各位看官,PPTP还需要用到一个协议,那就是GRE (RFC 2784)。而GRE是一个和TCP以及UDP处在同一个水平线的协议。但是和 TCP/UDP之流不同的是,GRE里面不携带端口信息,而它利用的就是call ID来作 multiplex以及demultiplex的。我们看一下客户端发给服务端的一个GRE数据包( 提示一点,GRE头后面的是PPP协议封装,不过这里不需要关心):
里面有call ID,这个call ID不是说自己的,而是说对方的(对,就是PPTP里 面的那个Server-Call-ID),也就是服务端的,也就是我这个GRE数据要发给服务 端的107“端口”。
而服务端也采用同样的策略,只不过call ID表明的 是客户端的,一个示例如下:
(注:上面的都是一些协议的原理,如果你读了RFC,未必不懂这些。插一个 情景,来自一个电影:C开一辆车在公路上,前面有一个人D骑一辆自行车。C在 追D的,C紧张的说:“你。。。你骑自行车未必比我开车快!”)
问题是 这些个数据包也要经过我们可怜的NAT啊,GRE会问NAT:“我这个call ID,管还 是不管?”,NAT答曰:”不管。”话虽如此,但是谈何容易,因为GRE里面没有 端口,如果NAT不伪造一个端口的话,下面的情形就不堪设想了:
一个主 机A的IP地址是192.168.1.2,向1.1.1.1(声明:这里仅仅是假设,没有对其进行 真正的试验,1.1.1.1请不要见怪)发起PPTP连接请求,Client-Call-ID是16384 ,Server-Call-ID是107;
还有一个主机B在内网,IP地址是192.168.1.3 ,也向1.1.1.1发起PPTP连接请求,Client-Call-ID2是16385, Server-Call- ID2是108。
NAT如果仅仅是转换IP地址(假设NAT的公网IP是 116.238.184.159),那么数据到能够到达1.1.1.1,可是GRE数据包回到 116.238.184.159的时候,NAT这个时候是该把它发给192.168.1.2呢,还是 192.168.1.3呢?在这种情况下,NAT必须要找一个“端口”,来决定这个数据包 是发给谁,而“端口”需要满足以下特性:
在一台主机上,这个是唯一 的;
必须每个数据包中都存在。
而扫描整个GRE数据包,只有call ID具有此特性。所以这个关系是这样的,由于GRE数据包里面没有像TCP/UDP的端 口信息,所以需要这样一个信息,而call ID的存在恰恰满足了这样一个条件。 但是call ID和TCP/UDP端口有不一样的地方:
TCP/UDP的端口在传输层中 的位置是一样的,相对偏移量是0,而call ID在传输层里面的偏移量是 6;
TCP/UDP的端口在每个数据包里面都会携带源端口和目的端口,但是 call ID仅仅携带一个,并且是指对方的。
意识到这些不同点非常重要, 这会影响到NAT对待TCP/UDP和GRE要完全不同,而也正是PPTP ALG的原因之一!
嘿嘿,是否对为何需要针对GRE作特殊处理的原因了吧?好,那我们看如 果保证GRE数据包能够顺利通过NAT。