被动FTP连接无法通过PHP工作



我的应用程序连接到通过VPN连接到服务器的FTP客户端。到目前为止,所有客户端都支持活动PHP,并且我使用的库默认使用活动FTP,因此没有问题。但是现在我们已经安装了一些无法在主动PHP上正常工作的新客户端,因此我发现从服务器(通过FTP cli和FileZilla over RDP)可以通过被动连接连接到所有客户端并与之通信。

但是,当尝试在PHP中建立被动连接时,所有FTP命令(例如nlist)都会超时。我遇到了这篇博客文章,它为特定的被动FTP问题提供了一个补丁(现在在常规PHP版本中可用),所以我尝试像这样测试它:

$conn = ftp_connect($address);
$login = ftp_login($conn, 'username', 'password');
ftp_set_option($conn, USEPASVADDRESS, false);
ftp_pasv($conn, true);
$contents = ftp_nlist($conn, '.');
var_dump($contents);
ftp_close($conn);

ftp_pasv返回 true,因此它正在切换到被动模式,但ftp_nlist超时,而主动模式和兼容客户端则不会超时。

PHP的FTP实现和FTP cli应用程序有什么区别?

我想我已经弄清楚了我的情况中的确切问题。我不确定这是否对其他人有帮助,但如果您遇到类似的问题,这可能是一个可以调查的想法。

激活被动模式时,服务器会告诉您要连接到的 IP 和端口以进行数据传输。使用ftpCLI 时,仅当您发送数据命令(如请求文件夹内容)时,才会发送实际的PASV命令。在这些情况下,CLI 发送PASV命令,接收 IP/端口,连接到它,然后通过该命令发送原始命令 (LIST)。

PHP似乎以不同的方式执行此操作:一旦您在我们的代码中切换到被动连接,它就会发送PASV命令并立即从服务器接收 IP/端口 - 但 PHP 尚未连接到它。当我要求目录列表时,首先激活 ASCII 模式,然后它才会连接到以前收到的 IP/端口以发送LIST命令。

因此,我怀疑我连接的FTP服务器有故障。我的想法是,一旦它收到PASV命令,它就会等到有人真正连接到该被动连接,然后才开始接受任何其他命令。事实上,我设法验证了这一点。当 PHP 脚本仍在等待响应时,我手动建立了与收到的被动端口的 TCP 连接,之后我的 PHP 代码恢复运行并向我显示结果。

不幸的是,这意味着我根本无法在这些服务器上使用被动FTP,并且无法更新/切换到不同的服务器实现。Active FTP也几乎是不可能的,因为我的应用程序在Docker中运行。

最新更新