即使使用正确的pasv_address,Vsftpd被动回复0,0,0,0地址

我在vsftpd中有以下configuration

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 

但是,当试图使用FTP连接到服务器时,出现以下警告,

 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 

如果你看到它进入被动模式与此

进入被动模式(0,0,0,0,4,1)

我不知道这是从哪里来的(甚至是什么)。 我也有SELinux执行。

我在这里做错了什么?

亲切的问候,V

它看起来像是vsftpd中的一个bug。

从代码看来,如果public pasv_address被设置,并且服务器有一个(本地)IPv6地址,vsftpd总是发送0,0,0,0

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]; } 

Imho,代码是错误的。 当IP地址从p_sess->p_local_addr “自动检测”时,它工作(并且是有意义的),但是在使用pasv_address地址时失败。

考虑把这个报告给vsftpd的作者。


我看到的唯一解决scheme是删除一个私有IPv6地址,如果在EC2中可能的话。

或者使用另一台FTP服务器,例如ProFTPD 。

我在阿里云托pipe的服务器上遇到了这个问题。

我通过禁用listen_ipv6并在configuration中启用listen来解决这个问题。

 listen_ipv6=NO listen=YES 

我也使用pasv_address=指定了我的外部IP