现在的位置: 首页 > 综合 > 正文

FTP中的NAT

2017年12月22日 ⁄ 综合 ⁄ 共 2335字 ⁄ 字号 评论关闭
文章目录

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

当然,这仅仅是一个假设,许多应用不会用到网络层以及传输层里面的信息;还有一些应用会在应用层携带者IP或者端口信息,比如迅雷,但是没有它,天
也不会塌下来;不过还有一些应用,非常需要它,如果没有它的话,当然天倒不会塌下来,但是一碰到NAT它却有可能没法活了,这些应用比如有
FTP,PPTP,VoIP等。。。。。。此时就需要NAT从中忽悠了,这个被称为ALG(Application 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模式

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

image

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

image

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

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

image

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

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

image

即为32597

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

image

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

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

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

image

这个时候,我们可以看到,情况有点不一样了,此时是客户端直接把自己的IP和开放的端口告诉给了服务端了,在这里IP是192.168.16.5,端口是
2230。服务端能够向192.168.16.5的2230端口发起数据请求吗?答案是否定的。这个时候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,这样服务端也不干啊,所以针对客户端发送出去的SEQ,NAT需要加上3。以后在这条连接上面,NAT需要做这样的事情over
    and over again去忽悠客户端和服务端;
  • 最后别忘了更新IP校验和,以及TCP校验和。

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

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

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

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

后记

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

抱歉!评论已关闭.