基础¶
FTP ( File Transfer Protocol) 是一种常见的传输协议,它处于 OSI 模型的应用层,构建在 TCP 协议上。
为了正常传输文件,FTP 要求建立两个连接:
- 控制连接 ,用于传输控制流。
- 数据连接 ,用于传输数据流。
此外,FTP 支持两种模式:主动模式和被动模式。
本文将讨论在两种模式下,FTP 两个连接的建立过程以及搭建 FTP 时 client / server 分别在 NAT 网关后的处理。
主动模式¶
“主动模式”下,由 server 主动向 client 建立 数据连接 ,连接建立过程如下:
- ( C ) client 端使用一个随机端口
N
(N > 1023
)连接 server 端的 命令端口 (通常是21
端口)并建立 控制连接 ; - ( C ) 连接建立后,client 开始监听一个新的端口
P
( 数据端口 ,通常是P = N + 1
),并通过 控制连接 ,发送 FTP 命令PORT P
告诉 server 端,“我正在监听P
端口”; - ( S ) server 端(通常使用
20
端口)主动连接到 client 的 数据端口 ,并建立 数据连接 。
至此,两条连接已经建立,可以进行数据传输。
这种模式下,自主搭建一个 ftp 服务器,需要在服务端防火墙添加以下 下行规则 (不考虑 IP 限制):
- 允许来自任何 IP 连接 server 端的
21
端口(用于和 client 端建立 控制连接 ) - 允许来自任何 IP 连接 server 端的
20
端口(用于和 client 端建立 数据连接 )
被动模式¶
“被动模式”下, 数据连接 是由 client 主动发起,而 server 是被动连接的。连接建立过程如下:
- ( C ) client 端使用一个随机端口
N
(N > 1023
)连接 server 端的 命令端口 (通常是21
端口)并建立 控制连接 ; - ( C ) client 端通过 控制连接 发送命令
PASV
,告诉服务端,“我们将通过 被动模式 建立 数据连接 ”; - ( S ) server 端在收到
PASV
命令后,根据配置的 被动模式端口范围 ,在本地监听一个随机端口P
,并将该端口P
响应给PASV
命令; - ( C ) client 端使用随机端口
N+1
建立到服务端P
端口的 数据连接 。
至此,两条连接已经建立,可以进行数据传输。
这种模式下,需要在 server 端防火墙添加以下 下行规则 (不考虑 IP 限制):
- 允许来自任何 IP 连接 server 端的
21
端口(用于和 client 端建立 控制连接 ) - 允许来自任何 IP 连接 server 端的 被动模式端口范围 (用于和 client 端建立 数据连接 )
NAT¶
从以上可以看出,“主动模式”和“被动模式”的主要区别在于 数据连接 的 端口监听 和 端口范围 。
“主动模式”下,要求 client 端监听一个 数据端口 。
而“被动模式”要求在服务端配置一段 数据端口 的范围,并保证对应下行是畅通的。
如果 server 端和 client 端都是直接暴露在公网中,使用“主动模式”配置会更简单些。
然而现实往往不是这样的。
server 端可能是机房内局域网的主机,client 更有可能在用户的局域网内,
两者都有可能是共享上网的(事实上这是最常见的场景)。
对于主机(不论是 client / server)处在局域网时,需要使用 NAT 来实现共享上网。
而对于 NAT 网关后的 FTP client / server,NAT 在两种模式下的配置又不同。下面我们来一一分析下。
主动模式¶
在“主动模式”下,在由 client 端发起的 控制连接 中,client 将本地监听端口 P
,
并通过 PORT P
命令告知 server,再由 server 主动向该端口发起连接。
因此,这种情况主要要解决如何从 server 端连接 client 端的 数据端口 :
-
- client 处于广域网
-
由于 client 直接在公网监听了端口
P
,client 告知 server 的是 公网 IP 和 端口 ,
server 可以直接通过该二元组建立连接。
-
- client 处于局域网
-
此时,对于 server 端而言,只知道 client 的公网 IP 和 client 主机内监听的端口 P,
所以必须在 client 的网关处配置端口转发(DNAT),让网关在收到
(公网 IP , 端口) 时转换为 (私网 IP ,端口) ,并经过路由转发到达 client 端。
被动模式¶
在“被动模式”下,在由 server 端发起的 控制连接 中,server 将监听指定端口范围中的随机端口 P
并响应给 PASV
命令,再由 client 主动向该端口发起连接。
因此,这种情况主要要解决 client 端如何连接 server 端的 数据端口 :
-
- server 处于广域网
-
由于 server 直接在公网监听了端口
P
, client 可以像连接 命令端口 那样直接连接 数据端口 。
-
- server 处于局域网
-
同样的,此时需要在 server 端配置端口映射来保证“数据连接”的建立。
而由于被动模式下 server 通常会随机监听指定端口范围中的某端口,server 的网关需要配置一段端口范围的 DNAT。