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

被动FTP连接无法通过PHP工作,php,ftp,Php,Ftp,我的应用程序连接到通过VPN连接到服务器的FTP客户端。到目前为止,所有客户端都支持活动PHP,我使用的库默认使用活动FTP,因此没有问题。然而,现在我们安装了一些新的客户端,它们不能在活动PHP上正常工作,因此我发现通过FTP cli和FileZilla over RDP从服务器上可以通过被动连接连接到所有客户端并与之对话 但是,当尝试在PHP中建立被动连接时,所有FTP命令(如nlist)都会超时。我遇到过,它为一个特定的被动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将超时,对于主动模式和兼容客户端,它不会超时


PHPs FTP实现和FTP cli应用程序之间有什么不同?

我想我已经弄清楚了我的问题所在。我不确定这是否对其他人有帮助,但如果你有类似的问题,这可能是一个值得研究的想法

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

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

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


不幸的是,这意味着我不能在这些服务器上使用被动FTP,更新/切换到其他服务器实现是不可能的。由于我的应用程序是在Docker中运行的,所以活动FTP也几乎是不可能的。

我想我已经弄清楚了我的问题所在。我不确定这是否对其他人有帮助,但如果你有类似的问题,这可能是一个值得研究的想法

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

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

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


不幸的是,这意味着我不能在这些服务器上使用被动FTP,更新/切换到其他服务器实现是不可能的。由于我的应用程序正在Docker中运行,所以活动FTP也几乎不可能实现。

您从FTP列表中得到的确切错误消息是什么?+显示FTP cli日志文件我是否正确理解您在同一台机器/服务器上运行的FTP cli,以及您运行PHP代码的位置?FTP cli为/usr/bin/FTP。ftp\u nlist不会抛出错误,它只是超时并返回false。您没有回答我所有的问题。不确定ftp是否写入日志文件,所以我不知道在哪里查找它,我现在能给您的是:至于另一个问题,是的,我正在运行PHP脚本的服务器上运行它。因此在您的PHP代码中,美元地址是192.168.12.10?+如何运行PHP代码?从命令行?来自与ftp相同的环境?+你有a吗
是否访问服务器端日志文件?如果没有,您可以执行Wireshark捕获或类似操作吗?您从ftp列表中获得的确切错误消息是什么?+显示FTP cli日志文件我是否正确理解您在同一台机器/服务器上运行的FTP cli,以及您运行PHP代码的位置?FTP cli为/usr/bin/FTP。ftp\u nlist不会抛出错误,它只是超时并返回false。您没有回答我所有的问题。不确定ftp是否写入日志文件,所以我不知道在哪里查找它,我现在能给您的是:至于另一个问题,是的,我正在运行PHP脚本的服务器上运行它。因此在您的PHP代码中,美元地址是192.168.12.10?+如何运行PHP代码?从命令行?来自与ftp相同的环境?+您有权访问服务器端日志文件吗?如果没有,你能做线鲨捕捉或类似的吗?我不这么认为。PHP ftp_pasv不做任何事情,它只设置一个内部标志。只有在使用ftp_nlist或类似函数后,PHP才会发送TYPE,然后发送PASV,并立即连接到提供的IP地址和端口。我调试这篇文章已经有一段时间了,我只是想用我的发现更新这篇文章。我研究了使用此FTP服务器和已知良好服务器之间的tcpdump差异,以及通过FTP CLI和PHP连接到的差异。PHP显示了错误的行为,正如我所说,我可以通过手动连接到被动端口来修复。即使PHP本身不是问题所在,我很确定FTP服务器是,当我手动建立一个完全独立的连接时,我的PHP脚本突然停止运行。我不这么认为。PHP ftp_pasv不做任何事情,它只设置一个内部标志。只有在使用ftp_nlist或类似函数后,PHP才会发送TYPE,然后发送PASV,并立即连接到提供的IP地址和端口。我调试这篇文章已经有一段时间了,我只是想用我的发现更新这篇文章。我研究了使用此FTP服务器和已知良好服务器之间的tcpdump差异,以及通过FTP CLI和PHP连接到的差异。PHP显示了错误的行为,正如我所说,我可以通过手动连接到被动端口来修复。即使PHP本身不是问题所在,我很确定FTP服务器是,当我手动建立一个完全独立的连接时,我的PHP脚本突然停止运行。