简介
文件传输协议(FTP)是一种标准的网络协议,用于在计算机网络上的客户端和服务器之间传输计算机文件。
FTP建立在客户端-服务器模型架构上,在客户端和服务器之间使用单独的控制和数据连接。[1] FTP用户可以使用明文登录协议对自己进行身份验证,通常以用户名和密码的形式进行身份验证,但如果服务器配置为允许,则可以匿名连接。为了保护用户名和密码以及对内容进行加密的安全传输,通常使用SSL / TLS(FTPS)来保护FTP或使用SSH文件传输协议(SFTP)来代替FTP。
第一个FTP客户端应用程序是在操作系统具有图形用户界面之前开发的命令行程序,并且仍随大多数Windows,Unix和Linux操作系统一起提供。[2] [3]此后,已经为台式机,服务器,移动设备和硬件开发了许多FTP客户端和自动化实用程序,并且FTP已被合并到生产力应用程序中,例如HTML编辑器。
2020年11月,谷歌浏览器弃用了对FTP协议的支持。[4]
协议
这里讲述协议细节及一些相关的调试手段
使用的端口
-
21:控制端口
-
20:数据端口(主动模式时使用的端口)
-
其他:协商出来的端口号
主动与被动
FTP有两种使用模式:主动和被动。主动模式要求客户端和服务器端同时打开并且监听一个端口以创建连接。在这种情况下,客户端由于安装了防火墙会产生一些问题。所以,创立了被动模式。被动模式只要求服务器端产生一个监听相应端口的进程,这样就可以绕过客户端安装了防火墙的问题。
一个主动模式的FTP连接创建要遵循以下步骤:
-
客户端打开一个随机的端口(端口号大于1024,在这里,我们称它为x),同时一个FTP进程连接至服务器的21号命令端口。此时,该tcp连接的来源地端口为客户端指定的随机端口x,目的地端口(远程端口)为服务器上的21号端口。
-
客户端开始监听端口(x+1),同时向服务器发送一个端口命令(通过服务器的21号命令端口),此命令告诉服务器客户端正在监听的端口号并且已准备好从此端口接收数据。这个端口就是我们所知的数据端口。
-
服务器打开20号源端口并且创建和客户端数据端口的连接。此时,来源地的端口为20,远程数据(目的地)端口为(x+1)。
-
客户端通过本地的数据端口创建一个和服务器20号端口的连接,然后向服务器发送一个应答,告诉服务器它已经创建好了一个连接。
主动和主动模式只在传输数据时有意义。这里的被动与主动都是针对服务端而言的:主动模式时,客户端监听在一个选定的端口,服务端的使用20端口主动去连接该端口;被动模式时,服务端监听在一个选定的端口,被动接受客户端的连接
主动连接使用PORT命令,被动连接使用PASV命令
命令列表
参见List of FTP commands - Wikipedia
使用方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
PS C:\Users\wsxq2> telnet 10.10.1.101 21
220 (vsFTPd 3.0.3)
OPTS UTF8 ON
200 Always in UTF8 mode.
USER anonymous
331 Please specify the password.
PASS
230 Login successful.
ls
500 Unknown command.
FEAT
211-Features:
UTF8
EPRT
EPSV
MDTM
PASV
REST STREAM
SIZE
TVFS
211 End
LIST
425 Use PORT or PASV first.
PASV
227 Entering Passive Mode (10,10,1,101,97,188).
LIST
由此可见,telnet无法使用主动模式和被动模式,无法LIST和传输文件
另外使用经典的FTP命令行客户端ftp命令中的-d参数也能看到具体的命令(注意区分ftp命令中的命令和FTP协议中的命令):
亦可在交互式界面使用debug命令(ftp的命令):
其它FTP客户端应当具有更加强大的功能,说不定可以直接输入原生命令(协议规定的命令,如CWD等)
服务端返回码
如果想要了解返回码的基本含义,经典FTP命令行客户端中就有提示(抓包也能看到提示),如果需要更加详细的信息,可参见List of FTP server return codes - Wikipedia。里面还提供了相关的RFC链接
实现
服务端
详情参见Comparison of FTP server software packages - Wikipedia
vsftpd
详情参见man vsftpd
安装
1
2
yum install -y vsftpd # for centos
apt install vsftpd # for ubuntu
配置
主配置文件位置:
1
2
/etc/vsftpd/vsftpd.conf # for centos
/etc/vsftpd.conf # for ubuntu
主配置文件常用内容(匿名用户,本机用户可登录):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
chroot_local_user=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
anon_root=/home6/ftp # 修改这个变量的值(FTP服务的目录)
allow_writeable_chroot=YES
注意修改后一定要重启vsftpd服务才能生效
启动
1
2
3
systemctl start vsftpd # 启动
systemctl enable vsftpd # 开机自启
systemctl restart vsftp # 重启
遇到过的问题
Allow anonymous upload for Vsftpd?
参见如下配置即可(注意加粗的行):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
listen=YES
anonymous_enable=YES
local_enable=YES
write_enable=YES
xferlog_file=YES
#anonymous users are restricted (chrooted) to anon_root
#directory was created by root, hence owned by root.root
anon_root=/var/ftp/pub/incoming
anon_upload_enable=YES
anon_mkdir_write_enable=YES
#chroot_local_user=NO
#chroot_list_enable=YES
#chroot_list_file=/etc/vsftpd.chroot_list
chown_uploads=YES
详情参见linux - Allow anonymous upload for Vsftpd? - Server Fault
How to Solve the VSFTPD 500 OOPS Error?
1
echo 'allow_writeable_chroot=YES' >> /etc/vsftpd/vsftpd.conf && systemctl restart vsftpd
或者:
1
chmod -w /var/ftp
详情参见How to Solve the VSFTPD 500 OOPS Error | Liquid Web
Permission denied in FTP even though I’m the owner?
1
write_enable=YES
详情参见Permission denied in FTP even though I’m the owner - Ask Ubuntu
但是好像没有解决,这块后续需要完善
客户端
详情参见Comparison of FTP client software - Wikipedia
ftp(pftp)
简介
命令行FTP客户端经典版本,仅支持基本功能(如不支持输入协议规定的原生命令、不支持修改为UTF8编码等)
使用示例
1
2
3
4
5
6
$ ftp 192.168.1.101
用户(192.168.1.101:(none)): anonymous # 输入匿名用户名
密码: # 直接回车
> ls
> cd ..
> get a.zip
详情参见man ftp
遇到过的问题
Windows ftp.exe不支持被动模式?
对比:
可以看到确实不支持
解决方法:如果主动模式不行,使用其他ftp客户端,如filezilla
Linux ftp客户端连上服务器ls时中文文件名乱码?
如下图所示:
图 3‑1客户端
图 3‑2服务端
事实上,经典命令行FTP客户端默认编码为GBK,服务器端(如vsftpd)亦如此。并且经典命令行客户端ftp命令还不支持设置修改默认编码
从底层来说,设置UTF8编码需要先发送FEAT命令看服务器是否支持UTF8,如果支持再使用OPTS UTF8 ON启用UTF8,否则需要在服务器端配置UTF8的支持性。
从顶层来说,直接使用支持UTF8的服务端(如vsftpd中配置utf8_filesystem=YES)和客户端(如lftp默认使用UTF8)即可
注:Windows上的ftp.exe默认使用UTF8
lftp
简介
复杂的FTP命令行客户端程序,功能强大。准确地说,它是一个支持基于IPv4和Ipv6的FTP, HTTP, FISH, SFTP, HTTPS, FTPS和BitTorrent协议的文件下载工具
例如使用它可以设置UTF8模式:
ftp:use-utf8 (boolean)
if true, lftp sends `OPTS UTF8 ON’ to the server to activate UTF-8 encoding (if supported). Disable it if the file names have a different encoding and the server has a trouble with it.
——引用自man lftp
例子
在以上操作期间抓包:
使用scapy解析抓取的报文可以看到:
其中a=rdpcap(‘lftp.pcap’)
遇到过的问题
lftp not respond to <Ctrl>-Z?
使用suspend命令即可
详情参见#158772 - lftp should respond to <Ctrl>-Z - Debian Bug report logs
ncftp
用户友好的具有丰富特征的FTP客户端
tnftp
在netbsd中被许多用户亲切地称为增强版FTP客户端
FileZilla
很好用的开源的跨平台的带GUI的FTP客户端,支持FTPS,SFTP等协议,适合新手和非专业人士
浏览器
几乎所有的浏览器都支持FTP协议
需要注意的是:2020年11月,谷歌浏览器弃用了对FTP协议的支持。
文件管理器
直接在Windows的文件管理器的地址栏中输入ftp地址即可。例如:ftp://192.168.1.101
修订记录
修订时间 | 修订人 | 版本 | 说明 |
---|---|---|---|
2021-01-07 | wsxq2 | 1.0 | 初稿 |
2021-01-19 | wsxq2 | 2.0 | 修改了目录结构,添加了更多的客户端 |
2021-01-22 | wsxq2 | 2.1 | 将‘遇到过的问题’放到了对应的位置,以便于查找 |