FTP穿越NAT

原文地中:http://hi.baidu.com/sprite72/blog/item/84da7ad39e1e9f2d32fa1c77.html

最简单的NAT只需要修改IP头里面的IP地址,不过大多数的NAT还需要传输层里面的端口。而这里我们仅仅考虑后者。在这个时候,存在着一个问题,那就是如果应用层需要使用IP地址或者端口,该怎么办?

 

当然,这仅仅是一个假设,许多应用不会用到网络层以及传输层里面的信息;还有一些应用会在应用层携带者IP或者端口信息,比如迅雷,但是没有它,天也不会塌下来;不过还有一些应用,非常需要它,如果没有它的话,当然天倒不会塌下来,但是一碰到NAT它却有可能没法活了,这些应用比如有 FTPPPTPVoIP等。。。。。。此时就需要NAT从中忽悠了,这个被称为ALGApplication Layer Gateway)

 

有人会有疑问,那既然这样,别在应用层数据里面使用IP或者端口信息,世界不就安宁了吗?当然,这是一个很好的建议,不过这在FTP是不可行的,因为FTP是在1985年的时候就诞生了(RFC 959),可是NAT是在1994年成为标准(RFC 1631)。但是还有很多应用比如PPTP是在1994年之后成为标准的,但是为何却不肯向NAT妥协呢?请读者讨论(当然,最好能够先问问PPTP等其他协议的作者,当时具体是如何思考这件事情的)。

 

FTP为何需要做ALG

FTP在进行NAT穿透的时候,根据不同的场合而有不同的结果(甚至有时候NAT不需要做任何事情):

客户端是在NAT内网,还是在外网(俗称NAT静态映射);

PORT模式还是PASV模式。

根据FTP协议,FTP会使用一条数据连接来传输数据,并且这条连接的IP和端口是在控制连接里面协商的结果。而决定是否需要做ALG的,就是要看在协商的时候是携带了内网IP和内网端口信息,如果是的话,就需要做ALG。以下分四种情况讨论。

 

客户端在内网,使用PASV模式

比如我现在以IP192.168.16.5,源端口为1315,然后通过firefox直接FTPwww.kernel.org 。首先会建立一条控制连接:


那么在这条连接里面,双方会协商数据传输的端口,在这里采用的是PASV模式:


注意后面的(149202013312785),这个就是本文的灵魂所在(NAT就是需要对这一串数字知根知底,顺便提一下《LOST》里面的4, 8, 15, 16, 23, 42)。在PASV模式下其实就是服务端告诉客户端其IP地址以及其开放的端口,通过以下方式运算得到:

-前面4个字节代表的是IP,逗号是分隔符,这里是:

转换成IP其实就是149.20.20.133,就是服务器的IP

-后面两个代表的是端口,这里是:

即为32597

PASV模式意味着,服务端打开了数据端口,这里是开启了32597端口,所以接下来了客户端会向服务端的32597端口发起连接:


在这种情况下,由于IP和端口是公网的,所以不需要做ALG了。一般的FTP客户端都是使用了这样PASV的方式,所以应用上一般都没有异常。

 

客户端在内网,使用PORT模式

我使用Firefox的一个插件FireFTP作为FTP客户端,并且设置为PORT模式,仍然FTP149.20.20.133,并且传输了一个文件:


这个时候,我们可以看到,情况有点不一样了,此时是客户端直接把自己的IP和开放的端口告诉给了服务端了,在这里IP192.168.16.5,端口是 2230。服务端能够向192.168.16.52230端口发起数据请求吗?答案是否定的。这个时候NAT需要勇敢的站出来了!

 

首先不管怎么说,NAT得把192.168.16.5这个内网的IP修改成公网的IP,这里是116.238.184.142,以便149.20.20.133能够访问得到;

端口呢?端口是否需要修改?这得分情况,如果说NAT出去的端口中没有2230这个端口,那么可以不修改;但是如果这个端口已经被占用了,那么就必须得修改,否则就会出现一台主机(NAT设备)出现两个相同的端口,比如现在我们将其修改成12345,修改之后还必须要添加一条NAT会话(相当于作了一条静态映射),以便服务端发起数据连接的时候能够匹配到;

还有一个事情必须得记住,那就是这些IP信息和端口信息是以ASCII码传输的,所以可能会造成数据包修改前后,长度发生了变化!比如从 192,168,16,5,8,182修改成116,238,184,142,48,57就是从18个字节增加到了21个字节了。所以这个数据包的修改需要同时更新IPLEN字段,并且你得记住你的长度变化(这里是3个字节),因为服务端响应的是后面修改的数据,所以ACK会比客户端预期的多3,当ACK 从服务端过来的时候,NAT要把ACK减掉3,以便让192.168.16.5认识。事情还没有完,由于ACK减少了,这样客户端发送出来的SEQ就是这个被减少了的ACK,这样服务端也不干啊,所以针对客户端发送出去的SEQNAT需要加上3。以后在这条连接上面,NAT需要做这样的事情over and over again去忽悠客户端和服务端;

最后别忘了更新IP校验和,以及TCP校验和。

 

客户端在外网,使用PASV模式

如果在NAT设备内网搭建了一台FTP服务器,客户端在外网来对其进行访问,结果将和前面的不一样。首先需要映射FTP服务器的端口,标准是 FTP/21。而此时由于是服务端报告自己的IP和端口信息,并且传输给客户端,由于服务端的IP信息是内网的,所以NAT需要对其进行修改,如何修改呢?留给读者去分析。

 

客户端在外网,使用PORT模式

想想看看,这个是客户端(外网)报告自己的IP和端口信息,哦,不用动。。。。。。

 

后记

在使用FTP的时候,并且处于NAT的环境之下,如果出现异常的话,就可以怀疑怀疑是否是ALG功能失效导致。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值