virginia east aws amazon-ec2 ftp vsftpd

amazon ec2 - east - vsftpd devuelve 0,0,0,0 en respuesta a PASV



security groups (1)

Parece un error en vsftpd para mí.

Del código que parece, siempre enviará el 0,0,0,0 , si se establece el público pasv_address , pero el servidor tiene una dirección (local) IPv6.

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

donde vsf_sysutil_sockaddr_ipv6_v4 devuelve 0, si el s_p_sockaddr no es IPv6, lo que nunca es, cuando se establece 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]; }

Imho, el código está mal. Funciona (y tiene sentido), cuando la dirección IP es "autodetectada" desde p_sess->p_local_addr , pero falla, cuando se pasv_address dirección pasv_address .

Considere reportar esto al autor de vsftpd.

La única solución que veo es eliminar una dirección IPv6 privada, si es posible en EC2.

O use otro servidor FTP, por ejemplo, ProFTPD .

Mantener una explicación original de PASV contra EPSV :

Solo para explicar la diferencia entre el PASV y el EPSV : El PASV devuelve una dirección IP en la respuesta. Esa información está en 99.9% redundante. Y comúnmente causa problemas cuando el servidor no tiene conocimiento de su dirección IP externa.

El EPSV se introdujo más tarde que el PASV , cuando quedó claro que la presencia de la dirección IP en la respuesta es problemática. Entonces, con el EPSV , solo se incluye un número de puerto. Y el cliente se conecta a la dirección IP del servidor FTP implícitamente.

Si el servidor realmente devuelve 0,0,0,0 en respuesta al comando PASV , queda claro por qué el cliente no se puede conectar al servidor cuando se usa PASV .

Configuré un servidor FTP en AWS EC2 (Ubuntu16.04) con modo pasivo ( PASV ), pero no funciona. Sin embargo, funciona con EPSV , no sé por qué. Busqué pero no encontré respuestas, ¿algún cuerpo puede ayudarme con esto?

1. configuración de 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 Firewall

3. Prueba a través de FireFTP

Con el modo PASV , no puedo conectarme al servidor FTP, el registro es:

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

Sin embargo, con esto funciona con EPSV (con la casilla de verificación IPV6 seleccionada), el registro de la siguiente manera:

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. Prueba a través de 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()

El registro de la siguiente manera:

*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