曾几何时,所有的ftp客户端都使用PORT。PORT的实质是,我侦听一个端口,你来连结我。事情在1989年起了变化,新发布的RFC 1123建议所有的FTP服务器支持PASV。PASV与PORT相对,服务器侦听一个端口,客户机连接服务器。RFC的动机在于支持一种比较高效的服务器之间转移文件的技术:proxy FTP,客户端仅负责控制,数据直接在服务器之间转移。
虽然最初RFC希望FTP的控制信息和文件传输在同一个连接上实现,但是实际上人们都为文件传输另外建立一个连接。PORT和PASV都是建立文件传输连接的具体办法,PORT和PASV, proxy FTP在实现上的细节很繁琐,大致的说,客户端用PASV命令使甲服务器在某某端口上等待连接,用PORT命令通知乙服务器连接到甲上,这样甲、乙互相传送文件,通讯量也算在他们身上。
下面是操作方法的示范,我在FreeBSD上运行。在这个例子中,我把file (ftp://foreign.host.com/pub/file)从foreign.host.com复制到neighbor.host.com (ftp://neighbor.host.com/incoming/file),再从neighbor.host.com下载,这样出国通讯费加在neighbor.host.com上面(这 可不是proxy FTP“正当”的用法:)。
ftp>open neighbor.host.com neighbor host open. (output message sniped) ftp>proxy open foreign.host.com foreign host open. (output message sniped) ftp>cd incoming ftp>proxy cd pub ftp>proxy put file file transfer start .... finished. ftp>proxy close ftp>get file ftp>bye
也可以这样:
ftp>open foreign.host.com foreign host open. (output message sniped) ftp>proxy open neighbor.host.com neighbor host open. (output message sniped) ftp>cd pub ftp>proxy cd incoming ftp>proxy get file file transfer start .... finished. ftp>proxy close ftp>close ftp>open neighbor.host.com neighbor host open. (output message sniped) ftp>cd incoming ftp>get file ftp>bye
这样使用proxy FTP有所限制。两个服务器当中必须有一个支持PASV(这不成问题。现在很少有服务器例外了),另外一个必须不检查PORT命令的范围(比如FreeBSD的ftpd)。应当用open命令打开不检查PORT命令的范围的服务器,用proxy open命令打开支持PASV命令的服务器。
历史充满了偶然,proxy FTP被证明是危险而且不甚实用的,现在多数的ftp服务器程序检查PORT命令的范围,看请求连接到的ip是不是请求者的ip。这样做一半是为了阻止proxy FTP。同时,为了proxy FTP所设计的PASV却被证明安全而且实用,因为这使得客户端可以在NAT防火墙后面接收文件。这最终导致RFC1579自相矛盾地建议所有的FTP客户和服务器都用PASV模式取代PORT。这很可能在几年以后变成事实。所以现在实在应该加紧用proxy FTP:)