2016-12-08 4 views
3

Я установил FTP-сервер на AWS EC2 (Ubuntu16.04) с пассивным режимом (PASV), но он не работает. Однако он работает с EPSV, не знаю почему. Я искал вокруг, но не нахожу ответов, любой орган может мне помочь в этом?vsftpd возвращает 0,0,0,0 в ответ на PASV

1. 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 брандмауэр

security groups (Inbound) setting

3. Испытание через FireFTP

Without IPV6 selected

В режиме PASV я не могу подключиться к FTP-серверу, журнал:

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 

Однако, он работает с EPSV (с выбранным IPV6 флажок), журнал, как показано ниже:

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. Тестирование с помощью 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() 

Бревно, как показано ниже:

*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

Действительно ли он возвращает '0,0,0,0' в ответ' PASV'? –

+0

Спасибо, Мартин! Как показано в журнале ftplib, он возвращает (0, 0, 0, 0, ..), в то время как применяется режим PASV. – codefluxer

+0

Тогда, я думаю, вы указали адрес IPv6 в 'pasv_address'. Он должен быть адресом IPv4 для работы «PASV». 'PASV' не поддерживает IPv6. –

ответ

2

Это похоже на ошибку в VSFTPD мне.

Из кода он будет выглядеть так: он всегда будет отправлять 0,0,0,0, если установлен pasv_address, но сервер имеет (локальный) IPv6-адрес.

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

где vsf_sysutil_sockaddr_ipv6_v4 возвращает 0, если s_p_sockaddr не IPv6, что он никогда не бывает, когда 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]; 
} 

Имхо, код неправильно. Он работает (и имеет смысл), когда IP-адрес «автоопределяется» от p_sess->p_local_addr, но не работает, когда используется адрес pasv_address.

Рассмотрите сообщение об этом автору vsftpd.

Единственное решение, которое я вижу, удаляет частный IPv6-адрес, если это возможно в EC2.

Или используйте другой FTP-сервер, например. ProFTPD.


Сохраняя оригинальное объяснение PASV VS. EPSV:

Просто, чтобы объяснить разницу между PASV и EPSV: The PASV возвращает IP-адрес в ответе. Эта информация в 99,9% избыточна. И это обычно вызывает проблемы, когда сервер не знает своего внешнего IP-адреса.

EPSV был введен позднее, чем PASV, когда было ясно, что присутствие IP-адреса в ответе проблематично. Таким образом, с EPSV включен только номер порта. И клиент неявно подключается к IP-адресу FTP-сервера.

Если сервер действительно возвращает 0,0,0,0 в ответ на команду PASV, понятно, почему клиент не может подключиться к серверу, когда используется PASV.

+0

Отличные объяснения, оценили! Не могу ничего сделать по поводу частного IPv6-адреса EC2, теперь мне нужно изменить и попробовать другой FTP-сервер. – codefluxer

+0

Спасибо за напоминание, примите это. – codefluxer