【问题标题】:Perl Net::FTPSSL doesn't work properly - timeout when trying to transfer dataPerl Net::FTPSSL 无法正常工作 - 尝试传输数据时超时
【发布时间】:2013-01-01 23:29:48
【问题描述】:

我必须将 pure-ftpd 的传输模式从常规 ftp 切换到带有 TLS 的 ftp。 所以我将配置标志 TLS 切换为 2(只有 TSL,没有常规 FTP)。

filezilla 的连接和文件传输工作正常。

现在我有一个 perl 脚本,它使用 NET::FTP 从服务器获取一些文件。

这是主要功能:

use Net::FTP;

$ftp = Net::FTP->new("[SERVERNAME]", Debug => 1)
  or die "Cannot connect to [SERVERNAME]: $@";

$ftp->login("[USER]",'[PASSWORD]')
  or die "Cannot login ", $ftp->message;

$ftp->cwd("/")
  or die "Cannot change working directory ", $ftp->message;

$ftp->dir("/")
  or die "get failed ", $ftp->message;

$ftp->get("somefile.txt")
  or die "get failed ", $ftp->message;

$ftp->quit;

为了重建 GET 功能,我尝试将 CPAN 模块 NET::FTPSSL 与以下脚本片段一起使用:

use Net::FTPSSL;

  my $ftps = Net::FTPSSL->new('[SERVERNAME]', 
                  Port => 21,
                              Encryption => EXP_CRYPT,
                  Croak => 1,
                  Trace => 1,
                              Debug => 2
                  )
    or die "Can't open [SERVERNAME]\n$Net::FTPSSL::ERRSTR";
  $ftps->login('[USER]', '[PASSWORD]') 
    or die "Can't login: ", $ftps->last_message();

  $ftps->cwd("/anyfolder") or die "Can't change directory: " . $ftps->last_message();
  $ftps->quot("PASV");
  $ftps->nlst() or die "Error: " . $ftps->last_message();
  $ftps->list("/anyfolder") or die "Can't change directory: " . $ftps->last_message();
  $ftps->binary() or die "Can't change directory: " . $ftps->last_message();
  $ftps->put("anyfile.txt") or die "Can't get file: " . $ftps->last_message();
  $ftps->get("anyfile.txt") or die "Can't get file: " . $ftps->last_message();

  $ftps->quit();

此脚本在身份验证过程中运行良好。 当涉及到文件传输时,它会停止,直到达到常规 timeaut。

脚本的调试输出如下所示:

SKT >> AUTH TLS SKT

用户 +++++++ 好的。要求输入密码 PASS * 具有组访问权限:100 ...,27,254) PBSZ 0 ...,145,153) --- 主机 (...) 端口 (37273) NLST

因此可以使用filezilla与服务器连接,但无法连接到服务器并使用脚本传输文件。

我知道这很可能不是什么大问题,但我目前无法找到错误。

【问题讨论】:

    标签: perl cpan


    【解决方案1】:

    我在从 Net::FTP 切换到 Net::FTPSSL 时遇到了类似的问题,我发现使用相同的远程地址传递 OverridePASV 参数解决了这个问题。

    【讨论】:

    • my $ftps = Net::FTPSSL->new('[Servername]', Port => 21, Encryption => EXP_CRYPT, Croak => 1, Trace => 1, OverridePASV => " xxx.xxx.xxx.xxx", Debug => 2 ) 没做好..
    • 进入被动模式后是否仍会立即死亡?
    • 是的,但这也不起作用。感觉跟证书有关系。我正在使用带有自己的 CA 的自签名证书。调试日志没有提到证书的验证。
    • 调试日志表明它正在尝试使用私有数据连接,但 Net::FTPSSL 中有 an open bug 表明当前不支持此功能。 pure-ftpd TLS readme 表示使用--tls=2 您应该仍然能够进行清除数据连接,但使用--tls=3 会拒绝它们。您是否能够根据文档检查 pure-ftpd 配置,以确保您没有强制进行私有数据连接?
    • Filezille 使用“私人”数据连接没有任何问题。 Filezilla.log 和我的脚本的 Debug 之间的唯一区别是两行:08:36:42 状态:正在初始化 TLS... 08:36:42 状态:正在检查证书...
    【解决方案2】:

    所以,您已经说过您尝试过 OverridePASV,但没有成功。通常,这是显而易见的解决方法,因为几个 FTP 服务器在 PASV 命令的响应中错误地返回了它们的 IP 地址。如果它们位于防火墙等之后,它们的外向 IP 地址就不是它们返回的那个。

    由于您是从广域网而不是内部局域网与服务器通信,因此将 PASV 连接设置到它为您提供的 IP 地址只会挂起。当您使用 OverridePASV 时,您可以强制被动连接使用 WAN IP 地址(即您用来连接它的地址)。

    鉴于 OverridePASV 不起作用,问题更可能是您的 FTP 服务器位于不允许被动连接完成的防火墙后面(即 FTP 服务器设置的端口没有获得端口-从 WAN 转发)或 FTP 服务器不支持被动。 Net::FTPSSL 只做被动(至少我正在查看的代码版本,标记为 0.31)。如果您正在与之交谈的 FTP 服务器不支持 PASV,或者您无法连接到被动端口,则连接通常会挂起,直到超时。 FileZilla 很可能使用的是 PORT 而不是 PASV,这就是它起作用的原因。

    【讨论】:

      【解决方案3】:

      $ftps->quot("PASV");

      quot 将文本发送到服务器以获得 Net::FTPSSL 中不存在的功能。

      PASV 改变了服务器的工作方式,但是因为“quot”,客户端并不在意。

      如果你想让 PASV 工作,你必须在 NET::FTPSSL 中创建一个新命令。

      这个新命令必须:

      1. 将“PASV”发送到服务器,然后
      2. 将客户端配置为作为数据连接的服务器。

      net::ftpssl 使用仅在客户端模式下工作的 DATA 连接库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-18
        • 2014-11-30
        • 1970-01-01
        相关资源
        最近更新 更多