FTP详解及模拟实现一个vsftpd服务器

FTP协议概念:

FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。在开发网站的时候,通常利用FTP协议把网页或程序传到Web服务器上。此外,由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议。
默认情况下FTP协议使用TCP端口中的 20和21这两个端口,其中20用于传输数据,21用于传输控制信息。但是,是否使用20作为传输数据的端口与FTP使用的传输模式有关,如果采用主动模式,那么数据传输端口就是20;如果采用被动模式,则具体最终使用哪个端口要服务器端和客户端协商决定。

FTP工作原理图:

FTP详解及模拟实现一个vsftpd服务器_第1张图片
同大多数Internet服务一样,FTP也是一个客户/服务器系统。用户通过一个客户机程序连接至在远程计算机上运行的服务器程序。依照 FTP 协议提供服务,进行文件传送的计算机就是 FTP服务器,而连接FTP服务器,遵循FTP协议与服务器传送文件的电脑就是FTP客户端。用户要连上FTP 服务器,就要用到 FTP 的客户端软件,通常 Windows自带“ftp”命令,这是一个命令行的 FTP客户程序,另外常用的 FTP 客户程序还有FileZilla、 CuteFTP、Ws_FTP、Flashfxp、LeapFTP等。

Windows与Linux之间建立FTP连接:

如果要使用FTP在Linux和Windows之间进行传输,那么就需要先在Linux中安装vsftpd服务:

  1. 使用sudo apt-get install vsftpd安装vsftpd服务
  2. 使用sudo vi /etc/vsftpd.conf查看vsftpd的配置文件
  3. 编辑配置文件:(需将以下几处语句前的#删除)
// 允许匿名用户登录
anonymous_enable=YES
// 允许本地用户登录
local_enable=YES
// 开启全局上传
write_enable=YES
// 允许匿名用户上传文件
anon_upload_enable=YES  
// 充许匿名用户新建文件夹
anon_mkdir_write_enable=YES
//允许使用ascii格式上传文件
ascii_upload_enable=YES
//允许使用ascii格式下载文件
ascii_download_enable=YES
//空闲断开(空闲时间可自行配置,初始值为600)
idle_session_timeout=60
//客户端最大连接数设置(该项为自行添加)
max_clients=3
//同一IP最大连接数(该项为自行添加)
max_per_ip=2
  1. 使用ps -ef | grep vsftpd查看vsfptd是否启动。如果未启动,使用sudo service vsftpd start启动vsftpd服务,如果成功启动,则使用ps -ef | grep vsftpd可见进程显示如下:
hackt@ubuntu:~$ ps -ef | grep vsftpd
root       4513      1  0 13:39 ?        00:00:00 /usr/sbin/vsftpd /etc/vsftpd.conf
hackt      5638   5609  0 22:40 pts/0    00:00:00 grep --color=auto vsftpd

此处使用LeapFTP举例:(配置的站点地址为Ubuntu18.04.4LTS的IP)
在LeapFTP中选择已经配置好的站点进行连接,如果连接成功,则为下图所示:
FTP详解及模拟实现一个vsftpd服务器_第2张图片
而在Windows的cmd命令行中启动FTP服务器,也会有相同的提示信息,如下图所示:FTP详解及模拟实现一个vsftpd服务器_第3张图片

FTP工作模式:

  1. 主动模式:port(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器从20端口向客户端的空闲端口发送连接请求AA,建立一条数据链路来传送数据。
    命令连接:客户端 >AA端口 ------> 服务器 21端口
    数据连接:客户端 >AA端口 <------ 服务器 20端口
    FTP详解及模拟实现一个vsftpd服务器_第4张图片
  2. 被动模式:pasv(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端向服务器的空闲端口发送连接请求,建立一条数据链路来传送数据
    命令连接:客户端 >1023端口 ------> 服务器 21端口
    数据连接:客户端 >1023端口 ------> 服务器 >1023端口FTP详解及模拟实现一个vsftpd服务器_第5张图片

FTP工作过程:

主动模式:

  1. 客户端向服务器端发送PORT命令
    客户端创建数据套接字
    客户端绑定一个临时端口
    客户端在套接字上监听
    将IP与端口格式化为h1,h2,h3,h4,p1,p2
  2. 服务器端以200响应
    服务器端解析客户端发过来的IP与端口暂存起来,以便后续建立数据连接
  3. 客户端向服务器端发送LIST
    服务器端检测在收到LIST命令之前是否接收过PORT或PASV命令
    如果没有接收过,则响应425 Use PORT or PASV first
    如果有接收过,并且是PORT,则服务器端创建数据套接字(bind 20端口),调用connect主动连接客户端IP与端口,从而建立了数据连接
  4. 服务发送 150应答给客户端,表示准备就绪,可以开始传输
  5. 开始传输列表
  6. 服务器发送226应答给客户端,表示数据传输结束
    传输结束,服务器端主动关闭数据套接字

被动模式:

  1. 客户端向服务器端发送 PASV命令
  2. 服务器端以227响应
    服务器端创建数据套接字
    服务器端绑定一个临时端口
    服务器在套接字上监听
    将IP与端I口格式化为h1,h2.h3,h4,p1,p2响应给客户端,以便客户端发起数据连接
  3. 客户端向服务器端发送 LIST
    服务器端检测在收到LIST命令之前是否接收过PORT或PASV命令
    如果没有接收过,则响应425 Use PORT or PASV first.
    如果有接收过,并且是PASV,则调用accept被动接受客户端的连接,返回已连接套接字,从而建立了数据连接
  4. 服务发送 150应答给客户端, 表示准备就绪,可以开始传输
  5. 开始传输列表
  6. 服务器发送226应答给客户端,表示数据传输结束
    传输结束,客户端主动关闭数据套接字

FTP客户端处于NAT或防火墙之后的主/被动模式

NAT:通过NAT可以将内网私有IP地址转换为公网IP地址
在主动模式下,客户端由于安装了防火墙会产生一些问题;在被动方式下,命令连接和数据连接都由客户端发起,只要求服务器端产生一个监听相应端口的进程,这样就可以解决从服务器到客户端的数据端口的入方向连接被防火墙过滤掉的问题。
FTP客户端处于NAT或防火墙之后,若主动(port)模式必须配置映射规则,否则不一定能连接成功。若被动(PASV)模式,客户端是可以经由NAT连接成功FTP服务器。

FTP服务器设计

对于FTP服务器来说,不允许使用多线程或者I/O复用(一个线程处理多个客户端的连接)实现,因为多个线程是共享同一工作目录的,而多个进程有各自独立的资源,所以采用多进程实现FTP模型。如下图:FTP详解及模拟实现一个vsftpd服务器_第6张图片
服务进程负责与客户端进行交互,而nobody进程则是协助服务进程创建数据连接通道以及需要特殊权限的操作的管理。由此可知nobody进程与服务进程间只是进行了内部通信,所以可以使用socketpair或者pipe进行通信,而不需要TCP/IP。

源代码

链接:https://pan.baidu.com/s/1KuxOgpsFspR65jhd3sfIMQ
提取码:pz2d
(源码改造并手写了一份,但是在PASV下有BUG,所以先上传C++教程网官方代码。在EditPlus中编写,打开Linux虚拟机并在EditPlus中建立FTP连接至Linux,在Linux中编译代码)

你可能感兴趣的:(Linux,socket通信)