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工作原理圖:

在這裏插入圖片描述
同大多數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中選擇已經配置好的站點進行連接,如果連接成功,則爲下圖所示:
在這裏插入圖片描述
而在Windows的cmd命令行中啓動FTP服務器,也會有相同的提示信息,如下圖所示:在這裏插入圖片描述

FTP工作模式:

  1. 主動模式:port(主動)方式的連接過程是:客戶端向服務器的FTP端口(默認是21)發送連接請求,服務器接受連接,建立一條命令鏈路。當需要傳送數據時,服務器從20端口向客戶端的空閒端口發送連接請求AA,建立一條數據鏈路來傳送數據。
    命令連接:客戶端 >AA端口 ------> 服務器 21端口
    數據連接:客戶端 >AA端口 <------ 服務器 20端口
    在這裏插入圖片描述
  2. 被動模式:pasv(被動)方式的連接過程是:客戶端向服務器的FTP端口(默認是21)發送連接請求,服務器接受連接,建立一條命令鏈路。當需要傳送數據時,客戶端向服務器的空閒端口發送連接請求,建立一條數據鏈路來傳送數據
    命令連接:客戶端 >1023端口 ------> 服務器 21端口
    數據連接:客戶端 >1023端口 ------> 服務器 >1023端口在這裏插入圖片描述

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模型。如下圖:在這裏插入圖片描述
服務進程負責與客戶端進行交互,而nobody進程則是協助服務進程創建數據連接通道以及需要特殊權限的操作的管理。由此可知nobody進程與服務進程間只是進行了內部通信,所以可以使用socketpair或者pipe進行通信,而不需要TCP/IP。

源代碼

鏈接:https://pan.baidu.com/s/1KuxOgpsFspR65jhd3sfIMQ
提取碼:pz2d
(源碼改造並手寫了一份,但是在PASV下有BUG,所以先上傳C++教程網官方代碼。在EditPlus中編寫,打開Linux虛擬機並在EditPlus中建立FTP連接至Linux,在Linux中編譯代碼)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章