【问题标题】:vsftpd returns 0,0,0,0 in response to PASVvsftpd 响应 PASV 返回 0,0,0,0
【发布时间】:2017-04-24 02:56:54
【问题描述】:

我在 AWS EC2 (Ubuntu16.04) 上使用被动模式 (PASV) 设置了一个 FTP 服务器,但它不起作用。但是,它适用于EPSV,不知道为什么。我四处寻找,但没有找到答案,任何机构可以帮助我吗?

1. vsftpd 配置

anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
pasv_enable=YES
pasv_min_port=13000
pasv_max_port=13100
port_enable=YES
pasv_address=[public ip address of AWS EC2 instance]
allow_writeable_chroot=YES
seccomp_sandbox=NO

2。 AWS EC2 防火墙

3.通过 FireFTP 测试

PASV模式下,无法连接FTP服务器,日志为:

220 (vsFTPd 3.0.3)
USER sensor
331 Please specify the password.
PASS (password not shown)
230 Login successful.
CWD /
250 Directory successfully changed.
TYPE A
200 Switching to ASCII mode.
PASV
QUIT

但是,它适用于EPSV(选中了IPV6复选框),日志如下:

220 (vsFTPd 3.0.3)
USER sensor
331 Please specify the password.
PASS (password not shown)
230 Login successful.
PWD
257 "/" is the current directory
TYPE A
200 Switching to ASCII mode.
EPSV
229 Entering Extended Passive Mode (|||13082|)
LIST
150 Here comes the directory listing.
226 Directory send OK.

4.通过 Python ftplib 测试

from ftplib import FTP
contents = []
ftp = FTP(host=xxx, timeout=3000)
ftp.login(user=xxx, passwd=xxx)
ftp.set_debuglevel(2)
ftp.retrlines("NLST", contents.append)
ftp.quit()

日志如下:

*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 Switching to ASCII mode.\n'
*resp* '200 Switching to ASCII mode.'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (0,0,0,0,50,245).\n'
*resp* '227 Entering Passive Mode (0,0,0,0,50,245).'
ConnectionRefusedError: [Errno 111] Connection refused

【问题讨论】:

    标签: amazon-ec2 ftp vsftpd


    【解决方案1】:

    在我看来,这就像 vsftpd 中的一个错误。

    从代码看起来,如果设置了公共pasv_address,它将始终发送0,0,0,0,但服务器具有(本地)IPv6 地址。

    要解决此问题,请确保服务器不侦听 IPv6 地址(默认行为是什么,您通过设置 listen_ipv6=YES 覆盖):

    listen_ipv6=NO
    listen=YES
    

    如果在 EC2 中可行,唯一的其他解决方案是删除私有 IPv6 地址。

    或使用其他 FTP 服务器,例如ProFTPD.

    或者让ftplib忽略服务器返回的IP地址。
    Cannot list FTP directory using ftplib – but FTP client works


    要证明这确实是一个bug,请查看最新vsftpd版本(3.0.3)的这段代码:

    handle_pasv in postlogin.c:

    int is_ipv6 = vsf_sysutil_sockaddr_is_ipv6(p_sess->p_local_addr);
    
    ...
    
    if (tunable_pasv_address != 0)
    {
      vsf_sysutil_sockaddr_alloc_ipv4(&s_p_sockaddr);
      /* Report passive address as specified in configuration */
      if (vsf_sysutil_inet_aton(tunable_pasv_address, s_p_sockaddr) == 0)
      {
        die("invalid pasv_address");
      }
    }
    else
    {
      vsf_sysutil_sockaddr_clone(&s_p_sockaddr, p_sess->p_local_addr);
    }
    str_alloc_text(&s_pasv_res_str, "Entering Passive Mode (");
    if (!is_ipv6)
    {
      str_append_text(&s_pasv_res_str, vsf_sysutil_inet_ntop(s_p_sockaddr));
    }
    else
    {
      const void* p_v4addr = vsf_sysutil_sockaddr_ipv6_v4(s_p_sockaddr);
      if (p_v4addr)
      {
        str_append_text(&s_pasv_res_str, vsf_sysutil_inet_ntoa(p_v4addr));
      }
      else
      {
        str_append_text(&s_pasv_res_str, "0,0,0,0");
      }
    }
    

    vsf_sysutil_sockaddr_ipv6_v4 返回 0,如果 s_p_sockaddr 不是 IPv6,那么当 pasv_address 设置时,它永远不会是。

    sysutil.c:

    const void*
    vsf_sysutil_sockaddr_ipv6_v4(const struct vsf_sysutil_sockaddr* p_addr)
    {
      static unsigned char pattern[12] =
          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF };
      const unsigned char* p_addr_start;
      if (p_addr->u.u_sockaddr.sa_family != AF_INET6)
      {
        return 0;
      }
      if (vsf_sysutil_memcmp(pattern, &p_addr->u.u_sockaddr_in6.sin6_addr, 12))
      {
        return 0;
      }
      p_addr_start = (const unsigned char*)&p_addr->u.u_sockaddr_in6.sin6_addr;
      return &p_addr_start[12];
    }
    

    恕我直言,代码错误。当 IP 地址是从p_sess->p_local_addr“自动检测”时,它有效(并且有意义),但在使用 pasv_address 地址时失败。

    考虑将此报告给 vsftpd 的作者。


    保留PASVEPSV 的原始解释:

    只是为了解释PASVEPSV 之间的区别:PASV 在响应中返回一个 IP 地址。该信息 99.9% 是多余的。当服务器不知道其外部 IP 地址时,它通常会导致问题。

    EPSV 的引入晚于 PASV,当时很明显响应中的 IP 地址存在存在问题。所以EPSV 只包含一个端口号。并且客户端隐式连接到FTP服务器IP地址。

    如果服务器在对PASV命令的响应中确实返回0,0,0,0,那么当使用PASV时,客户端无法连接到服务器的原因就很清楚了。

    【讨论】:

    • 很好的解释,感谢!无法对 EC2 的私有 IPv6 地址做任何事情,我现在必须更改并尝试另一个 FTP 服务器。
    猜你喜欢
    • 2021-01-12
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多