Parece um bug no vsftpd para mim.
No código, parece que o vsftpd sempre envia o 0,0,0,0
, se o público pasv_address
estiver definido, e o servidor tem um endereço IPv6 (local).
Para corrigir isso, certifique-se de que o servidor não escute no endereço IPv6 (o que é um comportamento padrão, que você está sobrescrevendo, definindo listen_ipv6=YES
):
listen_ipv6=NO
listen=YES
A única outra solução é remover um endereço IPv6 privado, se for possível no EC2.
Ou use outro servidor FTP, por ex. ProFTPD .
Para provar que isso é realmente um bug:
handle_pasv
em 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");
}
}
em que vsf_sysutil_sockaddr_ipv6_v4
retorna 0, se o s_p_sockaddr
não for IPv6 (o que nunca é, quando o pasv_address
é definido).
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, o código está errado. Ele funciona (e faz sentido) quando o endereço IP é "autodetectado" em p_sess->p_local_addr
, mas falha quando o endereço pasv_address
é usado.
Considere relatar isso ao autor do vsftpd.