文件传输协议(FTP)诞生于1971年,至今已经有40多年历史,作为最基础常用的互联网协议之一,它到现在依然发挥着重要作用。和大多数网络协议不一样,FTP是一个非常奇葩的网络协议,说它奇葩主要是有以下两点原因:第一是FTP有两个通道,数据通道和控制通道,数据通道用来传递数据,而指令通道用来传送客户端发送给服务器的指令。第二是FTP有主动和被动两种操作模式,他们的不同在于数据通道的连接方式,接下来我们来详细分析一下FTP协议。
和HTTP协议一样,FTP协议也是文本协议,和其不同的是,FTP是有状态的信息,和SMTP更为相似,它的所有指令如下:
CWD XCWD CDUP XCUP SMNT* QUIT PORT PASV
EPRT EPSV ALLO* RNFR RNTO DELE MDTM RMD
XRMD MKD XMKD PWD XPWD SIZE SYST HELP
NOOP FEAT OPTS AUTH* CCC* CONF* ENC* MIC*
PBSZ* PROT* TYPE STRU MODE RETR STOR STOU
APPE REST ABOR USER PASS ACCT* REIN* LIST
NLST STAT SITE MLSD MLST
为了验证FTP是两条通道,首先用FlashFXP登陆一个FTP服务器,ftp.ietf.org,然后用netstat查看本地socket状态:
netstat -an | findstr 4.31.198.44 TCP 192.168.1.56:65392 4.31.198.44:21 ESTABLISHED
可以看到只有一个65392的本地端口和远程FTP连接,接下来,试图下载服务器上的所有文件,然后不断监控本地socket状态,发现除开远程的21号端口外,还有其它的端口被连接,而且端口号处于不断的变化当中:
第一次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED TCP 192.168.1.56:65480 4.31.198.44:61254 ESTABLISHED
第二次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED
第三次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED TCP 192.168.1.56:65481 4.31.198.44:60724 ESTABLISHED
第四次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED TCP 192.168.1.56:65482 4.31.198.44:62712 SYN_SENT
进一步观察可以得出,每传送一个文件,服务器开一个端口,完成传送后,服务器关闭相应的端口,查看FlashFXP可知,当前使用的模式是被动模式。
我打开FlashFXP的主动模式,然后查看socket情况:
第一次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED
第二次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED TCP 192.168.1.56:49387 4.31.198.44:20 SYN_RECEIVED
第三次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED TCP 192.168.1.56:49390 4.31.198.44:20 LAST_ACK
第四次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED TCP 192.168.1.56:49391 4.31.198.44:20 SYN_RECEIVED
观察可知,服务器连接端口为21的指令传送端口没有变化,而20号数据传输端口则时断时续,本地的端口号也一直变化。
继续监控本地socket的监听状态,发现本地端口是处于监听状态。
从这里我们似乎就可以总结FTP主动模式和被动模式的区别,被动模式下,数据通道建立的过程中是客户端主动连接服务器,而主动模式下是服务器连接主动连接客户端。而主动被动,是针对服务端而言的。实际上他们的主要区别如下:
主动模式
主动模式下,FTP客户端从一个随机的非特权端口(大于1024)N连接到服务器的21号指令端口,接着客户端监听本地的N+1号端口,并用PORT指令把这个端口号发给服务端。服务器收到这个请求后,用20号端口连接到客户端指定的端口。流程图如下:
第一步,客户端的指令端口连接上服务端的指令端口,接着发送PORT 1027的指令。第二步服务端指令通道返回ACK给客户端,第三步服务端通过本地的20号端口和客户端指定的端口建立一个socket连接,最后客户端返回ACK给服务端。
在主动模式下,客户端实际上并没有做多余的操作,只是主动连接上了客户端并且监听了本地的一个端口。
被动模式
主动模式下,服务端需要主动连接到客户端指定的端口,而客户端的环境千奇百怪,如果客户端处于内网中,很难保证路由设备对数据通道连接的支持,所以被动模式被开发出来。被动模式下,服务端还是监听模式的21号端口,当建立连接时,客户端在本地初始化两个非特权端口,一条用于指令通道,一条用于数据通道。当指令通道连接后,客户端用PASV指令告诉服务端使用被动模式,然后服务端给客户端返回客户端开启的数据端口,客户端用初始化好的端口连接服务端指定的数据端口,接着进行数据传输。流程图如下:
评论列表: