响应PASV,vsftpd返回0,0,0,0 [英] vsftpd returns 0,0,0,0 in response to PASV

查看:2975
本文介绍了响应PASV,vsftpd返回0,0,0,0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

1。 vsftpd config

  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 = [AWS EC2实例的公有IP地址]
allow_writeable_chroot = YES
seccomp_sandbox = NO

2。 AWS EC2防火墙





3。通过FireFTP测试





使用 PASV 模式,我无法连接到FTP服务器,日志为:

  220(vsFTPd 3.0.3)
USER sensor
331请指定密码。
PASS(密码未显示)
230登录成功。
CWD /
250目录已成功更改。
TYPE A
200切换到ASCII模式。
PASV
QUIT

然而,它适用于 EPSV (选中IPV6复选框),日志如下:

  220(vsFTPd 3.0。 3)
USER传感器
331请指定密码。
PASS(密码未显示)
230登录成功。
PWD
257/是当前目录
TYPE A
200切换到ASCII模式。
EPSV
229进入扩展被动模式(||| 13082 |)
LIST
150这里是目录列表。
226目录发送确定。

4。从ftplib导入FTP
内容= [ ]
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\\\
'
* get *'200切换到ASCII模式.\\\
'
* resp *'200切换到ASCII模式。'
* cmd *'PASV'
* put * '进入被动模式(0,0,0,0,50,245)。''
* res'*'进入被动模式( '
ConnectionRefusedError:[Errno 111]连接被拒绝


解决方案

它看起来像是vsftpd中的一个bug。



从代码看起来,它总是会发送 0,0,0,0 ,如果pub设置lic pasv_address ,但服务器有一个(本地)IPv6地址。





<在$ postlogin.c 中: handle_pasv $ <$ p
$ b

  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);如果(vsf_sysutil_inet_aton(tunable_pasv_address,s_p_sockaddr)== 0)
{
/ *报告配置中指定的被动地址* /
;(无效的pasv_address)
}
}
else
{
vsf_sysutil_sockaddr_clone(& s_p_sockaddr,p_sess-> p_local_addr);
}
str_alloc_text(& s_pasv_res_str,输入被动模式();
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 s_p_sockaddr 不是IPv6,当设置 pasv_address 时,c>返回0。 / p>

sysutil.c

 

static unsigned char pattern [12] =
{0 ,0,0,0,0,0,0,0,0,0,0FF,0xFF};
const无符号字符* 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];
}

Imho,代码错误。当IP地址从 p_sess-> p_local_addr 中自动检测时,它工作(并且有意义),但是当 pasv_address <使用code>地址。



考虑向vsftpd的作者报告。






我看到的唯一解决方案是删除一个私有IPv6地址,如果它可能在EC2中。



或者使用另一个FTP服务器,例如 ProFTPD






保留 PASV EPSV 的原始解释:



只是为了解释 PASV EPSV 之间的区别: PASV 会在响应中返回一个IP地址。该信息99.9%是多余的。当服务器不知道其外部IP地址时,它通常会导致问题。 $ b $ EPSV PASV 晚,当时很明显,响应中的IP地址存在问题。因此,对于 EPSV ,只包含一个端口号。并且客户端隐式地连接到FTP服务器IP地址。



如果服务器真的返回 0,0,0,0 在对 PASV 命令的响应中,很明显为什么客户端无法连接到服务器,当 PASV 被使用。


I set up an FTP server on AWS EC2 (Ubuntu16.04) with passive mode (PASV), but it doesn't work. However, it works with EPSV, don't know why. I searched around but find no answers, any body can help me with this?

1. vsftpd config

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 Firewall

3. Test through FireFTP

With PASV mode, I cannot connect to FTP server, the log is:

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

However, with it works with EPSV (with IPV6 checkbox selected), the log as below:

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. Test through 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()

The log as below:

*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

解决方案

It looks like a bug in vsftpd to me.

From the code it looks like, it will always send the 0,0,0,0, if the public pasv_address is set, but the server has a (local) IPv6 address.

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");
  }
}

where the vsf_sysutil_sockaddr_ipv6_v4 returns 0, if the s_p_sockaddr is not IPv6, what it never is, when the pasv_address is set.

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];
}

Imho, the code is wrong. It works (and makes sense), when the IP address is "autodetected" from p_sess->p_local_addr, but fails, when the pasv_address address is used.

Consider reporting this to the author of vsftpd.


The only solution I see, is removing a private IPv6 address, if it is possible in EC2.

Or use another FTP server, e.g. ProFTPD.


Keeping an original explanation of the PASV vs. EPSV:

Just to explain the difference between the PASV and the EPSV: The PASV returns an IP address in the response. That information is in 99.9% redundant. And it commonly causes problems, when the server is not aware of its external IP address.

The EPSV was introduced later than the PASV, when it was clear that the IP address presence in the response is problematic. So with the EPSV, only a port number is included. And the client connects to the FTP server IP address implicitly.

If the server really returns 0,0,0,0 in a response to the PASV command, it's clear why the client cannot connect to the server, when the PASV is used.

这篇关于响应PASV,vsftpd返回0,0,0,0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆