1 背景
某客户现场,每天都会批量生成大量 CSV 文件存放到 FTP 系统,这些 CSV 文件需要导入到大数据平台 HIVE 数仓中做后续离线分析,且 HIVE 数仓中的离线分析作业目前是使用 JENKINS 来调度的。
由于这些 CSV 文件是每天都会生成,且文件数比较多数据量也比较大,初步计划使用 DATAX 来导入 FTP 上的 CSV 文件。
但在调度系统 JENKINS 中,如何检测 ftp 上的 csv 文件是否 ready,并及时触发 DATAX 导入作业,成为了一个问题。
为探索和验证 JENKINS 中 FTP 文件的检测和触发机制,笔者搭建了 FTP 服务器。
在此通过系列文章,跟大家分享一个开源的 FTP 服务器 vsftpd, 介绍下其安装配置和使用,然后介绍下 FTP 的 ACTIVE 与 PASSIVE 模式,最后介绍下 CurlFtpFS.
本片文章是系列文章第二篇,介绍下FTP 的 ACTIVE 与 PASSIVE 模式。
2 FTP 的工作模式概述
- FTP 协议不同于其他协议的一大特点是,其底层的 CLIENT 和 SERVER 之间有两个通信管道,即 command channel 和 data channel;
- command channel 用来在客户端和服务器之间,传输命令和对命令的响应(客户端会发送命令给服务端,服务端也会发送命令给客户端);
- data channel 用来进客户端和服务器之间,进行实际的文件数据的传输;
- 客户端的 command channel 和 data channel,使用的端口都是随机的;
- 默认情况下,服务端的 command channel 使用端口 21;
- 默认情况下,在 active 模式下,服务端的 data channel 使用端口 20;
- 在 passive 模式下,服务端的 data channel 使用一个随机的端口(其 range 可配置);
- 两个通信通道,和端口使用情况,简化示意图如下:
3 FTP 的 ACTIVE 工作模式详解
- 所谓 ACTIVE 工作模式,是指 FTP SERVER 端主动发起并建立了到客户端的 TCP 连接,此时 FTP SERVER 端是 TCP 连接的发起方,而 FTP CLIENT 是 TCP 连接的响应方;
- FTP ACTIVE 模式的产生早于 FTP passive 模式,是早期网络安全攻击还不那么猖獗的早期时代的产物;
- FTP ACTIVE 模式下,文件上传/下载底层的工作机制如下:
- 客户端使用一个随机端口,发起并建立到服务端 21 端口的 TCP连接;
- 建立 TCP 连接后,客户端会通过一系列命令跟服务端交互以登录服务端(具体的命令,包括 AUTH,USER,PASS,OPTS等);
- 客户端成功登录服务端后,在需要建立 data channel 数据通道时(即在进行文件上传/下载操作时),会首先通过 PORT 命令告知服务端,接下来建立 data channel 连接时,客户端可以使用的端口号;
- 服务端在获知客户端可以使用的 data channel 端口后,会主动通过自己的 20 端口,发起并建立到客户端上述 data channel 端口的 TCP 连接,此后该 session 下的文件上传和下载,就使用该 data channel 底层的 tcp 连接来进行;
- 后续再有文件上传/下载操作时,同样需要重复上述步骤建立 data channel,这些不同时刻建立的 data channel,其底层使用的客户端的端口号,并不一定相同;
- ACTIVE 模式下,客户端和服务器端的交互机制,示意图如下:
ACTIVE 模式下,客户端和服务器端在进行文件上传/下载操作时,其底层的 tcp 连接,在服务端可以使用 netstat 命令查看:
- ACTIVE 模式下,客户端 FileZilla 的日志如下(进行了文件上传和下载操作):
Status: Connecting to xx:21... Status: Connection established, waiting for welcome message... Response: 220 (vsFTPd 3.0.2) Command: AUTH TLS Response: 530 Please login with USER and PASS. Command: AUTH SSL Response: 530 Please login with USER and PASS. Status: Insecure server, it does not support FTP over TLS. Command: USER awsftpuser Response: 331 Please specify the password. Command: PASS ********** Response: 230 Login successful. Command: OPTS UTF8 ON Response: 200 Always in UTF8 mode. Status: Logged in Status: Retrieving directory listing... Command: PWD Response: 257 "/" Status: Directory listing of "/" successful Status: Connecting to xxx:21... Status: Connection established, waiting for welcome message... Response: 220 (vsFTPd 3.0.2) Command: AUTH TLS Response: 530 Please login with USER and PASS. Command: AUTH SSL Response: 530 Please login with USER and PASS. Status: Insecure server, it does not support FTP over TLS. Command: USER awsftpuser Response: 331 Please specify the password. Command: PASS ********** Response: 230 Login successful. Command: OPTS UTF8 ON Response: 200 Always in UTF8 mode. Status: Logged in Status: Starting upload of xxx Command: CWD / Response: 250 Directory successfully changed. Command: PWD Response: 257 "/" Command: TYPE I Response: 200 Switching to Binary mode. Command: PORT 10,23,10,64,196,12 Response: 200 PORT command successful. Consider using PASV. Command: STOR test1.ok Response: 150 Ok to send data. Response: 226 Transfer complete. Status: File transfer successful, transferred 9 bytes in 1 second Status: Retrieving directory listing of "/"... Command: PORT 10,23,10,64,196,15 Response: 200 PORT command successful. Consider using PASV. Command: LIST Response: 150 Here comes the directory listing. Response: 226 Directory send OK. Status: Directory listing of "/" successful Status: Disconnected from server Status: Connecting to xxx:21... Status: Connection established, waiting for welcome message... Response: 220 (vsFTPd 3.0.2) Command: AUTH TLS Response: 530 Please login with USER and PASS. Command: AUTH SSL Response: 530 Please login with USER and PASS. Status: Insecure server, it does not support FTP over TLS. Command: USER awsftpuser Response: 331 Please specify the password. Command: PASS ********** Response: 230 Login successful. Command: OPTS UTF8 ON Response: 200 Always in UTF8 mode. Status: Logged in Status: Starting download of /a.ok Command: CWD / Response: 250 Directory successfully changed. Command: TYPE I Response: 200 Switching to Binary mode. Command: PORT 10,23,10,64,196,40 Response: 200 PORT command successful. Consider using PASV. Command: RETR a.ok Response: 150 Opening BINARY mode data connection for a.ok (4 bytes). Response: 226 Transfer complete. Status: File transfer successful, transferred 4 bytes in 1 second
4 FTP 的 PASSIVE 工作模式详解
- 所谓 PASSIVE 工作模式,是指 FTP SERVER 端被动地建立了到客户端的 TCP 连接,此时 FTP CLIENT 端是 TCP 连接的发起方,而 FTP SERVER 是 TCP 连接的响应方;
- FTP PASSIVE 模式的产生晚于 FTP active 模式,适用于更复杂的网络环境,其安全性更高;
- FTP PASSIVE 模式下,文件上传/下载底层的工作机制如下:
- 客户端使用一个随机端口,发起并建立到服务端 21 端口的 TCP连接;(同 ACTIVE 模式)
- 建立 TCP 连接后,客户端会通过一系列命令跟服务端交互以登录服务端(具体的命令,包括 AUTH,USER,PASS,OPTS等);(同 ACTIVE 模式)
- 客户端成功登录服务端后,在需要建立 data channel 数据通道时(即在进行文件上传/下载操作时),会首先发送 PASV 命令到服务端,以请求服务端告知自己,接下来建立 data channel 连接时,服务端可以使用的端口号;(不同于 ACTIVE 模式)
- 客户端在获知服务端可以使用的 data channel 端口后,会主动通过自己的一个随机端口,发起并建立到服务端上述 data channel 端口的 TCP 连接,此后该 session 下的文件上传和下载,就使用该 data channel 底层的 tcp 连接来进行;(不同于 ACTIVE 模式)
- 后续再有文件上传/下载操作时,同样需要重复上述步骤建立 data channel,这些不同时刻建立的 data channel,其底层使用的服务端的端口号,并不一定相同;
- PASSIVE 模式下,服务器端 data channel 底层的端口号,其范围是可以配置的,配置方式如下(vsftpd 的配置文件是/etc/vsftpd/vsftpd.conf):
- PASSIVE 模式下,客户端和服务器端的交互机制,示意图如下:
- PASSIVE 模式下,客户端和服务器端在进行文件上传/下载操作时,其底层的 tcp 连接,在服务端可以使用 netstat 命令查看:
- PASSIVE 模式下,客户端 FileZilla 的日志如下(进行了文件上传和下载操作):
Status: Disconnected from server Status: Connecting to xxx:21... Status: Connection established, waiting for welcome message... Response: 220 (vsFTPd 3.0.2) Command: AUTH TLS Response: 530 Please login with USER and PASS. Command: AUTH SSL Response: 530 Please login with USER and PASS. Status: Insecure server, it does not support FTP over TLS. Command: USER awsftpuser Response: 331 Please specify the password. Command: PASS ********** Response: 230 Login successful. Command: OPTS UTF8 ON Response: 200 Always in UTF8 mode. Status: Logged in Status: Retrieving directory listing... Command: PWD Response: 257 "/" Status: Directory listing of "/" successful Status: Connecting to xxx:21... Status: Connection established, waiting for welcome message... Response: 220 (vsFTPd 3.0.2) Command: AUTH TLS Response: 530 Please login with USER and PASS. Command: AUTH SSL Response: 530 Please login with USER and PASS. Status: Insecure server, it does not support FTP over TLS. Command: USER awsftpuser Response: 331 Please specify the password. Command: PASS ********** Response: 230 Login successful. Command: OPTS UTF8 ON Response: 200 Always in UTF8 mode. Status: Logged in Status: Starting upload of xxx Command: CWD / Response: 250 Directory successfully changed. Command: PWD Response: 257 "/" Command: TYPE I Response: 200 Switching to Binary mode. Command: PASV Response: 227 Entering Passive Mode (3,22,42,20,4,13). Command: STOR 数据治理与安全-0828.docx Response: 150 Ok to send data. Status: Connecting to xxx:21... Status: Connection established, waiting for welcome message... Response: 220 (vsFTPd 3.0.2) Command: AUTH TLS Response: 530 Please login with USER and PASS. Command: AUTH SSL Response: 530 Please login with USER and PASS. Status: Insecure server, it does not support FTP over TLS. Command: USER awsftpuser Response: 331 Please specify the password. Command: PASS ********** Response: 230 Login successful. Command: OPTS UTF8 ON Response: 200 Always in UTF8 mode. Status: Logged in Status: Starting download of /kafka summit.docx Command: CWD / Response: 250 Directory successfully changed. Response: 226 Transfer complete. Status: File transfer successful, transferred 27,690,505 bytes in 25 seconds Command: TYPE I Response: 200 Switching to Binary mode. Command: PASV Response: 227 Entering Passive Mode (3,22,42,20,4,9). Command: RETR kafka summit.docx Response: 150 Opening BINARY mode data connection for kafka summit.docx (62879085 bytes).
5 Active 模式和 Passive 模式的主要区别
从上述对比可以看出,Active 模式 和 Passive 模式的区别,主要在于 data channel TCP 连接的建立方式:
- Active 模式下,是服务端主动发起的到客户端的 data channel tcp 连接;
- Passive 模式下,是客户端主动发起的到服务端的 data channel tcp 连接,服务端是被动的;
- Active 模式下,客户端会通过 PORT 命令告知服务端自己 data channel 底层的端口号;
- Active 模式下,服务端 data channel 底层的端口号默认是20;
- Active 模式下,服务端会主动通过自己的端口20,发起到客户端特定端口的 TCP 链接(端口号是客户端通过 PORT 命令告知的);
- Passive 模式下,客户端会通过 PASV 命令询问服务端其 data channel 底层的端口号;
- Passive 模式下,服务端收到客户端的 PASV 询问命令后,会回复客户端一个可用的 data channel 端口号;(端口 range 一般通过 pasv_min_port/pasv_max_port 指定,端口ip一般通过 pasv_address指定);
- Passive 模式下,客户端会主动通过自己的一个随机端口,发起到服务端特定端口的 TCP 链接(端口号是客户端通过 PASV 命令询问服务端获取的);
6 Active 模式和 Passive 模式,哪种模式更适合自己?
- 在不涉及网络地址转换(NAT)和防火墙 (firewall) 的情况下,Active 模式和 Passive 模式,都是可以工作的;
- 但出于信息安全的考虑,大部分站点的环境都部署了 NAT 或防火墙,此时网络管理员一般会配置 inbound rules 和 outbound rules, 限制外网特定IP/端口到内网特定IP/端口的访问,和内网特定IP/端口到外网特定IP/端口的访问;且在配置具体网络策略时,一般会限制外部对内部随机端口的 inbound 访问,只允许外部对内部特定端口的 inbound 访问;但倾向于允许内部随机端口到外部的 outbound 访问;
- FTP 客户端和 FTP 服务端可能都有自己的防火墙,且其网络安全策略的配置是独立开来,由不同组织不同人员配置和管控的,互不影响;
- 在 FTP Active 模式下,客户端会通过 PORT 命令告知服务端自己的 DATA CHANNEL 端口,且该端口是一个随机端口,随后服务端会通过自身的 20 端口主动发起到客户端该随机端口的 TCP 连接:此时服务端一般会配置自己的防火墙,开放自己20端口到外网的 outbound 连接,所以在服务端防火墙这一侧,一般是没有问题的;但客户端一般不会配置自己的防火墙,允许外网对内网所有随机端口的 inbound 连接,所以此时 TCP DATA CHANNEL 连接的建立就会失败;
- 而在 FTP PASSIVE 模式下,客户端会通过 PASV 命令询问服务端其DATA CHANNEL 端口,随后服务端会根据配置的端口范围(端口 range 一般通过 pasv_min_port/pasv_max_port 指定,端口ip一般通过 pasv_address指定)返回一个可用的端口给客户端,客户端在获取到服务端该端口后,会主动通过一个随机端口发起到服务端该端口的 TCP 连接:此时客户端防火墙一般会允许内部随机端口到外网的 outbound 连接,所以客户端防火墙这一侧一般是没有问题的;而在服务端,由于服务端 DATA CHANNEL 端口范围是自己可以控制的,一般也会配置服务端防火墙,允许外部随机端口到内部特定端口的 TCP 连接,所以此时 TCP DATA CHANNEL 连接的建立就不会有问题;
- 综合来看,在涉及内网外网,公网私网,和防火墙等复杂的网络环境的情况下,推荐使用 passive 模式的 ftp, 且此时 ftp 服务端应该根据实际情况,配置合适的 DATA CHANNEL 端口(端口 range 一般通过 pasv_min_port/pasv_max_port 指定,端口ip一般通过 pasv_address指定),并由网络管理员配置防火墙策略,允许外部对内部这些特定端口的 TCP 连接;
- 话说回来,出于用户体验的考量,FTP服务端也应该主动调整自身防火墙配置,不能要求所有客户端都配合你来调整其防火墙配置,所以推荐使用 passive 模式,而不是 active 模式;
7 Passive 模式下,如何合理配置 Passive DATA CHANNEL 端口的范围?
如上文所说,在复杂的网络环境下,推荐配置使用 passive 模式的 ftp,此时 ftp 服务端需要配置 Passive DATA CHANNEL 端口的范围,端口范围一般通过 pasv_min_port/pasv_max_port 指定,端口ip一般通过 pasv_address指定。
配置完Passive DATA CHANNEL 端口的范围后,还需要网络管理员配置防火墙策略,允许外部对内部这些特定端口的 TCP 连接,但出于于网络安全的考量,我们又不想该端口范围很大,那么如何选用一个合理的Passive DATA CHANNEL 端口范围呢?
- 合理的端口范围的大小,取决于 FTP 站点需要支持的并发连接数。
- 需要注意,这里的并发连接数,指的是实际的并发的文件上传或下载的任务数,每个并发任务底层都有一个并发连接,都需要占用一个端口;
- 并发连接数,并不一定是并发用户数,因为有的客户端可能会建立多个并发连接,以并发上传/下载多个文件,比如同时并发下载/上传1-个文件,就需要10个端口;
- 可以基于对并发用户数和并发任务数的规划,设置一个初始的 Passive DATA CHANNEL 端口的范围,然后再根据实际的使用和监控情况,进一步调整。