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
ただし、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のバグのように見えます。
コードからは、パブリック0,0,0,0
が設定されていて、サーバーに(ローカル)IPv6アドレスがある場合、vsftpdは常にpasv_address
を送信するように見えます。
これを修正するには、サーバーがIPv6アドレスをリッスンしないようにします(デフォルトの動作は何ですか。listen_ipv6=YES
を設定することでオーバーライドします)。
listen_ipv6=NO
listen=YES
他の唯一の解決策は、EC2で可能な場合、プライベートIPv6アドレスを削除することです。
または、別のFTPサーバーを使用します。 ProFTPD 。
これが確かにバグであることを証明するには:
handle_pasv
in 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
がIPv6でない場合、s_p_sockaddr
は0を返します(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の作成者に報告することを検討してください。
Aliyunでホストされているサーバーでこの問題が発生しました。
私はlisten_ipv6を無効にし、構成でlistenを有効にすることで問題を解決しました。
listen_ipv6=NO
listen=YES
また、pasv_address=
を使用して外部IPを指定しました