2016-12-08 12 views
3

J'ai mis en place un serveur FTP sur AWS EC2 (Ubuntu16.04) avec le mode passif (PASV), mais cela ne fonctionne pas. Cependant, cela fonctionne avec EPSV, je ne sais pas pourquoi. J'ai cherché autour mais je n'ai trouvé aucune réponse, n'importe quel corps peut m'aider avec ceci?vsftpd renvoie 0,0,0,0 en réponse à PASV

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

security groups (Inbound) setting

3. Test de par FireFTP

Without IPV6 selected

Avec le mode PASV, je ne peux pas se connecter au serveur FTP, le journal est:

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 

Cependant, il fonctionne avec EPSV (avec case à cocher IPV6 sélectionnée), le journal comme suit:

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. Testez par 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() 

Le journal comme suit:

*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 
+0

Renvoie-t-il vraiment '0,0,0,0' dans la réponse' PASV'? –

+0

Merci Martin! Comme indiqué dans le journal de ftplib, il renvoie (0, 0, 0, 0, ..) alors que le mode PASV est appliqué. – codefluxer

+0

Ensuite, je suppose que vous avez spécifié l'adresse IPv6 dans 'pasv_address'. Il doit être l'adresse IPv4 pour que 'PASV' fonctionne. Le 'PASV' ne supporte pas IPv6. –

Répondre

2

Il ressemble à un bogue dans vsftpd pour moi.

Du code il semble, il enverra toujours le 0,0,0,0, si le public pasv_address est défini, mais le serveur a une adresse IPv6 (locale).

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

où les rendements vsf_sysutil_sockaddr_ipv6_v4 0, si le s_p_sockaddr n'est pas IPv6, ce qu'il ne l'est jamais, quand le pasv_address est réglé.

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, le code est erroné. Cela fonctionne (et a du sens), lorsque l'adresse IP est "détectée automatiquement" de p_sess->p_local_addr, mais échoue, lorsque l'adresse pasv_address est utilisée.

Envisagez de le signaler à l'auteur de vsftpd.


La seule solution que je vois, est de supprimer une adresse IPv6 privée, si cela est possible dans EC2.

Ou utilisez un autre serveur FTP, par ex. ProFTPD.


Garder une explication originale du PASV par rapport EPSV:

Juste pour expliquer la différence entre le PASV et le EPSV: Le PASV renvoie une adresse IP dans la réponse. Cette information est redondante à 99,9%. Et il provoque généralement des problèmes, lorsque le serveur n'est pas au courant de son adresse IP externe. Le EPSV a été introduit plus tard que le PASV, lorsqu'il était clair que la présence de l'adresse IP dans la réponse est problématique. Donc, avec le EPSV, seul un numéro de port est inclus. Et le client se connecte implicitement à l'adresse IP du serveur FTP.

Si le serveur renvoie vraiment 0,0,0,0 dans une réponse à la commande PASV, il est clair pourquoi le client ne peut pas se connecter au serveur lorsque le PASV est utilisé.

+0

De bonnes explications, appréciées! Je ne peux rien faire à propos de l'adresse IPv6 privée de EC2, je dois changer et essayer un autre serveur FTP maintenant. – codefluxer

+0

Merci de le rappeler, acceptez-le. – codefluxer