在 ubuntu 上使用 sudo apt-get install vsftpd 后,vsftpd 按照附件 /etc/vsftpd.conf 文件进行配置。匿名 ftp 允许直接通过 cd 进行上传,并允许将 myfile.txt 放在服务器上,但客户端会挂起,无法继续。服务器上的文件保持为 0 字节。
以下是文件夹和权限:
root@support:/home/ftp# ls -ld .
drwxr-xr-x 3 root root 4096 Jun 22 00:00 .
root@support:/home/ftp# ls -ld pub
drwxr-xr-x 3 root root 4096 Jun 21 23:59 pub
root@support:/home/ftp# ls -ld pub/upload
drwxr-xr-x 2 ftp ftp 4096 Jun 22 00:06 pub/upload
root@support:/home/ftp#
这是 vsftpd.conf 文件:
root@support:/home/ftp# grep -v '#' /etc/vsftpd.conf
listen=YES
anonymous_enable=YES
write_enable=YES
anon_upload_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
anon_root=/home/ftp/pub/
connect_from_port_20=YES
chown_uploads=YES
chown_username=ftp
nopriv_user=ftp
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
以下是尝试上传的文件示例:
root@support:/home/ftp/pub/upload# ls -l
total 0
-rw------- 1 ftp nogroup 0 Jun 22 00:06 build.out
这是客户端尝试上传...此时它被冻结了:
$ ftp 173.203.89.78
Connected to 173.203.89.78.
220 (vsFTPd 2.0.6)
User (173.203.89.78:(none)): ftp
331 Please specify the password.
Password:
230 Login successful.
ftp> put build.out
200 PORT command successful. Consider using PASV.
553 Could not create file.
ftp> cd upload
250 Directory successfully changed.
ftp> put build.out
200 PORT command successful. Consider using PASV.
150 Ok to send data.
编辑:事实证明,ftp 客户端可以在其他运行 Linux 的系统上运行。上述错误消息仅在使用命令行 ftp 在 Windows 7 主机上使用 ftp 时才会发生。
事实上,在同一台 Windows 7 机器上,如果你将地址输入 Windows 资源管理器,它就可以正常工作。它可以复制和粘贴文件,并且它们会正确上传到服务器上。
因此,该问题仅发生在 Windows 7 命令行 ftp 上。注意:我仔细检查了这台机器上的防火墙是否已完全禁用。
答案1
看起来您正在尝试使用主动 FTP,但是服务器和客户端之间的防火墙阻止了数据通道。FTP 事务由两个通道或连接组成:命令通道(在端口 21 上)和数据通道(通常与端口 20 相关联)。客户端在命令通道上发出命令,而有效负载(文件内容和命令的输出,如ls
)则在数据通道上传输。如果防火墙或路由器干扰了数据通道,您可以登录,一切似乎都正常,直到您尝试从服务器获取或发送信息 - 此时一切似乎都挂起了。服务器正在尝试重新连接客户端,但无法这样做。
在主动模式下(除非您发送命令,否则默认为主动模式PASV
[请注意 vsftpd 建议您这样做Consider using PASV
]),服务器会尝试打开与客户端的数据通道连接。没错 - 服务器正在连接回客户端,并且使用大于 1023 的端口。防火墙往往会反对这种做法,如果您使用 NAT,它根本无法工作。
这就是被动 FTP 的用武之地。使用被动 FTP,服务器使用已建立的 connamd 通道告诉客户端要使用哪个端口和 IP 地址作为数据通道,然后客户端为数据通道打开与服务器的第二个连接。这解决了客户端位于防火墙后面的问题。您需要做的就是PASV
在 之前从客户端发出命令PUT
。如果这不起作用,那么您可能需要稍微帮助 vsftpd。您可能需要包括pasv_min_port
和 的配置项pasv_max_port
,它们可让您控制 vsftpd 告诉客户端连接的一系列端口,以便您可以在防火墙中打开它们。此外,如果服务器没有在客户端连接的同一 IP 地址上监听(可能在 NAT 内),则pasv_address
告诉 vsftp 客户端实际想要连接到哪里(它不会自动使用打开命令通道的地址)。