简介
FTP 协议要用到两个 TCP 连接, 一个是命令连接, 用来在 FTP 客户端与服务器之间传递命令; 另一个是数据连接, 用来上传或下载数据. 通常 21 端口是命令端口, 20 端口是数据端口. 当混入主动 / 被动模式的概念时, 数据端口就有可能不是 20 了. 无论是主动模式还是被动模式, 其要进行文件传输都必须依次建立两个连接, 分别为命令连接与数据连接. 而主动模式与被动模式的差异主要体现在数据连结通道上.
命令连接
当 FTP 客户端需要登 6 到 FTP 服务器上的时候, 服务器与客户端需要进行一系列的身份验证过程, 这个过程就叫做命令连接. 如在客户端向服务器发起连接请 求的时候, 客户端会随即的选择某个 TCP 端口来跟 FTP 服务器的 21 号端口进行连接, 这主要是通过 TCP 三方握手来实现的. 当三方握手完成之后, 客户端与 服务器之间便建立了命令连接通道. 不过这个通道的用途是非常有限的, 其主要用来传输 FTP 的相关指令. 如查看文件列表, 删除文件等等, 而不能够用来在客户 端与服务端进行文件传输. 为此这个通道就被称之为命令通道. 到客户端与服务器建立了连接之后, 可能客户端暂时不需要进行数据传输. 如只是需要查看目录下的文件或则其他相关的动作. 此时之需要命令连接通道就可以完 成了.
数据连接
如果此时客户端需要往 FTP 服务器上上传或者下载文件的话, 就需要在客户端与服务器端再建立一条额外的数据传输连接.
主动模式
主动模式下, FTP 客户端从任意的非特殊的端口 (N> 1023) 连入到 FTP 服务器的命令端口 --21 端口. 然后客户端在 N+1(N+1>= 1024)端口监听, 并且通过 N+1(N+1>= 1024)端口发送命令给 FTP 服务器. 服务器会反过来连接用户本地指定的数据端口, 比如 20 端口.
FTP 服务器命令 (21) 端口接受客户端端口(N> 1023)(客户端初始连接)
FTP 服务器命令 (21) 端口到客户端端口(>1023)(服务器响应客户端命令)
FTP 服务器数据 (20) 端口到客户端端口(>1023)(服务器初始化数据连接到客户端数据端口)
FTP 服务器数据 (20) 端口接受客户端端口(>1023)(客户端发送 ACK 包到服务器的数据端口)
被动模式
在被动方式 FTP 中, 命令连接和数据连接都由客户端发起, 这样就可以解决从服务器到客户端的数据端口的入方向连接被防火墙过滤掉的问题.
在被动模式下, FTP 库户端随机开启 (N>1024) 的端口向服务器的 21 号端口发起连接, 同时会开启 N+1 号端口. 然后向服务器发送 PASV 命令, 通知服务器自己处于被动模式. 服务器收到命令后, 会开放一个大于 1024 的端口 P 进行监听, 然后用 PORT P 命令通知客户端, 自己的数据端口是 P. 客户端收到命令后, 会通过 N+1 号端口连接服务器的端口 P, 然后在两个端口之间进行数据传输.(在 vsftpd.conf 中指定被动端口范围为 4000-4500)
FTP 服务器命令 (20) 接收客户端任何大于 1024 的端口(客户端的初始化连接)
FTP 服务器命令 (21) 到客户端 (>1024) 的端口 (服务器响应到客户端的控制端口的连接)
FTP 服务器数据 (>1024) 接收客户端 (>1024) 的端口(客户端初始化数据连接到服务器指定的任意端口)
FTP 服务器数据 (>1024) 到客户端 (>1024) 的端口(服务器发送 ACK 响应和数据到客户端的数据端口)
不同工作模式的网络设置
主动模式传送数据时是 "服务器" 连接到 "客户端" 的端口; 被动模式传送数据是 "客户端" 连接到 "服务器" 的端口.
在实际项目中碰到的问题是, FTP 的客户端和服务器分别在不同网络, 两个网络之间有至少 4 层的防火墙, 服务器端只开放了 21 端口, 客户端机器没开放任何端口. FTP 客户端连接采用的被动模式, 结果客户端能登录成功, 但是无法 LIST 列表和读取数据. 很明显, 是因为服务器端没开放被动模式下的随机端口导致.
由于被动模式下, 服务器端开放的端口随机, 但是防火墙要不能全部开放, 解决的方案是, 在 ftp 服务器配置被动模式下开放随机端口在 50000-60000 之间(范围在 ftp 服务器软件设置, 可以设置任意 1024 上的端口段), 然后在防火墙设置规则, 开放服务器端 50000-60000 之间的端口端.
主动模式下, 客户端的 FTP 软件设置主动模式开放的端口段, 在客户端的防火墙开放对应的端口段.
来源: http://www.bubuko.com/infodetail-2768566.html