我很难理解, 为什么所有的FTP服务器都要求使用被动模式数据通道的端口范围 ,而不是只为所有传入的数据通道连接使用一个数据端口。
FTP服务器在端口21上处理许多同时连接的客户端。Web服务器在端口80上处理许多同时连接的客户端。
那么为什么FTP服务器只能使用一个数据通道端口用于所有传入的被动数据连接(并且仍然能够处理该端口上的许多同时连接的客户端,例如端口1024)?
或者可以吗?
我有兴趣知道为什么这是不可能的或不推荐的技术细节。
关于将数据端口locking为仅一个端口的多个并发FTP会话问题的清晰和技术性的解释是我最深入了解的内容。 什么时候能工作,什么时候不工作,为什么不推荐,等等。
这将是一个疯狂的猜测,因为我没有testing它,你应该自己尝试一下,看看是否有其他一些我可能错过的问题。
我想你可以限制被动端口范围到一个单一的端口 。 实际上你可以看到在这个问题 中实际上使用的是小的端口范围 。 理论上讲,为了支持多个并发连接,你只需要4个值: 本地IP,本地端口,远程IP,远程端口是唯一的。 这是你如何辨别不同的连接。
如果将服务器上的端口locking为单个值,则剩下的唯一variables就是客户端使用的端口。 这不是一个问题,只要客户端拥有足够大的免费临时端口池供您select。 除非它正在做一些沉重的NAT,否则你不必担心这一点。 现在,被警告这将是纯理论性的东西 :如果您在服务器上使用多个端口,则可以通过启用每个端口客户端的number of ports in range
连接中number of ports in range
数来倍增假设的并发连接number of ports in range
。 但在实践中不会发生这种情况,因为我怀疑是否有FTP客户端的实现可以支持这个function(因为它没有什么意义)。 另外,如果客户不得不以这种方式分享他的短暂的港口,不能只是开一个新的港口,那么他就有更严重的问题要处理。 所以,从这个angular度来看,使用单个端口应该是完全安全的。
让我们来思考为什么一个港口可能不够用 。
首先,我可以想出一个真正有问题的FTP服务器实现只使用本地端口号来识别客户端数据传输的情况。 再次,我不认为任何体面的FTPd会这样做。
真正的问题 ( 是的,你可以忽略所有以上的主要题外话 —)) 被动端口范围是在一个非特权范围 。
这意味着您select的端口号 本身 并不是保留的 ,事实上,任何用户进程(不需要root权限)都可以在您的FTP服务器之前抓取它。 如果你有一个丰富的端口池可供select,你只要随机取一个。 如果您必须使用唯一的一个,并且已经被使用,您将无法正确处理传输。
对不起,如果答案似乎有点太投机。 说实话,我努力find一个不用一个端口的原因,除了最后一点之外,我想不出有什么确凿证据。 尽pipe如此,你提出了一个有趣和具有挑战性
FTP依靠两个单独的连接,一个用于控制或命令stream,另一个用于传递数据文件和其他信息,如目录列表。 控制stream通过传统的TCP连接传输。 客户端绑定到非特权端口,并向连接到端口21的FTP服务器发送连接请求。该连接用于传递命令。
在端口或主动模式下,客户端会告诉服务器它将监听哪个次要,非特权的端口。 然后,服务器启动从端口20到客户端指定的非特权端口的数据连接。
当客户端是Web浏览器时,被动模式是一种较新的机制,是默认的。 服务器不是绑定到端口20,而是告诉客户端使用哪个高端口进行数据传输。 数据然后通过非特权端口在客户端和服务器之间传输。
有关更多详情,请参阅:
http://tools.ietf.org/html/rfc959
编辑
至于把服务器locking到一个特定的端口,在一些服务器上是可能的。 例如在vsftpd中,您有以下configuration选项。
pasv_max_port The maximum port to allocate for PASV style data connections. Can be used to specify a narrow port range to assist firewalling. Default: 0 (use any port) pasv_min_port The minimum port to allocate for PASV style data connections. Can be used to specify a narrow port range to assist firewalling. Default: 0 (use any port)
如果您将两个端口设置为相同的,例如pasv_max_port = 12345,pasv_min_port = 12345,您可能能够得到您所要的。 我怀疑这会限制你服务器支持的并发FTP会话的数量。 请testing一下。
FTP服务器可能能够将客户端的数据端口连接与基于源IP的控制端口连接相匹配,而不是基于所使用的端口号。
这将打破客户端连接到两个服务器(一个处于被动模式)的FXP (这可能不是一件坏事),然后在收到被动服务器的PORT信息后,将其作为PORT命令传递给主动模式服务器,模式服务器连接到被动模式服务器。
我怀疑许多服务器不会创build数据套接字,直到客户端请求被动模式。 在这种情况下,如果两个客户端同时请求被动模式,则创build的套接字将需要唯一的端口号。
编辑 :想到FTP服务器不这样做的另一个原因:服务器不能告诉多个用户分开相同的IP地址。
在端口21或80上(就像所有已知的端口一样),有一套协议,客户端用它来告诉它想要什么。 这样服务器就知道你连接了什么。 在数据连接端口上,没有协议。 服务器知道的所有东西 – 唯一的连接是唯一的 – 就是你连接的端口号。
如果您每次连接到相同的端口,服务器将无法知道您要连接的文件。 端口号用作控制连接上的传输请求和数据连接之间的链接。
如果两个客户端同时请求传输,当服务器在单个端口上接受连接时,服务器将无法分辨要传输的文件。 当然,服务器可以使用客户端IP来做出决定(实际上,为了安全起见,许多FTP服务器都会validation客户端IP与控制连接上使用的IP匹配)。
但是这不适用于:
另请参阅FTP数据连接重用 。
听起来就像你已经知道控制端口和数据端口,所以我会切入正题。 控制端口本质上是突发通信,就像网站的端口80一样。 他们可以处理许多不同的请求(不是同时的,但由于他们很快完成,所以要closures)。 另一方面数据端口是FTP发生奇迹的地方。 如果将自己限制为单个数据端口,则一次只能进行一次数据传输。 考虑一个大文件传输。 在单个数据端口打开的情况下,只有传输完成后才能移动其他数据。 这意味着在传输时,第二个用户甚至不能列出ftp文件夹的目录内容。 当然,他们能够成功login,但是他们的行为就像数据端口根本没有打开一样。 如果你可以这样做,一个单一的港口将为你工作的很好。 请记住,一些FTP客户端(我可以想到1蝙蝠)默认情况下设置多个连接在一个单一的会议下载。 所以对于这个客户端来说,在一个单一的端口场景下,考虑批量传输1个大文件和4个小文件。
客户端启动第一个大文件的转移,所有hunky dory。 然后,在传输过程中,它将启动第二个文件。 没有骰子。 那么第三,也是zilch(技术术语)。 最后,日志应该显示1个成功和4个失败的转移。 解决的办法是限制客户端每个会话连接一个单一的连接,你会很好(假设其他人没有得到他们的脚在一个微妙的一个传输完成,另一个还没有开始。 )