1.ftp协议介绍
ftp协议是工作于TCP/IP模型中的应用层,基于的传输协议是TCP。FTP客户端和服务端之间的连接是可靠的和双重的,为数据的传输提供保证。之所以是双重连接,因为FTP是一个会话交互系统,客户端每次调用FTP服务端,都会建立控制连接的会话,以发送控制命令,客户端每发起一次传数据文件的请求,会跟FTP服务端建立一个数据连接的会话,以传送实际的数据文件。当数据文件传输结束,关闭数据连接,还可以通过控制连接进行发送命令。
- ftp主动模式和被动模式
FTP协议之wikipediaftp是client-server架构模型,client和server之间建立单独的控制连接和数据连接。FTP可以运行在active主动模式或passive被动模式,运行的模式决定ftp如何建立数据连接。
主动模式和被动模式的区别是什么?
二者在控制连接过程都是一样的,在数据连接时不一样:主动模式下是服务端主动连接客户端以建立数据连接;被动模式下是服务端被动的,由客户端连接服务端以建立数据连接。
主动模式和被动模式的使用场景
-
当ftp服务器能力比较弱时,ftp客户端可以采用被动模式。
-
ftp服务器不支持主动模式或被动模式,那么ftp客户端只能采用被动或主动模式。
-
针对客户端firewall场景,当ftp服务端主动连接客户端的某个数据端口被防火墙firewall过滤的问题,ftp客户端可以采用被动模式。
-
针对NAT场景,当服务端主动连接客户端的某个端口时,发送port命令中包含的端口和ip地址,需要转换为内部的ip和端口而不是公共的ip和端口号,ftp客户端可以采用被动模式。另外一种方法是需要一个application-level gateway来为NAT进行转换为内部的IP和端口,此时也可以使用主动模式。
被动模式和主动模式的实现过程
FTP服务端运行(FTP服务开启),服务器上有“主服务进程”运行,即服务器发布一个服务,比如端口是21,用户名和密码为11/22。
被动模式下,FTP交互的过程如下:
-
ftp客户端先启动一个socket控制进程,打开客户端的某个端口,访问ftp服务端的21端口。客户端用TCP和指定主机上的ftp服务器之间建立控制连接。
-
ftp服务端主进程收到请求后,派生出来一个服务端控制进程,和客户端控制进程之间建立控制连接,开始会话。
-
ftp客户端和ftp服务端之间通过各自的控制进程进行用户名和密码校验等操作。
-
当ftp客户端要发起数据文件传输时,ftp客户端控制进程向服务端控制进程发起pasv命令。
-
ftp服务端控制进程收到pasv请求后,派生出来一个数据传输进程,并将端口号告知客户端控制进程,返回227 entering passive mode (h1,h2,h3,h4,p1,p2),其中端口号是 p1*256+p2,ip 地址为h1.h2.h3.h4。
-
ftp客户端控制进程收到响应后,派生出来一个客户端数据传输进程,随机产生一个客户端数据传输端口,连接服务端的数据传输端口号,然后进行数据文件传输。
-
当数据传输完毕,服务端数据传输进程返回传输完毕,数据连接通道会关闭,保留控制连接通道。
-
如果此时没有其他文件传输,控制通道也会相继关闭。
主动模式下,FTP交互的过程如下:
除了被动模式的4),5),6)步骤不一样外,其余都一样。
-
当ftp客户端要发起数据文件传输时,客户端派生出一个数据传输进程,并通过客户端控制进程将用于数据连接的客户端端口port告知服务端控制进程。
-
当ftp服务端收到请求后,派生出一个服务端数据传输进程,产生一个服务端端口号,然后根据请求中ftp客户端数据传输过来的端口号建立数据传输连接。
-
ftp客户端收到服务端的响应后,进行数据文件的传输。
问题反思:
- 每传输一个文件会建立一个数据传输连接还是共用一个数据连接?-看第6部分抓包分析可知答案。
3.ftp传输方式/文件类型/数据结构
文件类型: NVT ASCII码,EBCDIC(要求客户端服务端都是EBCDIC系统),图像文件(数据发送呈现连续的比特流),local模式(服务端和客户端之间协商)。
数据结构:文件结构(字节流),记录结构(文本文件),页结构(文件被划分为页,随机读取或顺序存放)。
传输方式:流模式(数据以字节流形式传送,适用于记录结构和文件结构),块模式(以块的形式传送,块带有自己的头部,头字节包括16位计数域和8位描述子代码),压缩模式。
4.ftp控制命令和响应码
控制连接:NVT ASCII
数据连接:文件类型、数据结构、传输方式
ftp控制命令和响应都是以nvt ascii形式传送,每行结尾都要CR、LF对。
常用命令(从ftp登录到退出过程):
USER 系统登录用户名
PASS 系统登录的密码
TYPE 文件类型(A=ASCII,E=EBCDIC,I=binary)
STRU 数据结构(F=file,R=record,P=Page)
MODE 传输模式
PASV 等待数据连接的请求
PORT
IP地址和两个字节的端口idCWD 改变服务器上的工作目录
LIST 列出显示的文件和目录
PWD 显示当前工作目录
RETR 从server下载文件到client
REST 由特定偏移量重启文件传递
STOR 上传文件到服务器
STOU 上传文件到服务器(不覆盖同名文件)
ACCT 系统优先级
DELETE 删除服务器上指定文件
RMD 在服务器上删除指定目录
MKD 在服务器上建立指定目录
QUIT 从ftp服务器退出登录
常用响应码(从ftp登录到退出过程):
332 需要账号名 331 用户名有效,需要密码
230登录成功 530登录失败
200 成功
227 进入被动模式(发送IP和端口号)
220 服务器准备就绪 421关闭服务器
225 数据连接打开 425 不能打开数据连接
226 数据连接关闭
452磁盘空间不足 552 超过分配的存储空间
426结束连接
500无效命令 504无效命令参数
501 错误参数 502命令未执行
125 数据连接已打开,在短时间内开始传输
120在短时间内服务器准备就绪
250 完成的文件行为
257 当前的路径名 550不可用的文件
553 不允许的文件名 551不知道的页类型
- ftp客户端和服务端的编程步骤
Socket 客户端编程主要步骤如下:
-
socket() 创建一个 Socket(控制和数据)
-
connect() 与服务器连接(控制和数据)
-
listen() 监听 (主动模式下)
-
write() 和 read() 进行会话
-
close() 关闭 Socket(控制和数据)
Socket 服务器端编程主要步骤如下:
-
socket() 创建一个 Socket(控制和数据)
-
bind()
-
listen() 监听
-
accept() 接收连接的请求
-
write() 和 read() 进行会话
-
close() 关闭 Socket(控制和数据)
- 抓包分析(被动和主动模式)
被动模式抓包分析(ftp客户端默认为被动)
ftp客户端:192.168.0.102
ftp服务端:192.168.0.100,端口2121,用户名和密码都是ftp。
ftp控制连接
首先控制连接在TCP三次握手结束后,ftp服务器响应220表明服务端已经准备就绪(ftp客户端控制连接的端口号62463,服务端控制连接的端口号2121)。
然后是客户端通过控制连接发送auth tls和ssl鉴权命令,服务端响应502表明未执行命令(因不是sftp,所以没有执行ssl鉴权命令)。
客户端通过控制连接发送USER ftp命令,服务端响应331(表明用户有效,需要密码)。客户端继续发送PASS ftp命令,服务端230表明ftp登录成功。
客户端通过控制连接发送SYST命令获取服务器操作系统,服务端返回UNIX type:L8。
客户端通过控制连接发送FEAT命令,服务端返回211(系统状态回复)表明ftp服务端支持扩展命令(FEAT命令是用来请求FTP服务器列出它的所有的扩展命令与扩展功能的,属于主动模式命令,被动模式慎用,如果服务端不支持呢!)客户端没有发任何信息,服务端回复UTF8 MDTM MEMT 211END。
客户端通过控制连接发送OPTS UTF8 on命令,服务端响应200(表明OPTS成功)(OPTS为特性选择项,解决服务端目录乱码问题)。
客户端通过控制连接发送PWD命令,服务端响应257显示当前路径名称“/”。
客户端通过控制连接发送TYPE I命令,服务端响应200(表明客户端和服务端以二进制传输设置成功)。
客户端通过控制连接发送PASV命令,服务端响应227(表面服务端进入被动模式),ip和端口号53093。
ftp数据连接
客户端通过控制连接发送LIST命令,客户端和服务端之间的数据连接在进行三次握手后(端口号62464和53093),服务端控制连接响应150(文件OK,短时间内将关闭数据连接)(表明服务端开启二进制传输文件列表模式)。然后服务端通过数据连接(端口53093向62464)。文件传输成功后服务端通过控制连接响应226表明数据连接短时间内传输完毕并关闭。
客户端通过控制连接发送MDTM命令,服务端响应213 20171211135455(服务端返回文件最终修改时间)(213是文件系统回复)。
cwd切换目录
客户端通过控制连接发送CWD backup命令,服务端响应250(完成目录切换行为)。客户端ftp要求显示当前路径,发送PWD,服务端响应257响应当前路径名。
客户端通过控制连接发起pasv命令,服务端响应227(服务端数据连接的端口号为51785)。客户端控制连接发送list命令,客户端和服务端又一次TCP三次握手建立数据连接(端口号62467和51785),服务端控制连接响应150(短时间内开启数据连接)开启二进制模式进行列表显示。服务端通过数据连接51785向客户端数据连接62467发送文件列表。
ftp上传文件建立连接
客户端通过控制连接(62470和62469)发起2次pasv命令(网络有环路),服务端响应2次227(服务端数据连接的端口号为42131-对应客户端控制连接的62470,服务端数据连接58968对应客户端控制连接62469)。
客户端通过数据连接62470向服务端控制连接2121发送STOR ping.png。数据连接62469也向服务端控制连接2121发送STOR ping2.png。客户端和服务端之间通过TCP三次握手建立2个数据连接(62475-42131,62476-58968)。然后开始文件传输。
ftp上传图片
文件传输成功后,服务端控制连接2121分别向客户端控制连接62470和62469响应150数据传输(数据连接短时间内开启)。然后通过建立的2个数据连接进行传输数据,当传输完毕,服务端控制连接2121会分别向客户端控制连接62470和62469响应226数据传输完毕。
控制连接断开没有抓到包(手工关闭ftp,没有看到quit的命令)。
主动模式抓包(仅解介绍和被动模式不一样的地方)
ftp客户端:192.168.0.102
ftp服务端:192.168.0.101,端口2121,用户名和密码都是ftp。
ftp客户端(fileZilla)设置为主动模式,如下
Ftp客户端设置为主动模式
客户端通过控制连接51321向服务端控制连接2121发送PORT 192.168.0.102,200,122命令,服务端控制连接响应200(进入主动模式)。
ftp主动模式
客户端通过控制连接发起list命令,服务端和客户端又一次TCP三次握手建立数据连接(服务端数据连接51436和客户端数据连接51322)。服务端响应150(短时间开启数据连接)开启二进制传输文件列表。服务端通过数据连接进行传输文件列表。