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服務的許多站點都開放匿名服務,在這種設置下,用戶不需要帳號就可以登錄服務器,默認情況下,匿名用戶的用戶名是:“anonymous”。
支持網頁瀏覽器和文件管理器
大多數最新的網頁瀏覽器和文件管理器都能和FTP服務器創建連接。這使得在FTP上通過一個接口就可以操控遠程文件,如同操控本地文件一樣。這個功能通過給定一個FTP的URL實現,形如ftp://<服務器地址>(例如,ftp://ftp.gimp.org )。是否提供密碼是可選擇的,如果有密碼,則形如ftp://<login>:<password>@<ftpserveraddress>。大部分網頁瀏覽器要求使用被動FTP模式,然而并不是所有的FTP服務器都支持被動模式。
FTP狀態碼:
1xx-肯定的初步答復這些狀態代碼指示一項操作已經成功開始,但客戶端希望在繼續操作新命令前得到另一個答復。
110重新啟動標記答復。
120服務已就緒,在nnn分鐘后開始。
125數據連接已打開,正在開始傳輸。
150文件狀態正常,準備打開數據連接。
2xx-肯定的完成答復一項操作已經成功完成。客戶端可以執行新命令。
200命令確定。
202未執行命令,站點上的命令過多。
211系統狀態,或系統幫助答復。
212目錄狀態。
213文件狀態。
214幫助消息。
215NAME系統類型,其中,NAME是AssignedNumbers文檔中所列的正式系統名稱。
220服務就緒,可以執行新用戶的請求。
221服務關閉控制連接。如果適當,請注銷。
225數據連接打開,沒有進行中的傳輸。
226關閉數據連接。請求的文件操作已成功(例如,傳輸文件或放棄文件)。
227進入被動模式(h1,h2,h3,h4,p1,p2)。
230用戶已登錄,繼續進行。
250請求的文件操作正確,已完成。
257已創建“PATHNAME”。
3xx-肯定的中間答復該命令已成功,但服務器需要更多來自客戶端的信息以完成對請求的處理。
331用戶名正確,需要密碼。
332需要登錄帳戶。
350請求的文件操作正在等待進一步的信息。
4xx-瞬態否定的完成答復該命令不成功,但錯誤是暫時的。如果客戶端重試命令,可能會執行成功。
421服務不可用,正在關閉控制連接。如果服務確定它必須關閉,將向任何命令發送這一應答。
425無法打開數據連接。 426Connectionclosed;transferaborted.
450未執行請求的文件操作。文件不可用(例如,文件繁忙)。
451請求的操作異常終止:正在處理本地錯誤。
452未執行請求的操作。系統存儲空間不夠。
5xx-永久性否定的完成答復該命令不成功,錯誤是永久性的。如果客戶端重試命令,將再次出現同樣的錯誤。
500語法錯誤,命令無法識別。這可能包括諸如命令行太長之類的錯誤。
501在參數中有語法錯誤。
502未執行命令。
503錯誤的命令序列。
504未執行該參數的命令。
530未登錄。
532存儲文件需要帳戶。
550未執行請求的操作。文件不可用(例如,未找到文件,沒有訪問權限)。
551請求的操作異常終止:未知的頁面類型。
552請求的文件操作異常終止:超出存儲分配(對于當前目錄或數據集)。
553未執行請求的操作。不允許的文件名。
常見的FTP狀態代碼及其原因:
150-FTP使用兩個端口:21用于發送命令,20用于發送數據。
狀態代碼150表示服務器準備在端口20上打開新連接,發送一些數據。
226-命令在端口20上打開數據連接以執行操作,如傳輸文件。該操作成功完成,數據連接已關閉。
230-客戶端發送正確的密碼后,顯示該狀態代碼。它表示用戶已成功登錄。
331-客戶端發送用戶名后,顯示該狀態代碼。無論所提供的用戶名是否為系統中的有效帳戶,都將顯示該狀態代碼。
426-命令打開數據連接以執行操作,但該操作已被取消,數據連接已關閉。
530-該狀態代碼表示用戶無法登錄,因為用戶名和密碼組合無效。如果使用某個用戶帳戶登錄,可能鍵入錯誤的用戶名或密碼,也可能選擇只允許匿名訪問。如果使用匿名帳戶登錄,IIS的配置可能拒絕匿名訪問。
550-命令未被執行,因為指定的文件不可用。例如,要GET的文件并不存在,或試圖將文件PUT到您沒有寫入權限的目錄。
常見的Ftp服務器:
linux:vsftp,FileZilla Server...
Windows:Server-U,FileZilla Server....
Ftp有兩種工作模式:PORT 和 Passive
-
主動模式
ftp> put issue
local: issue remote: issue
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
29 bytes sent in 0.00 secs (480.0053 kB/s)
ftp>
22:33:38.185125 IP (tos 0x10, ttl 64, id 34867, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.106.53614 > 192.168.2.10.21: Flags [P.], cksum 0x8fa2 (correct), seq 30:38, ack 97, win 229, options [nop,nop,TS val 2979868386 ecr 6094179], length 8: FTP, length: 8
TYPE I "客戶端通知進入 二進制模式 ===Type set to A表示的是字符模式;Type set to I表示的是二進制模式"
22:33:38.185286 IP (tos 0x0, ttl 64, id 3837, offset 0, flags [DF], proto TCP (6), length 83)
192.168.2.10.21 > 192.168.2.106.53614: Flags [P.], cksum 0x860a (incorrect -> 0xbd0a), seq 97:128, ack 38, win 227, options [nop,nop,TS val 6122503 ecr 2979868386], length 31: FTP, length: 31
200 Switching to Binary mode. "服務器通知,已切換到二進制模式"
22:33:38.185605 IP (tos 0x10, ttl 64, id 34868, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.53614 > 192.168.2.10.21: Flags [.], cksum 0xf2d7 (correct), ack 128, win 229, options [nop,nop,TS val 2979868387 ecr 6122503], length 0
22:33:38.185864 IP (tos 0x10, ttl 64, id 34869, offset 0, flags [DF], proto TCP (6), length 80)
192.168.2.106.53614 > 192.168.2.10.21: Flags [P.], cksum 0x3eda (correct), seq 38:66, ack 128, win 229, options [nop,nop,TS val 2979868387 ecr 6122503], length 28: FTP, length: 28
PORT 192,168,2,106,220,251 "客戶端通知服務器自己打開的端口 是 200*256+251=56571"
22:33:38.185946 IP (tos 0x0, ttl 64, id 3838, offset 0, flags [DF], proto TCP (6), length 103)
192.168.2.10.21 > 192.168.2.106.53614: Flags [P.], cksum 0x861e (incorrect -> 0x475d), seq 128:179, ack 66, win 227, options [nop,nop,TS val 6122503 ecr 2979868387], length 51: FTP, length: 51
200 PORT command successful. Consider using PASV. "服務器回復:PORT命令成功。考慮使用PASV"
22:33:38.186495 IP (tos 0x10, ttl 64, id 34870, offset 0, flags [DF], proto TCP (6), length 64)
192.168.2.106.53614 > 192.168.2.10.21: Flags [P.], cksum 0x3981 (correct), seq 66:78, ack 179, win 229, options [nop,nop,TS val 2979868388 ecr 6122503], length 12: FTP, length: 12
STOR issue "客戶端發送命令: 儲存 issue"
"=====服務端使用21端口發起=====三次握手========="
22:33:38.186943 IP (tos 0x0, ttl 64, id 29344, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.10.20 > 192.168.2.106.56571: Flags [S], cksum 0x85f3 (incorrect -> 0xb801), seq 806100648, win 29200, options [mss 1460,sackOK,TS val 6122504 ecr 0,nop,wscale 7], length 0
22:33:38.187434 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.106.56571 > 192.168.2.10.20: Flags [S.], cksum 0x7ad8 (correct), seq 4031212861, ack 806100649, win 28960, options [mss 1460,sackOK,TS val 2979868389 ecr 6122504,nop,wscale 7], length 0
22:33:38.187448 IP (tos 0x0, ttl 64, id 29345, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.10.20 > 192.168.2.106.56571: Flags [.], cksum 0x85eb (incorrect -> 0x19df), ack 1, win 229, options [nop,nop,TS val 6122505 ecr 2979868389], length 0
22:33:38.187604 IP (tos 0x0, ttl 64, id 3839, offset 0, flags [DF], proto TCP (6), length 74)
"==========三次握手完成========="
192.168.2.10.21 > 192.168.2.106.53614: Flags [P.], cksum 0x8601 (incorrect -> 0xe02d), seq 179:201, ack 78, win 227, options [nop,nop,TS val 6122505 ecr 2979868388], length 22: FTP, length: 22
150 Ok to send data. "服務器通知客戶端可以發數據了"
22:33:38.188605 IP (tos 0x8, ttl 64, id 62609, offset 0, flags [DF], proto TCP (6), length 81)
192.168.2.106.56571 > 192.168.2.10.20: Flags [P.], cksum 0x0854 (correct), seq 1:30, ack 1, win 227, options [nop,nop,TS val 2979868389 ecr 6122505], length 29
22:33:38.188618 IP (tos 0x8, ttl 64, id 62610, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.56571 > 192.168.2.10.20: Flags [F.], cksum 0x19c3 (correct), seq 30, ack 1, win 227, options [nop,nop,TS val 2979868389 ecr 6122505], length 0
22:33:38.188722 IP (tos 0x8, ttl 64, id 29346, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.10.20 > 192.168.2.106.56571: Flags [.], cksum 0x85eb (incorrect -> 0x19c1), ack 30, win 229, options [nop,nop,TS val 6122506 ecr 2979868389], length 0
22:33:38.188840 IP (tos 0x8, ttl 64, id 29347, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.10.20 > 192.168.2.106.56571: Flags [F.], cksum 0x85eb (incorrect -> 0x19bf), seq 1, ack 31, win 229, options [nop,nop,TS val 6122506 ecr 2979868389], length 0
22:33:38.189178 IP (tos 0x8, ttl 64, id 62611, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.56571 > 192.168.2.10.20: Flags [.], cksum 0x19c0 (correct), ack 2, win 227, options [nop,nop,TS val 2979868390 ecr 6122506], length 0
22:33:38.189319 IP (tos 0x0, ttl 64, id 3840, offset 0, flags [DF], proto TCP (6), length 76)
192.168.2.10.21 > 192.168.2.106.53614: Flags [P.], cksum 0x8603 (incorrect -> 0x234e), seq 201:225, ack 78, win 227, options [nop,nop,TS val 6122507 ecr 2979868388], length 24: FTP, length: 24
226 Transfer complete. "到此,傳輸完成"
22:33:38.189578 IP (tos 0x10, ttl 64, id 34871, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.53614 > 192.168.2.10.21: Flags [.], cksum 0xf248 (correct), ack 225, win 229, options [nop,nop,TS val 2979868391 ecr 6122505], length 0
-
被動模式
ftp> put issue
local: issue remote: issue
227 Entering Passive Mode (192,168,2,10,204,61).
150 Ok to send data.
226 Transfer complete.
29 bytes sent in 0.00 secs (449.5288 kB/s)
ftp>
23:08:14.730673 IP (tos 0x10, ttl 64, id 40034, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.106.54150 > 192.168.2.10.21: Flags [P.], cksum 0x8964 (correct), seq 42:50, ack 210, win 229, options [nop,nop,TS val 2981944932 ecr 8182778], length 8: FTP, length: 8
TYPE I "客戶端通知進入 二進制模式 ===Type set to A表示的是字符模式;Type set to I表示的是二進制模式"
23:08:14.730825 IP (tos 0x0, ttl 64, id 36152, offset 0, flags [DF], proto TCP (6), length 83)
192.168.2.10.21 > 192.168.2.106.54150: Flags [P.], cksum 0x860a (incorrect -> 0xe5e2), seq 210:241, ack 50, win 227, options [nop,nop,TS val 8199048 ecr 2981944932], length 31: FTP, length: 31
200 Switching to Binary mode. "服務器通知,已切換到二進制模式"
23:08:14.731163 IP (tos 0x10, ttl 64, id 40035, offset 0, flags [DF], proto TCP (6), length 58)
192.168.2.106.54150 > 192.168.2.10.21: Flags [P.], cksum 0x6b01 (correct), seq 50:56, ack 241, win 229, options [nop,nop,TS val 2981944932 ecr 8199048], length 6: FTP, length: 6
PASV "客戶端通知使用passive模式"
23:08:14.731321 IP (tos 0x0, ttl 64, id 36153, offset 0, flags [DF], proto TCP (6), length 102)
192.168.2.10.21 > 192.168.2.106.54150: Flags [P.], cksum 0x861d (incorrect -> 0x97f4), seq 241:291, ack 56, win 227, options [nop,nop,TS val 8199049 ecr 2981944932], length 50: FTP, length: 50
227 Entering Passive Mode (192,168,2,10,204,61). "服務器通知進入Passive模式,端口為:204*256*61=52285"
"=====客戶端發起對服務器開啟端口的=====三次握手========="
23:08:14.731819 IP (tos 0x0, ttl 64, id 35548, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.106.49672 > 192.168.2.10.52285: Flags [S], cksum 0x1608 (correct), seq 208867143, win 29200, options [mss 1460,sackOK,TS val 2981944933 ecr 0,nop,wscale 7], length 0
23:08:14.731840 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.2.10.52285 > 192.168.2.106.49672: Flags [S.], cksum 0x85f3 (incorrect -> 0xe8d9), seq 614067565, ack 208867144, win 28960, options [mss 1460,sackOK,TS val 8199049 ecr 2981944933,nop,wscale 7], length 0
23:08:14.732221 IP (tos 0x0, ttl 64, id 35549, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.49672 > 192.168.2.10.52285: Flags [.], cksum 0x87e1 (correct), ack 1, win 229, options [nop,nop,TS val 2981944933 ecr 8199049], length 0
23:08:14.732239 IP (tos 0x10, ttl 64, id 40036, offset 0, flags [DF], proto TCP (6), length 64)
"==========三次握手完成========="
192.168.2.106.54150 > 192.168.2.10.21: Flags [P.], cksum 0x6270 (correct), seq 56:68, ack 291, win 229, options [nop,nop,TS val 2981944933 ecr 8199049], length 12: FTP, length: 12
STOR issue "客戶端發送命令: 儲存 issue"
23:08:14.732644 IP (tos 0x0, ttl 64, id 36154, offset 0, flags [DF], proto TCP (6), length 74)
192.168.2.10.21 > 192.168.2.106.54150: Flags [P.], cksum 0x8601 (incorrect -> 0x091e), seq 291:313, ack 68, win 227, options [nop,nop,TS val 8199050 ecr 2981944933], length 22: FTP, length: 22
150 Ok to send data. "服務器通知客戶端可以發數據了"
23:08:14.732927 IP (tos 0x8, ttl 64, id 35550, offset 0, flags [DF], proto TCP (6), length 81)
192.168.2.106.49672 > 192.168.2.10.52285: Flags [P.], cksum 0x7653 (correct), seq 1:30, ack 1, win 229, options [nop,nop,TS val 2981944934 ecr 8199049], length 29
23:08:14.732967 IP (tos 0x8, ttl 64, id 35551, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.49672 > 192.168.2.10.52285: Flags [F.], cksum 0x87c2 (correct), seq 30, ack 1, win 229, options [nop,nop,TS val 2981944934 ecr 8199049], length 0
23:08:14.733044 IP (tos 0x8, ttl 64, id 63204, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.10.52285 > 192.168.2.106.49672: Flags [.], cksum 0x85eb (incorrect -> 0x87c4), ack 30, win 227, options [nop,nop,TS val 8199050 ecr 2981944934], length 0
23:08:14.733234 IP (tos 0x8, ttl 64, id 63205, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.10.52285 > 192.168.2.106.49672: Flags [F.], cksum 0x85eb (incorrect -> 0x87c1), seq 1, ack 31, win 227, options [nop,nop,TS val 8199051 ecr 2981944934], length 0
23:08:14.734445 IP (tos 0x8, ttl 64, id 35552, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.49672 > 192.168.2.10.52285: Flags [.], cksum 0x87be (correct), ack 2, win 229, options [nop,nop,TS val 2981944935 ecr 8199051], length 0
23:08:14.734821 IP (tos 0x0, ttl 64, id 36155, offset 0, flags [DF], proto TCP (6), length 76)
192.168.2.10.21 > 192.168.2.106.54150: Flags [P.], cksum 0x8603 (incorrect -> 0x4c3e), seq 313:337, ack 68, win 227, options [nop,nop,TS val 8199052 ecr 2981944933], length 24: FTP, length: 24
226 Transfer complete. "到此,傳輸完成"
23:08:14.735454 IP (tos 0x10, ttl 64, id 40037, offset 0, flags [DF], proto TCP (6), length 52)
192.168.2.106.54150 > 192.168.2.10.21: Flags [.], cksum 0x1b38 (correct), ack 337, win 229, options [nop,nop,TS val 2981944937 ecr 8199050], length 0
這里存在一些問題:
如果使用主動模式,那么服務器會去主動連接客戶端打開的隨機端口,但如果有防火墻這將是不會允許的
如果使用被動模式,那么服務器端的防火墻又應該如何設置?
以下是ftp被動模式iptables規則
一、默認策略為ACCEPT
[root@centos6 ~]# modprobe nf_conntrack_ftp
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@centos6 ~]# iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
[root@centos6 ~]# iptables -A INPUT -j DROP
二、默認策略為DROP
[root@centos6 ~]# modprobe nf_conntrack_ftp
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
[root@centos6 ~]# iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
[root@centos6 ~]# iptables -P INPUT DROP
[root@centos6 ~]# iptables -P OUTPUT DROP
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT #在INPUT鏈上放行ftp命令端口
[root@centos6 ~]# iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT #在INPUT鏈上放行ftp數據端口
[root@centos6 ~]# iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT #在OUTPUT鏈上放行ftp連接,只要是已建立的連接都放行
如果防火墻只開啟了21、20端口,又沒有權限修改,又如何處理呢?可不可以將passive的數據端口限定在20呢?
測試后發現,vsftp的passive模式只能打開1024之上的端口,這樣就只能在客戶端設置使用主動模式連接了
在Centos 中使用的ftp服務器為vsftp
了解了Ftp的兩種工作模式,下面來看看關于授權的問題
所有的網絡共享服務用戶的最終權限都取決于服務程序開放的權限和文件系統權限的交集
- 用戶
系統用戶
系統中passwd文件中存在的用戶
在系統中直接使用useradd添加的用戶
/etc/pam.d/vsftpd 控制用戶登陸驗證匿名用戶
anonymous,用戶不用提供用戶名就能訪問,最終會映射到ftp用戶
/etc/pam.d/vsftpd 控制用戶登陸驗證虛擬用戶
使用獨立的賬號和密碼數據庫來驗證,最終也會映射到一個系統用戶
需要使用自建一套pam來驗證
相關的配置項
系統用戶
系統用戶登陸后,進入家目錄,默認可以訪問有限制的整個文件系統,使用chroot可以將其限制在"家目錄"中
================================
ftp> pwd
257 "/home/test"
===============================
chroot_local_user=YES # 是否所有的系統用戶登陸都chroot
chroot_list_enable=YES # 使用控制列表文件來指定哪些用戶需要chroot(和chroot_local_user 不同時使用)
chroot_list_file=/etc/vsftpd/chroot_list # chroot控制列表文件,可自己指定
===============================
[root@localhost ~]# cat /etc/vsftpd/chroot_list
test
[root@localhost ~]# ftp 127.0.0.1
Connected to 127.0.0.1 (127.0.0.1).
220 (vsFTPd 3.0.2)
Name (127.0.0.1:root): test
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>
===============================
從2.3.5之后,vsftpd增強了安全檢查,如果用戶被限定在了其主目錄下,則該用戶的主目錄不能再具有寫權限了!
如果檢查發現還有寫權限,就會報該錯誤。 要修復這個錯誤,可以用命令chmod a-w /home/test去除用戶主目錄的寫權限,注意把目錄替換成你自己的。
或者你可以在vsftpd的配置文件中增加下列兩項中的一項:
allow_writeable_chroot=YES
=============修改權限后==================
ftp> pwd
257 "/"
ftp>
===============================
匿名用戶
anonymous_enable=YES # 啟用匿名用戶
anon_upload_enable=NO # YES 允許匿名用戶上傳
anon_mkdir_write_enable=NO # YES 允許匿名用戶創建目錄
anon_other_write_enable=NO # YES 刪除和重命名。
no_anon_password=NO # YES 啟用后,這將阻止vsftpd詢問匿名密碼-匿名用戶將直接登錄。
[root@localhost ~]# grep ftp /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@localhost ~]# ls -ld /var/ftp
drwxr-xr-x. 3 root root 17 Oct 15 19:02 /var/ftp
[root@localhost ~]# ls -ld /var/ftp/pub/
drwxr-xr-x. 2 root root 6 Oct 31 2018 /var/ftp/pub/
ftp(anonymous)用戶的家目錄為: /var/ftp,匿名用戶登陸后會進入/var/ftp目錄,并chroot。
而且該目錄的屬主為root,其它用戶沒有寫權限,所以在配置中開啟了寫入權限也無法上傳.
最好使用setfacl -m u:ftp:rwx /var/ftp/pub來添加一個ftp用戶的權限,而不是使用chown來改用戶和組。
"注意:不能修改 /var/ftp 目錄的權限,否則會報錯"
[root@localhost ~]# ftp 127.0.0.1
Connected to 127.0.0.1 (127.0.0.1).
220 (vsFTPd 3.0.2)
Name (127.0.0.1:root): ftp
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
Login failed.
421 Service not available, remote server has closed connection
===============================
虛擬用戶
虛擬用戶的上傳和寫權限也是受匿名anonymous用戶的權限控制的如:
anon_upload_enable=YES
anon_mkdir_write_enable=YES
...
-
基于文件驗證的vsftpd 虛擬用戶
-
1. 生成密碼數據庫文件
vim /etc/vsftpd/vusers.txt
tom
1
jerry
1
奇數行為虛擬用戶
偶數行為密碼
cd /etc/vsftpd/
db_load -T -t hash -f vusers.txt vusers.db 編碼文件為hash 格式
chmod 600 vusers.db 禁止非root 修改查看 處于安全性 -
2. 創建linux 系統用戶及訪問ftp目錄
useradd -d /var/ftproot -s /sbin/nologin vuser
chmod +rx /var/ftproot/ 給予執行和讀權限 使得可以ftp登陸
centos7 還需要執行以下操作:
chmod -w /var/ftproot/
mkdir /var/ftproot/upload
setfacl -m u:vuser:rwx /var/ftproot/upload 為vuser 設置 acl 權限 -
3. 創建pam配置文件
vim /etc/pam.d/vsftpd.db
auth required pam_userdb.so db=/etc/vsftpd/vusers
account required pam_userdb.so db=/etc/vsftpd/vusers -
4. 指定pam配置文件
vim /etc/vsftpd/vsftpd.conf
guest_enable=YES
guest_username=vuser
pam_service_name=vsftpd.db -
5. 禁用SELINUX 和 firewalld
iptables -F
setenforce 0 -
6 create a config file for vitual user
mdkir /etc/vsftpd/vusers.d/ 創建配置文件存放的路徑
vim /etc/vsftpd/vsftpd.conf
user_config_dir=/etc/vsftpd/vusers.d/ 指定虛擬用戶獨立的配置目錄
cd /etc/vsftpd/vusers.d/
vim tom
anon_upload_enable=YES 匿名上傳
anon_mkdir_write_enable=YES
anon_other_write_enable=YES 允許匿名用戶具有建立目錄,上傳之外的權限,如重命名,刪除
-
1. 生成密碼數據庫文件
===============================
-
mysql驗證的vsftpd 虛擬用戶
1. 在數據庫服務器上安裝包:
Centos7:在數據庫服務器上安裝
yum –y install mariadb-server
systemctl start mariadb.service
systemctl enable mariadb
Centos6:在數據庫服務器上安裝
yum –y install mysql-server
-
2. 在FTP服務器上安裝vsftpd和pam_mysql包
centos6:pam_mysql由epel6的源中提供
yum install vsftpd pam_mysql
centos7:無對應rpm包,需手動編譯安裝
yum -y groupinstall "Development Tools"
yum -y install mariadb-devel pam-devel vsftpd
下載pam_mysql-0.7RC1.tar.gz
https://sourceforge.net/projects/pam-mysql/
https://sourceforge.net/projects/pam-mysql/files/latest/download- 2.1 解壓縮pam模塊
tar -xf pam_mysql-0.7RC1.tar.gz
cd pam_mysql-0.7RC1/
- 2.2 編譯
./configure --with-pam-mods-dir=/lib64/security
or
./configure --with-pam-mods-dir=/lib64/security --with-mysql=/usr --with-pam=/usr
=====================
make && make install
- 2.1 解壓縮pam模塊
3. 創建數據庫和表
1)創建ftpuserdb數據庫
MariaDB [(none)]> create database ftpuserdb;
2)授權一個用戶可以連這個數據庫(有讀權限就行)
MariaDB [(none)]> grant select on ftpuserdb.* to vsftpd@'localhost' identified by 'vsftpdpass';
注意這里只授權了vsftpd用戶的本地訪問權限,如有需要自行增加
3)創建一個表
MariaDB [ftpdb]> create table users (id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, name VARCHAR(50) BINARY NOT NULL, password CHAR(48) BINARY NOT NULL );
4)往表里增加虛擬用戶
MariaDB [ftpdb]> INSERT INTO users(name,password) values('tom',password('1'));
MariaDB [ftpdb]> INSERT INTO users(name,password) values('jerry',password('centos'));
4. 準備一個pam配置文件
vim /etc/pam.d/vsftpd.mysql
auth required pam_mysql.so user=vsftpd passwd=vsftpdpass host=localhost db=ftpdb table=users usercolumn=name passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftpd passwd=vsftpdpass host=localhost db=ftpdb table=users usercolumn=name passwdcolumn=password crypt=2
5.配置使用pam文件和虛擬用戶
vim /etc/vsftpd/vsftpd.conf
guest_enable=YES
guest_username=vftpuser
pam_service_name=vsftpd.mysql
6. 準備用戶和目錄
useradd -s /sbin/nologin vftpuser
chmod 500 /home/vftpuser/
把用戶家目錄的寫權限去掉,家目錄用戶自己不能有寫權限,不然登陸時chroot()就會出錯,登陸失敗
mkdir /home/vftpuser/upload
##創建上傳用的文件夾
chown vftpuser /home/vftpuser/upload/
7. 虛擬用戶的獨立控制
修改配置文件,指明用戶控制文件的位置
vim /etc/vsftpd/vsftpd.conf
user_config_dir=/etc/vsftpd/vftpuser.d/
=====
mkdir /etc/vsftpd/vftpuser.d/
# 創建目錄
vim /etc/vsftpd/vftpuser.d/tom
# 編寫tom用戶的配置文件
anon_upload_enable=YES
anon_mkdir_write_enable=YES
=====
vim /etc/vsftpd/vftpuser.d/jerry
local_root=/data/jerry
這種設置要切兩次根,第一次切vftpuser的根/home/vftpuser/,第二交再切到local_root
[root@localhost ~]# ls -ld /data/jerry/
drwxr-xr-x. 2 root root 23 Oct 16 00:19 /data/jerry/
備注1:要想 jerry 充當虛擬用戶 jerry的根 jerry自己必須沒有寫權限
備注2:要想讓 jerry用戶有寫權限,在/etc/vsftpd/vftpuser.d/jerry文件中加入
anon_upload_enable=YES
anon_mkdir_write_enable=YES
還要對/data/jerry/upload目錄要有寫權限
setfacl -m u:vftpuser:rwx /data/jerry/upload
==============================
-
更多的權限控制
- 1. user_list
userlist_deny
This option is examined if userlist_enable is activated. If you set this setting to NO,
then users will be denied login unless they are explicitly listed in the file specified by userlist_file. When login is denied, the denial is issued before the user is asked for a password.
Default: YES
userlist_enable
If enabled, vsftpd will load a list of usernames, from the filename given by userlist_file. If a user tries to log in using
a name in this file, they will be denied before they are asked for a password. This may be useful in preventing cleartext
passwords being transmitted. See also userlist_deny.
Default: NO
userlist_file
This option is the name of the file loaded when the userlist_enable option is active.
Default: /etc/vsftpd/user_list
userlist_deny=YES
默認的黑名單,user_list文件中的用戶名不能登陸
如果設置為NO,則user_list就成為了白名單,只有文件中的用戶名才能登陸
而且這個文件的定義,會在詢問密碼之前生效
-
2. ftpusers
這個是在默認pam中定義的
auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
定義在這個文件中的用戶將禁止登陸ftp服務器 -
3. tcp_wrapper
使用tcp_wrapper=YES
可以調用tcp_wrapper來控制主機的訪問
=============================
被動模式的端口限制
.......
pasv_min_port=port number
pasv_max_port=port number
設定在PASV模式下,建立數據傳輸所可以使用port范圍的下界和上界,0 表示(1024 – 65535端口)。默認值為0。把端口范圍設在比較高的一段范圍內,比如50000-60000,將有助于安全性的提高。
=============================
問題(Centos 7)
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
系統用戶可以控制是否chroot
匿名用戶和虛擬用戶默認會chroot
在chroot環境下,用戶家(根)目錄 用戶自己不能有寫權限,否則報錯
如:jerry的根目錄為/data/jerry 只要jerry用戶沒有寫權限就OK
226 Transfer done (but failed to open directory).
登陸正常,但登入服務器后,ls都顯示如上錯誤
- selinux問題,關閉
- 登陸的用戶在文件系統中沒有權限,文件夾的x權限
500 OOPS: bad bool value in config file for: anon_mkdir_write_enable
systemctl restart vsftpd
時報錯,其實并不是配置寫錯了,而是anon_mkdir_write_enable=YES
后多了空格
550 Failed to open file.
上傳文件正常,但不能下載文件
-rw------- 1 1001 1001 0 Oct 15 16:31 hello.txt #默認anon_umask=077情況下的上傳文件
-rw-r--r-- 1 1001 1001 23 Oct 15 17:21 issue # anon_umask=022情況下的上傳文件
get: Access failed: 550 Failed to open file. (hello.txt)
原因:默認anon_world_readable_only=YES
為開啟狀態
這個參數的意義:anonymous僅全局可讀 開啟
啟用后,將僅允許匿名用戶下載全局可讀(other有讀權限)的文件。 這是承認ftp用戶可能擁有文件,尤其是在存在上傳文件的情況下。
解決方案:
- 修改默認的anon_uamsk
anon_umask=022
默認為:077
- 修改默認的anon_uamsk
- 修改默認的anon_world_readable_only
anon_world_readable_only=NO
默認為:YES
- 修改默認的anon_world_readable_only