|
折腾了半小时,法上FileZilla 的传文状态栏一直卡在“正在传输 xxx.zip”,进度条死活不动,法上最后弹出一行红字:传输失败,传文无法打开数据连接。法上服务器明明连上了,传文目录也列出来了,法上偏偏传文件就断。传文这种破事我遇到过不下十次,法上每次原因都不一样。传文 最坑的法上一次是公司内网。能登录、传文能浏览,法上上传就超时。传文查了半天,法上防火墙把被动模式的端口段封了。FTP 这协议设计得早,主动模式是服务器回头连客户端,客户端这边一挡就废;被动模式是客户端连服务器开的高位端口,可服务器那端如果没放行 pasv_min_port 到 pasv_max_port 这段,照样白搭。我那次就是运维只开了 21 端口,以为万事大吉,结果文件传输走的是另一个端口,21 只管命令通道。 被动模式的问题最隐蔽。你用 ftp 命令行手动敲 passive 再 put,可能就成功了。因为命令行的被动模式协商跟图形客户端不一样。FileZilla 默认走被动,但有些服务器返回的 PASV 响应里给的是内网 IP,比如 227 Entering Passive Mode (192,168,1,10,...)。客户端拿到这个内网地址,当然连不上。这时候要么在客户端强制用主动模式,要么让服务器配置里把 pasv_address 设成公网 IP。我见过一个运维把服务器放在 NAT 后面,FTP 服务返回的永远是 10.0.0.x,外面的人传文件全挂,他还以为是账号权限问题。 权限的事也常被忽略。能列目录不代表能写。Linux 下 vsftpd 的 write_enable=YES 没开,或者目录的 w 位没给,上传就是 550 Permission denied。更阴间的是 SELinux。CentOS 上 ftp_home_dir 布尔值没开,或者目录的 SELinux 上下文不对,文件就是写不进去,日志里报 Permission denied,但你看 ls -l 权限明明是 777。我当初被这个坑了一下午,最后 getenforce 一看是 Enforcing,setsebool -P ftp_home_dir on 才解决。 客户端这边也有锅。Windows 防火墙有时候会拦 FileZilla 的出站连接,尤其是被动模式下客户端要开一个本地端口去连服务器。你看着它连上了 21 端口,但数据连接一建立就被系统墙掐了。临时关掉防火墙测试一下,如果好了,那就是它。还有一种情况是 MTU 问题。PPPoE 拨号的环境,MTU 默认 1492,传小文件没事,传大文件就卡死。因为数据包分片被中间设备丢了。把客户端网卡 MTU 调到 1400 试试,有时候能救急。 说个具体的。上周帮朋友调一个 vsftpd,症状是能登录、能 ls、能下载,就是不能上传。我让他把 /var/log/vsftpd.log 发过来,里面一行 500 OOPS: vsftpd: refusing to run with writable root inside chroot()。原因是他开了 chroot_local_user=YES,但用户主目录对用户自己可写。vsftpd 从 2.3.5 开始就不允许 chroot 目录可写。解决办法要么去掉主目录的写权限,要么加 allow_writeable_chroot=YES。他加完重启,文件嗖嗖就上去了。 所以 FTP 上传失败,别急着怪网络。先看日志,服务器端和客户端都看。然后分清楚是命令通道的问题还是数据通道的问题。命令通道通、数据通道不通,八成是模式或防火墙。命令通道就报权限错,查 write_enable 和目录权限。如果日志里出现 425、426、550、500 这些代码,对应去查,比瞎猜快得多。实在不行,换 SFTP 吧,一个端口搞定所有事,省心。 |