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

Vic*_*c85 4 selinux ftp vsftpd

我在 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
Run Code Online (Sandbox Code Playgroud)

但是,当尝试使用 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

我在这里做错了什么?

亲切的问候,V

Mar*_*ryl 11

对我来说,它看起来像是 vsftpd 中的一个错误。

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

要解决此问题,请确保服务器不侦听 IPv6 地址(默认行为是什么,您将通过设置覆盖listen_ipv6=YES):

listen_ipv6=NO
listen=YES
Run Code Online (Sandbox Code Playgroud)

唯一的其他解决方案是删除私有 IPv6 地址(如果在 EC2 中可能的话)。

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


为了证明这确实是一个错误:

handle_pasvpostlogin.c

listen_ipv6=NO
listen=YES
Run Code Online (Sandbox Code Playgroud)

其中,vsf_sysutil_sockaddr_ipv6_v4返回0,如果s_p_sockaddr不支持IPv6(它永远不会是什么,当pasv_address设置)。

sysutil.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");
  }
}
Run Code Online (Sandbox Code Playgroud)

恕我直言,代码错了。当从 中“自动检测到”IP 地址时,它有效(并且有意义)p_sess->p_local_addr,但在使用该pasv_address地址时失败。

考虑向 vsftpd 的作者报告这个问题。