一篇文章彻底掌握 FTP 服务器的 ACTIVE 与 PASSIVE 工作模式

article/2025/10/26 5:58:00

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 可配置);

  • 两个通信通道,和端口使用情况,简化示意图如下:b11d08ccb6d27a06a9fa5789c84a20f3.png

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 模式下,客户端和服务器端的交互机制,示意图如下:

3452953c7fac640caa0e4ba7469f44f7.png
ftp-active-mode-communication
  • ACTIVE 模式下,客户端和服务器端在进行文件上传/下载操作时,其底层的 tcp 连接,在服务端可以使用 netstat 命令查看:852fea828e06811a70aa048f144c4076.png

  • 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):c90fe9e40133e3a322a405547051d8e6.png

  • PASSIVE 模式下,客户端和服务器端的交互机制,示意图如下:06e0534917b731385f79fa0d3d7855fb.png

  • PASSIVE 模式下,客户端和服务器端在进行文件上传/下载操作时,其底层的 tcp 连接,在服务端可以使用 netstat 命令查看:4b25d8810dfa48dfc9499ef48277f3af.png

  • 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 模式;d32779fbbbe79ebc3e4f73357cce438c.png

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 端口的范围,然后再根据实际的使用和监控情况,进一步调整。

!关注不迷路~ 各种福利、资源定期分享!欢迎小伙伴们关注公众号!

!欢迎小伙伴们添加明哥微信,备注“加群交流”,拉你加入ABC技术交流群!

IT明哥

http://chatgpt.dhexx.cn/article/WiWILDbD.shtml

相关文章

passive 的事件监听器

很久以前,addEventListener() 的参数约定是这样的: addEventListener(type, listener, useCapture) 后来,最后一个参数,也就是控制监听器是在捕获阶段执行还是在冒泡阶段执行的 useCapture 参数,变成了可选参数&…

强化学习之Passive learning求解 (1)

在MDP系列博客中,我们以一个Agent在4*3网格中寻找终点最优的路径策略为例,论述了MDP问题的原理和求解。有了MDP讲解作为基础之后,我们就可以正式的切入到“强化学习”的学习中来了。强化学习的目的是通过观测到的reward来为当前环境学习一个&…

【重要!!】passive优化页面性能

在js中给dom元素添加监听事件: let dom1document.getElementById("box1"); function box(that){console.log(that); } dom1.addEventListener("click",function(){box(1)});一般都是这样,但是还是有第三个参数,Boolean类…

Passive Event Listener

起源 最近打开项目随便点点,控制台就开始报警: Added non-passive event listener to a scroll-blocking ‘mousewheel’ event. Consider marking event handler as ‘passive’ to make the page more responsive 可以看到警告信息是element-ui和echa…

passive的作用和原理

passived到底有什么用? passived主要用于优化浏览器页面滚动的性能,让页面滚动更顺滑~~BetterScroll:可能是目前最好用的移动端滚动插件 passived产生的历史时间线 addEventListener():大家都是认识的,为dom添加触发…

Java并发编程—CompletableFuture的介绍和使用

在博主上一篇博客介绍中,Java并发编程—java异步Future的迭代过程_小魏快起床的博客-CSDN博客,这里面给大家分析了Future的使用过程和一些存在的问题,那么针对里面出现的阻塞问题,博主将在这一篇文章给大家介绍清楚 &#x1f34f…

Java8 CompletableFuture runAsync等使用学习总结 submit() execute()等

一般的 Executors 的 execute以及submit 并发包下 Executors 创建的线程存在 一个 execute(),以及三个 submit() 不同的是使用 execute() 执行的任务是没有返回值的,使用 submit() 则是存在返回值的,这与接下里要说的 CompletableFuture.run…

实现异步编程,这个工具类你得掌握!

前言 最近看公司代码,多线程编程用的比较多,其中有对CompletableFuture的使用,所以想写篇文章总结下 在日常的Java8项目开发中,CompletableFuture是很强大的并行开发工具,其语法贴近java8的语法风格,与st…

Java异步编程之CompletableFuture

异步任务 Future获取异步任务结果 利用 Java 并发包提供的 Future 可以很容易获得异步任务的执行结果,无论异步任务是通过线程池 ThreadPoolExecutor 执行的,还是通过手工创建子线程来执行的。利用多线程可以快速将一些串行的任务并行化,从而…

JUC异步编程

什么是JUC JUC的意思是java并发编程工具包,是java.util.concurrent包的简称。目的就是为了更好的支持高并发任务,让开发者利用这个包进行的多线程开发时,可以有效的减少竞争条件和死锁线程。 异步编程 模拟用户下单操作。。。 1、根据地址…

线程、多线程的使用、线程池、异步(CompletableFuture)-48

一:线程 1.初始化线程的四种方式 1)、继承 Thread public class ThreadTest {public static void main(String[] args) {System.out.println("main...start...");Thread01 thread new Thread01();//启动线程thread.start();System.out.pri…

CompletableFuture 执行异步任务

CompletableFuture 执行异步任务 参考: (10条消息) Java 8 的异步编程利器 CompletableFuture 真香!_不才陈某的博客-CSDN博客 提供几十种方法,帮助异步任务执行调用; 主要包括: 创建异步任务任务异步回调多个任务…

CompletableFuture实现异步编排全面分析和总结

一、🌈CompletableFuture简介 CompletableFuture结合了Future的优点,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提…

【Java8新特性--->异步处理】CompletableFuture

一、引入 假设一个商品详情页需要以下操作: 查询展示商品的基本信息耗时:0.5s查询展示商品的销售信息耗时:0.7s查询展示商品的图片信息耗时:1s查询展示商品销售属性耗时:0.3s查询展示商品规格属性耗时:1.…

CompletableFuture API

目录 1. 为什么要用CompletableFuture1.1 API 2. CompletableFuture Demo1. 创建CompletableFuture2. 定义CompletableFuture完成时和异常时需要回调的实例3. CompletableFuture的优点 3. demo:多个CompletableFuture串行执行4. demo:多个CompletableFut…

CompletableFuture实战与分析

Future对于结果的获取不够好,只能通过阻塞或者轮询的方式得到任务的结果。在Java8中Doug Lea大师提供了一个CompletableFuture工具类,可以更优雅的对异步并行操作进行编排。 Future VS CompletableFuture CompletableFuture支持手动完成任务&#xff0…

Java8 CompletableFuture异步非阻塞做法

创建异步任务 Future.submit supplyAsync / runAsync 异步回调 thenApply / thenApplyAsync thenAccept / thenRun exceptionally whenComplete handle 组合处理 thenCombine / thenAcceptBoth / runAfterBoth applyToEither / acceptEither / runAfterEither thenCom…

2022.2.5 第十三次周报

文章目录 前言一、论文阅读《ROCKET: Exceptionally fast and accurate time series classification using random convolutional kernels》Abstract摘要Introduction介绍Method方法Kernels内核Transform转换Classifier分类器Complexity Analysis复杂性分析 Experiments实验Con…

并发编程(十五)-CompletableFuture中常用方法的使用与分析

文章目录 一、CompletableFuture API介绍1. 描述2. CompletionStage3. CompletableFuture 4个核心静态方法(1)runAsync(Runnable runnable)(2)runAsync(Runnable runnable, Executor executor)(3)supplyAsy…

Java 编程问题:十一、并发-深入探索

原文:Java Coding Problems 协议:CC BY-NC-SA 4.0 贡献者:飞龙 本文来自【ApacheCN Java 译文集】,自豪地采用谷歌翻译。 本章包括涉及 Java 并发的 13 个问题,涉及 Fork/Join 框架、CompletableFuture、ReentrantLock…