在命令行下连接被动模式FTP服务器,最直接的办法是进入ftp命令交互界面后执行passive命令,或者使用curl工具的–ftp-pasv参数。
需要说明的是,FTP会话包含两条通道:一条用于发送指令,另一条用于传输数据,被动模式(PASV)把数据连接的建立权交给客户端,这样即使客户端处在防火墙后面也能正常工作,本文围绕这一模式,讲清连接步骤、失败原因和不同系统的实操方案。
命令行怎么连接被动模式的ftp服务器
不管用的是Linux、macOS还是Windows,命令行连接被动模式FTP都绕不开两个工具:系统自带的ftp命令,以及跨平台能力更强的curl,下面按使用频率排序,给出完整操作路径。
使用系统内置ftp命令连接
系统内置的ftp客户端虽然界面朴素,但胜在随处可用,以Linux终端为例,操作分四步走。
- 打开终端,输入
ftp 服务器地址,例如ftp 192.168.1.100 - 在
Name提示符后输入用户名,回车 - 在
Password提示符后输入密码,回车(输入时屏幕不会回显,这是正常现象) - 登录成功后,输入
passive开启被动模式
这里有个容易被忽略的细节:很多发行版默认就是被动模式,但为了确保万无一失,登录后最好主动敲一次passive,执行后屏幕上会出现“Passive mode on”之类的反馈,随后再执行ls或get命令,数据连接就会走被动通道。
如果你用的服务器要求主动模式,则输入passive会提示“Passive mode off”,此时数据连接改由服务器主动发起,大多数互联网场景下,被动模式更稳妥,因为主动模式要求客户端开放高端口给服务器连接,这在个人电脑上几乎不可行。
用curl命令一步到位
curl原本是下载工具,但它在各类系统上都能原生支持FTP被动模式,而且不需要进入交互界面。
curl --ftp-pasv -u 用户名:密码 ftp://服务器地址/目录/
--ftp-pasv明确指定使用被动模式-u后面跟用户名和密码,中间用英文冒号分隔- URL末尾的斜杠表示目录,想下载文件就去掉斜杠并把路径写全
额外提一句,curl还支持--ftp-ssl参数,能顺手把FTP升级成FTPS加密连接,这对有安全要求的传输场景很重要,因为普通FTP的用户名和密码都是明文传输的。
ftp被动模式连接失败怎么办
结合近年来在线服务商的安全配置情况,被动模式连接失败相当一部分原因是服务器端配置了过窄的数据端口范围,遇到这种情况,排查思路比生记命令更有价值。
先分清主动与被动模式的区别
主动模式下,服务器使用21端口发指令,用20端口主动连回客户端的高端口,被动模式下,服务器开放一个随机高端口,客户端主动去连那个端口,下表列出两者的本质区别:
| 对比维度 | 主动模式(PORT) | 被动模式(PASV) |
|---|---|---|
| 数据连接方向 | 服务器连客户端 | 客户端连服务器 |
| 客户端防火墙要求 | 必须放行入站数据传输端口 | 只需放行出站连接 |
| 服务端防火墙要求 | 放行21和20端口 | 放行21端口及数据端口范围 |
| 适用场景 | 内网直连,无NAT | 客户端位于NAT或防火墙后 |
从上表能看出,被动模式把连接压力转移到了服务端,所以当你连接失败时,重点检查服务端防火墙的数据端口是否放行。
按顺序排查问题点
我建议你按下面这个顺序逐项验证,能省去不少摸索时间。
- 确认服务器PASV功能已开启:登录服务器后输入
quote PASV,如果返回“Entering Passive Mode”则正常 - 检查服务端数据端口范围:很多FTP服务器软件允许指定被动端口范围,例如5000到6000,如果服务器在NAT后面,还需要把公网IP映射到内网
- 测试端到端连通性:在客户端本机执行
telnet 服务器IP 21,能通说明控制连接正常,至于数据端口,可以找一台没有防火墙的测试机跑curl --ftp-pasv做对照 - 抓包确认模式切换:使用tcpdump或Wireshark抓取21端口通信过程,重点看客户端发出的命令是
PORT还是
PASV,如果发的是PORT,说明模式没切换成功
值得强调的现实情况是:多数云服务商的防火墙默认不放开高端口,所以如果你租用的是云服务器,需要去安全组规则里显式放行被动数据端口,这算是新手最容易踩的坑。
不同系统下连接被动模式FTP的实操路径
命令行的一大特点是跨平台表现不一,尤其是Windows和Unix生态,内置ftp命令的语法存在明显差异,掌握各自的正确姿势,可以减少来回折腾的时间。
linux终端和macOS终端连FTP
两者都使用BSD风格的ftp客户端,行为基本一致,登录后执行passive即可切换,macOS上如果遇到“ftp: command not found”,说明系统没带该工具,可以改用curl。
# linux一键连接并下载文件 ftp -n 服务器IP <<EOF quote USER 用户名 quote PASS 密码 passive get 目标文件 bye EOF
这种写法用here文档把命令一次性灌给ftp进程,适合做成脚本批量执行,注意-n参数用来禁止自动登录,密码才能通过quote PASS使用。
windows cmd连接被动模式的正确方法
Windows自带的ftp.exe比较特殊,它不支持passive子命令,也就是说,在cmd窗口里直接敲ftp进入的命令行,只能走主动模式,这在现代网络环境里基本连不上。
行业共识认为,Windows用户连接被动模式FTP有以下两个更实用的方案。
- 使用Windows 10及以上系统自带的curl命令,在cmd里执行
curl --ftp-pasv -u 用户名:密码 ftp://服务器/文件,效果与Linux一致 - 使用PowerShell的WebClient对象,执行
$webclient = New-Object System.Net.WebClient,再调用$webclient.DownloadFile()方法,不过WebClient默认行为不完全等价于被动模式,用curl更直接
如果你坚持用ftp.exe,还有一条路:通过quote PASV手动发送被动命令,部分FTP服务器会响应这个指令,但数据连接的构建方式仍受Windows实现限制,建议不要在生产环境依赖这一写法。
用脚本批量处理被动模式FTP传输
当文件数量多了以后,手动敲命令就不现实了,把被动模式写进脚本,可以让机器替我们完成重复劳动。
批量下载目录文件
以lftp工具为例,它内置丰富的模式控制参数,先安装lftp,然后执行:
lftp -e "set ftp:passive-mode yes; mirror -c /remote /local; bye" -u 用户名,密码 服务器IP
set ftp:passive-mode yes显式开启被动模式mirror -c开启断点续传,中断后重跑能跳过已有文件- 方括号内的两个路径先是远端目录,后是本地目录
lftp用的逗号分隔用户名密码,跟curl的冒号不同,写脚本时容易混淆。
把验证信息写进安全的配置
直接在命令行明文写密码有暴露风险,一个常见做法是把密码写入.netrc文件,并设置600权限,curl读取该文件后可以省略-u参数。
chmod 600 ~/.netrc格式 machine 服务器IP login 用户名 password 密码
这样在脚本里只需要写curl --ftp-pasv ftp://服务器IP/文件即可,密码不会出现在命令行历史记录中。
命令行连接ftp被动模式常见问题
为什么我的FTP客户端已经启用了被动模式,但还是卡在列目录这一步?
多数情况是数据端口未放行,被动模式下,服务器会告知客户端一个IP和端口,客户端去连接这个端口时被防火墙拦截,导致连接挂起,解决方向是放行服务器上的被动端口范围,并确认服务器返回的IP是客户端能访问到的公网IP,而不是内网地址。
如何判断当前连接是否真的处于被动模式?
在ftp交互界面输入status命令,会输出当前模式设置,另一个可靠方法是抓包,数据包中出现PASV命令字符串(客户端发出)和227 Entering Passive Mode响应(服务端返回),即可确认为被动模式,如果看到的是PORT命令,说明仍是主动模式。
用curl连接被动模式时怎么处理TLS证书问题?
FTP over TLS(FTPS)需要验证服务器证书,curl默认验证CA证书,如果服务器用的是自签名证书,可以加-k参数跳过验证,但此做法降低安全性,仅建议在调试阶段临时使用,生产环境应通过--cacert指定自定义CA文件。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/607579.html




