NAT 心得

来源:互联网 发布:自拍风格淘宝女装店 编辑:程序博客网 时间:2024/04/29 15:05

前言:做了十几天的NAT穿越,网上的资料很多,一搜一堆,但也都是大抄小抄,基本上能自己写的也就那么几篇,但自己实现的时候总是不成功,原理并不难,为什么总是不成功呢,当时只纠结于我在实验室跟女朋友公司的电脑通信,我能收到她的,可她就是收不到我发过去的信息,按说这是不可能的啊,后来我让其它实验室的同学帮做测试,是可以通的,当时感觉我们应该是在一个局域网,通的话也是理所当然的,但今天再做测试,从服务器上显示的IP来看,我们是不同的IP地址。这说明了,我的程序是正确的,打洞成功了!!!!我女朋友那收不到很可能是防火墙的问题。这些天查了很多的资料,也想了很多的办法,就在这里做下笔记吧,希望能帮到大家。

我这有个NAT类型测试工具,很好用,不要分,大家可以去下载:http://download.csdn.net/detail/harvic880925/5327776

(在做P2P测试之前一定要先检测两边的NAT类型,如果是对称型的NAT还是绕过吧)

首先,我想讲下NAT的类型。

1、 Full Cone NAT (全通型NAT)

所有来自同一 个内部主机的请求均被NAT转换至同一个外部地址+端口,而不管这些请求是不是属于同一个应用或者是多个应用的。而且很重要的是,这种NAT不对外来主机的地址进行过滤,只要能找到相应的SESSION,由于对外部请求的来源无任何限制,因此这种方式虽然足够简单,但却不那么安全

原理如下:

我认为这种NAT,在它的NAT表中只有这两个信息

源IP                         NAT端口号

10.0.0.10                    1200

10.0.0.11                    1311

当10.0.0.10的主机向外部通信时,NAT会把它转换为:221.23.56.64:1200的地址,不管目标地址是哪里,全部用这个地址加端口通信。相反,当此NAT接收到从外来主机发回的信息时,根据目标地址的NAT端口号1200,查找NAT表,然后将数据包发给10 .0.0.10的主机。

更重要的是,因为NAT表中没有目标主机啥啥的过滤项,只要第三方主机知道了221.23.56.64:1200这个地址,就能直接发信息给10.0.0.10了,NAT不会管这个第三方是不是曾经跟10.0.0.10通过信。

2. Restricted Cone NAT (地址受限型NAT)

很容易理解,所有来自同一个内部主机的请求均被NAT转换至同一个外部地址+端口,这与Full Cone相同,但不同的是,只有当内部主机曾经发送过报文给外部主机(假设其IP地址为Z)后,外部主机才能以Y中的信息作为目标地址和目标端口,向内部 主机发送UDP请求报文,这意味着,NAT设备只向内转发(目标地址/端口转换)那些来自于当前已知的外部主机的UDP报文,从而保障了外部请求来源的安全性。

原理如下:

这个NAT的NAT表中比上面全通型NAT多了一项内容,它的NAT表如下:

源IP                目的IP                 NAT端口号

10.0.0.10      40.23.67.84              1200

10.0.0.10      233.46.87.65            2300

10.0.0.10      132.68.53.211         1304

从上面的NAT表中就可以看到,当目的IP不一样时,NAT的端口号是不一样的,所以当一个信息传过来要与NAT的内部主机通信时,它首先匹配端口号对不对,如果端口号对了,再查看发送这个数据报的源IP,是不是根NAT表中记录的目的IP一样,如果不同就丢弃。也就是说,这种NAT是识别IP地址的

3. Port Restricted Cone NAT (端口受限型NAT即NAPT)

4. Symmetric NAT(对称型NAT)

下面对第三种和第四种做详细的讲解:

下面先说下NAT的转换法则:

现在来看一下我们最关心的问题,就是NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的呢?主要有一下几个策略:

A. 源地址(内网IP地址)不同,忽略其它因素, 在NAPT上肯定对应不同的Session
B. 源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session
C. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)相同,目的端口不同,则在NAPT上肯定对应同一个Session
D. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)不同,忽略目的端口,则在NAPT上是如何处理Session的呢?

D的情况正式我们关心和要讨论的问题。依据目的地址(公网IP地址)对于Session的建立的决定方式我们将NAPT设备划分为两大类:

Symmetric NAPT:
对于到同一个IP地址,任意端口的连接分配使用同一个Session; 对于到不同的IP地址, 任意端口的连接使用不同的Session.
我们称此种NAPT为 Symmetric NAPT. 也就是只要本地绑定的UDP端口相同, 发出的目的IP地址不同,则会建立不同的Session.

Cone NAPT:
对于到同一个IP地址,任意端口的连接分配使用同一个Session; 对于到不同的IP地址,任意端口的连接也使用同一个Session.
我们称此种NAPT为 Cone NAPT. 也就是只要本地绑定的UDP端口相同, 发出的目的地址不管是否相同, 都使用同一个Session.

上面只是说,NAT是怎么让消息出去的,却没有讲怎么让消息进来的。

这段时间,我做P2P打洞,有外网,特意买了个云服务器,嘿嘿,说正题:

我做了服务器端和客户端,两个客户端完全相同,我这边运行一个,女朋友那边运行一个,我能收到她发来的消息,但我就是没办法回送给她,后来我改了改程序,写了两个客户端,在我这边收到她的消息之后,直接用recvfrom()获取的发送过来的地址,回送个消息回去,还是收不到,再后来,远程控制她电脑,抓包,看我发的消息,有没有到她电脑上,抓包显示,根本没有我发过来的包,这说明了个问题,我的包,在路由器时就被丢弃了,这是为什么呢!!!!!百思不得其解,后来我猜测-----:下面是我的猜测的内容,虽然能解释原因,但不知道对不对:

我先画了个图:

一、


讲解:主机A和主机B在登陆时都会向S发送UDP消息,此时S就记录下了A和B的IP和端口,而此时A的NAT(以后我称之为A-NAT)表中,会新增一条Session:

(假设SERVER的IP和监听端口分别是:42.98.87.65:6000)

        源IP                            源端口                目的IP                   目的端口                     NAT端口

10.12.150.19                    20000          42.98.87.65                 6000                          160000

同样B-NAT中,也会新增一条Session:

        源IP                            源端口                目的IP                   目的端口                     NAT端口

198.126.23.67                 10000           42.98.87.65                 6000                          2300

下面讲打洞过程:如果A-NAT和B-NAT都是cone NAT,就会如下的打洞过程:

讲的是A向B打洞,B向A打洞的过程

图示讲解:

上面我们讲了,对于cone NAT,对于主机内同一应用程序的同一端口,不管它发向哪个IP哪个端口,都使用同一个Session号(即NAT端口号)

A向B发送消息(打洞),

即当A向主机B发送消息后,经过NAT后,注意,虽然用的是同一个NAT端口号,但并不代表不增加记录!!!对于不同的目的IP,使用同一个NAT端口号,但会增加一条记录!!!,即:

        源IP                            源端口                目的IP                   目的端口                     NAT端口

10.12.150.19                    20000          42.98.87.65                 6000                          160000

10.12.150.19                    20000          19.67.134.58               2300                          160000

同样B-NAT中,因为B-NAT也是cone NAT,所以B-NAT的NAT转换表中的NAT端口号仍使用同一个转换端口,但仍会添加记录:

        源IP                            源端口                目的IP                   目的端口                     NAT端口

198.126.23.67                 10000           42.98.87.65                 6000                          2300

198.126.23.67                 10000           42.96.223.96             160000                       2300

这样发一会打洞消息后,A-NAT会收到B发过来的消息,

在B发过来的消息中在,IP层中会有如下信息:

                                                          源IP:19.67.134.58  (B的公网IP)

                                                      源端口: 2300

                                                      目的IP:42.96.223.96  (A的公网IP)

                                                  目的端口:160000

重要的来了!!!!

当A-NAT收到上面的IP消息时,会匹配目的IP,对的话说明是发给它的,然后再查找NAT表,匹配目的端口,也就是转换后的NAT端口,大家可以看到在A-NAT表中是有160000这个NAT端口记录的,说明这个消息是给他的,然后再匹配IP中的源IP和源端口是否根A-NAT表中的目的IP和目的端口是否匹配,如有这三项都匹配再根据A-NAT表中记录的源IP,找到要转发给的主机地址,将数据报转发给它!!!!

在写完这篇文章之后,我想我要彻底弄懂NAPT的接收机制,找到了H3C S9500的技术白皮书,上面有这么几句话,讲NAPT的机制的:

(1)         NAT设备接收到私网用户发出的访问公网主机报文。
(2)         如果是私网用户对外发起一个新连接,NAT设备从地址池中选择一对空闲的公网地址和端口,建立NAT转换表项(正反向)。
(3)         根据私网源IP地址、目标IP地址、源端口号和目标端口号查找正向NAPT表项,根据查表结果转换报文,向公网侧发送。
(4)         NAT设备接收到公网侧的回应报文,根据报文的源IP地址、目标IP地址、源端口号和目标端口查找反向NAPT表项,根据查表结果转换报文,向私网侧发送。

大家注意(4),从这句话猜测只有不仅要有NAT端口号正确,而且要源IP,源端口,目的IP,目的端口也要全部正确才会被转发!!!!!其中NAT端口号正确是前提,只有NAT端口号正确了,它才会继续往下匹配!!!!

H3C S9500技术白皮书网址:http://www.h3c.com.cn/Products___Technology/Products/Switches/Catalog/S9500/S9500/White_Paper/200803/336115_30003_0.htm#_Toc192048546



根据上述的猜想过程,我更迷茫了,更不理解为什么我能收到信息,而对方却收不到了,哎,NND,先到这吧,想到之后再接着写吧。


原创粉丝点击