Resposta passiva Vsftpd com endereço 0,0,0,0 mesmo com pasv_address correto

1

Eu tenho a seguinte configuração em vsftpd

listen_ipv6=YES
allow_writeable_chroot=YES
seccomp_sandbox=NO
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
pasv_enable=YES
pasv_min_port=1024
pasv_max_port=1048
pasv_address=<Elastic ip from amazon aws ec2 instance>
pasv_promiscuous=YES

No entanto, ao tentar se conectar ao servidor usando FTP, recebo este aviso a seguir,

Status: Retrieving directory listing...
Command: PWD
Response: 257 "/"
Command: TYPE I
Response: 200 Switching to Binary mode.
Command: PASV
Response: 227 Entering Passive Mode (0,0,0,0,4,1).
Status: Server sent passive reply with unroutable address. Using server address instead.
Command: LIST
Response: 150 Here comes the directory listing.
Response: 226 Directory send OK.
Directory listing of "/" successful

Se você ver, ele entra no modo passivo com isso

Entering Passive Mode (0,0,0,0,4,1)

Eu não tenho idéia de onde isso está vindo (ou até mesmo o que é isso). Eu tenho o SELinux reforçando também.

O que estou fazendo de errado aqui?

Atenciosamente, V

    
por Vic85 16.12.2016 / 00:18

2 respostas

6

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.

    
por 16.12.2016 / 07:40
1

Eu tive esse problema com um servidor hospedado no Aliyun.

Eu resolvi isso desabilitando o listen_ipv6 e habilitando o listen na configuração.

listen_ipv6=NO
listen=YES

Eu também especifiquei meu IP externo usando pasv_address=

    
por 17.03.2017 / 18:20