本文環境:CentOS 7shell
簡介vim
FTP(文件傳輸協議,File Transfer Protocol)是最古老的協議之一,誕生於1971年,距今已經半個世紀了,它的目的是在不一樣計算機之間傳輸文件(實現跨平臺傳輸),工做於TCP/IP協議的應用層,須要注意的是,FTP以明文方式傳輸。安全
聲明:下文出現的連接是名詞,表示端口到端口之間的虛擬鏈路;而鏈接是動詞,表示創建鏈路的這個動做,鏈接 = 創建連接。bash
工做流程簡介服務器
FTP使用兩個端口同時進行通訊,即控制連接和數據鏈接,它們都基於TCP協議,控制連接端口默認是21,數據連接默認端口是20,控制連接用來傳輸用戶名、密碼、傳輸方式等,而數據鏈接就是用來傳輸真實的文件數據,因此客戶端和服務端都同時運行着控制連接進行和數據鏈接進行,通常而言,客戶端首先向服務器發起控制鏈接請求,服務器的控制連接默認監聽21端口,同時告訴服務器本身的一個空閒端口號,用於以後傳輸數據,而後,服務器經過默認的20端口和客戶機所提供的空閒端口創建起數據連接,至此整個FTP連接所有創建,能夠開始傳輸數據了。ide
默認狀況下,控制連接在整個FTP會話期間一直存在,但數據連接在每次傳輸完文件後會自動斷開,繼續傳文件須要從新創建數據連接。測試
FTP的數據傳輸格式ui
ASCII或BINARY,即以文本方式傳輸仍是以二進制方式傳輸,以文本方式傳輸會自動轉換一些特殊字符,如,Windows向Linux以文本方式傳輸文件下會把CRLF轉爲LF,整個FTP傳輸的過程以字符流或比特流傳輸。spa
服務器應答格式(由三位數字組成)server
第一位數字:
1XX 肯定預備應答:在發送一個命令前期待另外一個命令應答
2XX 肯定完成應答:要求的操做已經完成,能夠接受新的命令了
3XX 肯定中間應答:此命令已被接受,但在處理前,還須要另外一個命令
4XX 暫時拒絕完成應答:請求的命令被拒絕,可是隻是暫時的,能夠稍後重發此命令再次嘗試
5XX 永久拒絕應答:請求的命令被拒絕,而且要求再也不重試
第二位數字:
X0X 語法錯誤
X1X 通常性的解釋信息
X2X 與控制和數據連接有關
X3X 與認證和帳號登入有關
X4X 保留
X5X 與文件系統有關
第三位數字是在第二個數字的基礎上對應答作進一步細化,沒有具體的規定,可是,有些約定成文的常見應答,以下,
125 數據連接已經打開,開始傳輸
200 就緒
214 面向用戶的幫助信息
331 用戶名已接收,等待密碼輸入
425 不能打開數據連接
452 寫文件出錯
500 語法錯誤(未知的命令)
501 語法錯誤(參數錯誤)
數據鏈接的主動和被動
數據連接的創建分爲主動方式和被動方式,具體選擇哪一種方式由客戶端決定,客戶端在上傳或下載文件時要先發送一個PORT或PASV命令,表示採用主動方式仍是被動方式,須要注意的是,主動和被動是相對於服務器而言的:若是數據鏈接由服務器先發起,則爲主動方式;若是數據鏈接由客戶機先發起,則爲被動方式。
主動方式下,客戶端首先經過PORT命令向服務器發送本身的一個空閒端口號(大於1024),而後服務器經過默認的20端口向客戶端提供的端口創建數據連接。
被動方式下,客戶端先向服務器發送PASV命令,服務器會迴應一個它空閒的端口號(定義在主配置文件中的passv_min_port和passv_max_port兩個配置項指定的閉區間),告訴客戶端它將在這個端口監聽來自客戶端的數據連接創建請求,最後,客戶端選擇一個空閒端口(大於1024)向服務器的這個端口創建數據連接。
vsftp服務器端配置
本文以vsftp(very secure ftp)軟件來配置服務器端的FTP服務,著名的Red Hat、SUSE、Debian、GNU等都是使用這款軟件來部署它們的FTP服務器。
第一步:在服務器端安裝vsftpd軟件
有三種安裝方式,編譯源碼安裝、使用RPM包安裝和使用YUM源安裝,這裏使用YUM 源安裝,這種方式安裝前請確保已正確配置YUM源,
[root@localhost ~]# yum -y install vsftpd
第二步:在客戶端安裝ftp軟件
也有三種安裝方式,這裏使用YUM,
[root@localhost ~]# yum -y install ftp
第三步:測試匿名用戶是否能登入
先開啓服務端的vsftp服務,
[root@localhost ~]# systemctl start vsftpd
關閉服務端的防火牆和SELinux,
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
在客戶端輸入「ftp 服務器的地址」進行測試,其中匿名用戶登入的用戶名是anonymous, 密碼能夠爲空,也能夠是任意字符串,
[root@localhost ~]# ftp 192.168.88.128
Connected to 192.168.88.128 (192.168.88.128).
220 (vsFTPd 3.0.2)
Name (192.168.88.128:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
輸入quit命令便可退出ftp回到原來的Shell,
ftp> quit
221 Goodbye.
第三步:配置本地FTP用戶
首先建立一個本地帳戶,
[root@localhost ~]# useradd -s /sbin/nologin -g ftp ftptest1
爲這個用戶配置密碼,這裏密碼設爲123,
[root@localhost ~]# echo 123 | passwd --stdin ftptest1
Changing password for user ftptest1.
passwd: all authentication tokens updated successfully.
回到客戶端,使用以前的方法進行測試,
[root@localhost ~]# ftp 192.168.88.128
Connected to 192.168.88.128 (192.168.88.128).
220 (vsFTPd 3.0.2)
Name (192.168.88.128:root): ftptest1
331 Please specify the password.
Password:
530 Login incorrect.
Login failed.
ftp>
這裏出現了一個問題,即使密碼輸入正確,依舊顯示登入失敗,這時因爲PAM模塊驗 證機制致使的(PAM會阻止那些是nologin shell的用戶登入FTP服務),解決這個問題 有兩個辦法,第一個是建立一個具備登入shell(如bash)的用戶,可是這樣會產生安 全問題,第二個是找到PAM模塊,將其對FTP驗證的功能關閉,這裏使用第二個方法,
[root@localhost ~]# vim /etc/pam.d/vsftpd
而後將包含」pam_shells.so」這行註釋,前面添加#進行註釋,
#auth required pam_shells.so
重啓vsftpd服務,而後再回到客戶端繼續嘗試登入,
[root@localhost ~]# ftp 192.168.88.128
Connected to 192.168.88.128 (192.168.88.128).
220 (vsFTPd 3.0.2)
Name (192.168.88.128:root): ftptest1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
登入成功,使用pwd命令查看所在的FTP服務器的路徑,
ftp> pwd
257 "/home/ftptest1"
發現能夠查看到完整路徑名(從根開始),這是很不安全的
第四步:限定用戶的登入目錄
找到vsftpd的主配置文件並打開,
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
將其中的」#chroot_local_user=YES」取消註釋,而後重啓服務,再去客戶端登入,
[root@localhost ~]# ftp 192.168.88.128
Connected to 192.168.88.128 (192.168.88.128).
220 (vsFTPd 3.0.2)
Name (192.168.88.128:root): ftptest1
331 Please specify the password.
Password:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
Login failed.
421 Service not available, remote server has closed connection
ftp>
又出現錯誤了,大體意思是:拒絕一個帶有寫權限的根目錄,爲何呢?這是由於vsftp 是一個很安全的FTP服務軟件,因此,若是一個用戶的登入目錄被限制了,那麼他的登 入目錄不該該再有寫的權限,咱們來看看ftptest1的登入目錄(也就是他的家目錄),
[root@localhost ~]# ll -d /home/ftptest1/
drwx------. 2 ftptest1 ftp 62 Dec 18 15:11 /home/ftptest1/
能夠發現,ftptest1確實對他本身的家目錄有寫的權限,怎麼解決呢?也有兩個解決方 法,第一個是使用chmod命令將這個目錄的寫權限去掉,第二個是修改主配置文件, 這裏選擇第二個方法,在主配置文件中添加下行,
allow_writeable_chroot=YES
而後重啓服務,
[root@localhost ~]# ftp 192.168.88.128
Connected to 192.168.88.128 (192.168.88.128).
220 (vsFTPd 3.0.2)
Name (192.168.88.128:root): ftptest1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp>
問題成功解決,而且用戶的登入已經被限制了
第五步:FTP黑名單
vsftpd存在一個全局黑名單,是/etc/vsftpd/ftpusers,將用戶添加到這個文件(每一個用戶 名佔一行),那麼,即使用戶輸對了密碼,也提示密碼錯誤,除了這個黑名單,vsftpd 還存在另外一個黑名單,是/etc/vsftpd/user_list(也是每一個用戶佔一行),開啓這個黑名單 須要修改主配置文件,確保userlist_enable的值是YES,以下,
userlist_enable=YES
位於user_list文件中的用戶,一旦輸入用戶名,直接被拒絕,連輸入密碼的機會都沒有, 更新user_list或ftpusers都不須要重啓vsftpd服務。
第六步:上傳和下載
先將上一步中的ftptest1用戶從全局黑名單和user_list黑名單中移除,而後在這個用戶 的登入目錄新建一個文件夾爲pub,權限爲777,做爲共用目錄,
[root@localhost ~]# mkdir /home/ftptest1/pub
[root@localhost ~]# chmod 777 /home/ftptest1/pub/
[root@localhost ~]# ll -d /home/ftptest1/pub/
drwxrwxrwx. 2 root root 6 Dec 18 15:40 /home/ftptest1/pub/
而後在這個目錄裏面建立一個文件,用於客戶端的下載,
[root@localhost ~]# echo "hello I am from vsftpd" > /home/ftptest1/pub/readme.txt
回到客戶端,在/tmp下建立一個文件,用於上傳,
[root@localhost ~]# echo "2019" > /tmp/example.txt
打開ftp,鏈接到服務器,查看、下載到客戶端的tmp目錄和上傳到服務器的pub目錄,
[root@localhost ~]# ftp 192.168.88.128
Connected to 192.168.88.128 (192.168.88.128).
220 (vsFTPd 3.0.2)
Name (192.168.88.128:root): ftptest1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp> ls
227 Entering Passive Mode (192,168,88,128,51,1).
150 Here comes the directory listing.
drwxrwxrwx 2 0 0 24 Dec 18 20:46 pub
226 Directory send OK.
ftp> cd pub
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,88,128,102,108).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 23 Dec 18 20:41 readme.txt
226 Directory send OK.
ftp> get readme.txt /tmp/readme.txt
local: /tmp/readme.txt remote: readme.txt
227 Entering Passive Mode (192,168,88,128,160,11).
150 Opening BINARY mode data connection for readme.txt (23 bytes).
226 Transfer complete.
23 bytes received in 9.7e-05 secs (237.11 Kbytes/sec)
ftp> put /tmp/example.txt /pub/example.txt
local: /tmp/example.txt remote: /pub/example.txt
227 Entering Passive Mode (192,168,88,128,209,58).
150 Ok to send data.
226 Transfer complete.
5 bytes sent in 0.000344 secs (14.53 Kbytes/sec)
ftp> ls
227 Entering Passive Mode (192,168,88,128,67,163).
150 Here comes the directory listing.
-rw-r--r-- 1 1001 50 5 Dec 18 20:50 example.txt
-rw-r--r-- 1 0 0 23 Dec 18 20:41 readme.txt
226 Directory send OK.
ftp> quit
221 Goodbye.
至此,基本的vsftpd服務的配置已經完成!