You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP调用FTPS出现ftp_nlist()错误,需添加何种防火墙规则?

问题描述

在使用PHP进行FTPS文件传输时遇到报错:

ftp_nlist(): php_connect_nonb() failed: Operation now in progress (115)

演示代码如下:

<?php 
error_reporting(E_ERROR | E_WARNING | E_PARSE);
ini_set('display_errors', 1);

$response = '';
$ftp = ftp_ssl_connect('ftps.site.com', 2222, 180);
if (!$ftp) {
   echo 'Connect failed' . "\n"; 
   return -1; 
}
if (!ftp_login($ftp, 'user', 'pass')) {
   echo 'Login failed' . "\n"; 
   return -1; 
}
ftp_set_option($ftp, FTP_USEPASVADDRESS, false); // added later
ftp_pasv($ftp, true);          
echo 'printing ftp_nlist response: ' . '<br>'; 
print_r(ftp_nlist($ftp, "/keydealer/"));
ftp_close($ftp); 
echo 'done<br>'; 
return 0; 

原本以为设置ftp_set_option($ftp, FTP_USEPASVADDRESS, false);能解决问题,但没有效果。禁用防火墙后功能恢复正常,请问需要添加什么防火墙规则来解决该问题?


解决方案

这个报错的核心原因是被动模式(PASV)下的FTPS数据连接被防火墙拦截。FTPS使用被动模式时,控制连接(代码里的2222端口)建立后,服务器会开放一段数据端口,客户端需要主动连接这些端口传输目录列表、文件内容等数据,防火墙默认会拦截这类非标准端口的请求。

你需要根据防火墙类型添加对应规则:

1. Linux系统(iptables)

先确认FTP服务器配置的被动模式数据端口范围(比如多数服务器可设置为40000-50000),再执行以下命令:

# 放行FTPS控制端口(对应代码中的2222)
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 2222 -j ACCEPT

# 放行被动模式数据端口范围(示例为40000-50000,需和FTP服务器配置一致)
iptables -A INPUT -p tcp --dport 40000:50000 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 40000:50000 -j ACCEPT

# 保存规则(不同系统命令可能有差异)
service iptables save

2. Windows系统防火墙

  • 打开Windows Defender防火墙高级设置
  • 新建入站规则:
    1. 规则类型选「端口」,点击下一步
    2. 选择「TCP」,输入特定本地端口:2222,40000-50000(替换为你的控制端口和数据端口范围),点击下一步
    3. 选择「允许连接」,点击下一步
    4. 勾选适用的网络类型,点击下一步
    5. 命名规则(如「FTPS端口放行」),完成设置
  • 重复上述步骤新建出站规则,确保客户端能发起对这些端口的连接

额外注意事项

  • 必须给FTP服务器配置固定的被动模式端口范围(不要用随机端口),否则防火墙无法精准放行。比如vsftpd可在配置文件中设置pasv_min_port=40000和pasv_max_port=50000
  • 代码中已开启被动模式ftp_pasv($ftp, true);,需确保FTP服务器端也启用了被动模式支持

内容的提问来源于stack exchange,提问作者Scott C Wilson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 12:52:24