响应PASV,vsftpd返回0,0,0,0 [英] vsftpd returns 0,0,0,0 in response to PASV
问题描述
我使用被动模式( 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 如下: 它看起来像是vsftpd中的一个bug。 从代码看起来,它总是会发送
内容= [ ]
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]连接被拒绝
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 $ c $如果
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 $ 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屋!