FTP 介紹 FTP是File Transfer Protocol的縮寫,譯為文件傳輸協議,是基於CS結構的應用層協議。其主要作用是在網路上的兩台電腦之間傳輸文件。 FTP傳輸層使用的是TCP協議,它有一個很大的特點是採用雙埠的工作模式,即客戶端和服務端的通信是通過兩個通道進行的 命令通道用於服 ...
FTP 介紹
FTP是File Transfer Protocol的縮寫,譯為文件傳輸協議,是基於CS結構的應用層協議。其主要作用是在網路上的兩台電腦之間傳輸文件。
FTP傳輸層使用的是TCP協議,它有一個很大的特點是採用雙埠的工作模式,即客戶端和服務端的通信是通過兩個通道進行的
-
命令通道用於伺服器和客戶端之間交互指令的傳輸。固定使用21埠
-
數據通道用於用於實際的文件傳輸,包括上傳和下載文件等,使用的埠不固定。
FTP採雙通道模式有以下原因:
1、 隔離作用:將命令(控制信息)和數據流隔離,FTP確保了命令傳輸的簡潔性和效率。即使在大量數據傳輸時,也可以無干擾地發送控制信息。
2、 信息加密:分開命令和數據流,可以在不同通道上應用不同的安全措施
FTP服務端的命令通道埠預設為21/tcp,但是數據通道的埠不固定,在不同的工作模式下有所不同。
1、主動模式:即伺服器主動向客戶端發起連接,服務端數據通道用20埠,客戶端的埠隨機
2、被動模式:即客戶端主動發起連接請求,服務端被動接受客戶端的連接請求,此時雙方都是使用隨機埠
FTP為什麼要分為主動模式和被動模式,猜測可能是為了相容更多的使用場景吧。但是兩種模式在使用和功能上是一樣的,主要區別在於建立數據連接的方式和使用的埠。
1、主動模式:服務端的20埠會連接客戶端的隨機埠,如果客戶端開啟了防火牆就會導致連接拒絕;
2、被動模式:被動模式是客戶端主動發起連接,一般情況下防火牆都是不限制出去的流量的,主要服務端配置了合適的策略,那麼不會導致連接失敗的。這也是為什麼大多數現代FTP客戶端會預設使用被動模式,這樣與各種網路配置的相容性更好。
說明:
FTP服務端有兩種方法解決被動模式下客戶端訪問本機隨機埠,一種是通過連接追蹤功能,還有一種直接把防火牆關了,就不會有這個問題了。
FTP的工作流程大體上時這樣的,簡單來說就是先建立命令通道再建立數據通道。
1、 服務端開啟對應守護進程,監聽21/tcp埠
2、 客戶端發起連接請求,通過21埠連接到伺服器。建立命令通道,命令通道用於傳輸和通信相關的一些指令。
3、 建立數據通道:如果是主動模式,服務端數據通道使用20埠,客戶端隨機。如果是被動模式,雙方都使用隨機埠
4、 兩個通道建立後,進行數據的傳輸。
在Linux主機上,一般通過vsftpd這個軟體來搭建FTP服務端,因為vsftpd具有速度快、穩定性好,單機就可支持15K併發量的特點。
vsftp官網:https://security.appspot.com/vsftpd.html
在windows主機上,一般可以用FileZilla Server這個工具搭建FTP服務端,因為它的配置很簡單,搭建很容易。
FileZilla官網:https://filezilla-project.org/
安裝vsftpd,一般通過軟體管理工具進行安裝即可,例如yum、apt等。也可以去官網下載源碼進行編譯安裝。
例如:ubuntu安裝vsftpd
sudo apt install vsftpd
vsftpd 配置項說明
配置文件
使用軟體管理工具安裝的vsftpd,主配置文件一般位於/etc/vsftpd.conf或者/etc/vsftpd/vsftpd.conf,編輯配置文件即可完成相關功能的配置;
vsftpd中也有子配置文件,但是預設是需要自己指定的,通過 ser_config_dir 選項可以指定存放子配置文件的位置。這樣服務載入時會預設讀取該目錄中以.conf結尾的配置文件
例如;指定自配文件存放位置為/etc/vsftpd.d
ser_config_dir=/etc/vsftpd.d
埠修改
服務端預設監聽21埠,在一些特殊情況下可能要進行修改,可以用 listen_port 選項修改服務端命令通道預設監聽的埠。
例如:將埠改為2121
listen_port=2121
主動模式下服務端數據通道預設使用的埠是20埠,是通過 connect_from_port_20=YES 選項指定的如果需要修改主動模式的埠,可以將 connect_from_port_20 設置為NO,然後通過 ftp_data_port 選項進行指定。
例如:將主動模式下數據通道埠修改為200
connect_from_port_20=NO
ftp_data_port=200
被動模式下,服務端數據通道預設埠範圍時沒有限制的,但是可以指定數據通道的埠範圍,通過 pasv_min_port 指定下限值,通過 pasv_max_por 指定上限值
例如:將被動模式下服務端的數據通道埠指定為6000-6010這個範圍
pasv_min_port=6000
pasv_max_port=6010
時間配置
vsftpd預設使用的是預設使用的是格林尼治時間,所以如果要使用本地時間的話,需要將 use_localtime 設置為YES。
use_localtime=YES
說明: 格裡尼治時間約等於世界標準時間,本地時間 = 世界標準時間 + 時區差 例如:北京時間 = 世界標準時間 + 8
用戶禁錮
當客戶端連接到服務端時,後起始目錄(FTP根目錄)通常是用戶的家目錄,FTP一般預設用戶能夠訪問其家目錄之外的其他文件系統目錄。為了安全考慮,可以將其限制在這個目錄內,不能訪問它的上級目錄,此時該目錄就是用戶能見到的根目錄。
可以通過 chroot_local_user 選項實現,這個選項是針對所有用戶生效的,不管是匿名用戶還是系統用戶。
chroot_local_user=YES
更改數據目錄
用戶登錄到FTP伺服器後起始目錄是該用戶的家目錄,但是在某些情況下我們可能想更改其所在目錄,這個時候可以通過 local_root 指定用戶登錄到FTP伺服器後切換到local_root指定的目錄。但是這個選項對匿名用戶沒效,匿名用戶要使用 anon_root 才可以實現。
這裡需要註意一點是:用戶在登錄FTP伺服器後再切換到的這個指定目錄,所以剛開始連接到服務端時,用戶還是會進入其家目錄然後再切換到指定目錄。如果這個時候用戶的家目錄不存在就會報錯,連接不上服務端。
例如:將用戶的數據目錄更改到/data目錄
local_root=/data
![](https://img2023.cnblogs.com/blog/1519088/202311/1519088-20231108235521165-1118182363.png)
例如:更改匿名用戶的數據目錄為/data
anon_root=/data
根目錄寫許可權
我們在使用 chroot_local_user 將用戶禁錮到某個目錄時,此時預設是不允許用戶對該目錄具備寫許可權的,因為可能會利用某些許可權提升漏洞來獲得對整個系統的訪問權。
如果此時用戶擁有對該目錄,也就是該用戶的根目錄擁有寫許可權,沒法正常連接到服務端,此時有種簡便方法就是通過 allow_writeable_chroot 選項解決。但是該選項對匿名用戶不生效,即這個配置通常用於本地非匿名用戶。因為如果匿名用戶可以寫入自己的chroot目錄,他們可能會上傳惡意文件,或者以其他方式改變伺服器的文件系統,從而危害伺服器的安全。
allow_writeable_chroot=YES
說明: 匿名用戶要解決這個問題,一種方法就是將該目錄的寫許可權給取消,但是此時匿名用戶沒有了修改服務端數據的能力,還有種方法就是再該目錄下再創建一個帶寫許可權的目錄,這樣就能再這個子目錄裡面進行相關數據的操作了。
日誌設置
如果想要vsftpd的日誌輸出更詳細,可以通過以下選項來進行配置。
-
xferlog_file:可以指定一個自定義的日誌文件路徑,日誌文件預設位置通常是/var/log/vsftpd.log
-
xferlog_enable:是否啟用文件傳輸日誌,這會記錄所有的上傳和下載,一般設置為YES
-
xferlog_std_format:如果設置為NO,vsftpd將使用詳細日誌格式而不是標準的xferlog格式。這提供了更多的詳細信息,包括每個FTP命令的日誌記錄
-
log_ftp_protocol:啟用此選項將記錄每個FTP會話的詳細對話,這包括客戶端和伺服器之間的所有交互,一般設置為YES
匿名用戶模式
匿名用戶模式是一種特殊的訪問方式,允許用戶在沒有個人賬戶的情況下登錄到FTP伺服器。這通常是為了公共文件共用而設置的。
啟用匿名用戶:
啟用匿名用戶一般通過以下兩個選項即可:
-
anonymous_enable:是否啟用匿名用戶模式,YES表示啟用
-
no_anon_password:是否要求匿名用戶輸入密碼。YES表示不用輸入密碼,但是客戶端軟體可能仍會提示輸入密碼,設置為YES後可以輸入任何內容(或者留空),因為伺服器已經被配置為不驗證匿名用戶的密碼。
匿名用戶許可權配置:
因為匿名用戶在FTP服務中通常受到特別的管理和限制,主要是因為安全考慮。由於匿名用戶不需要身份驗證即可訪問FTP服務,因此需要對他們的許可權進行嚴格控制。所以配置選項較多且嚴格。
-
write_enable:是否讓所有用戶擁有刪除、上傳、修改等許可權。此選項針對所有用戶生效,但是如果匿名用戶只開啟了這個選項,照樣沒許可權,因為vsftpd對匿名用戶的許可權管控很嚴格,所以還需要一些其它選項輔助才行。
-
anon_upload_enable: 控制匿名用戶是否可以上傳文件。通常設置為YES
-
anon_umask:控制匿名用戶上傳文件後,文件的umask,通常設置為022.
-
anon_mkdir_write_enable: 控制匿名用戶是否可以創建新目錄。通常設置為YES
-
anon_other_write_enable: 控制匿名用戶是否可以進行其他寫操作,如刪除和重命名文件。通常設置為YES
-
anon_world_readable_only: 控制匿名用戶只能下載全局可讀的文件,通常設置為NO,表示不是僅可讀的文件也能下載。
本地用戶模式
本地用戶模式指的是允許系統上的本地用戶使用他們的系統用戶名和密碼通過FTP登錄。
啟用本地用戶:
- local_enable:是否允許客戶端使用ftp伺服器上的系統用戶進行登錄
本地用戶許可權:
- write_enable:允許用戶對ftp服務端的數據進行操作。相對於匿名用戶模式,本地模式的許可權配置就簡單很多了。直接通過 write_enable 選項就可以開啟修改服務端數據的許可權了。
用戶映射模式
用戶映射一般是都將多個虛擬用戶映射為一個本地系統用戶。這樣使得FTP用戶與系統用戶不直接關聯,增強了安全性,並且可以給不通的虛擬用戶設置不同的許可權。
虛擬用戶: 指的是在操作系統層面不存在的用戶賬號,這些用戶在 /etc/passwd 文件中找不到,虛擬用戶只存在於為它們創建的特定服務中,它們有自己的認證機制和許可權設置,與系統用戶完全獨立。
FTP中的虛擬用戶: 一般是存在一個Berkeley DB文件文件中,然後編寫對應的 PAM 規則來實現身份驗證(因為FTP支持PAMA插件),這樣在客戶端進行登錄的時候就能驗證用戶的身份,從而執行下一步操作。
Berkeley DB文件: 這是一個鍵值對資料庫文件,通常包含用戶名和加密後的密碼。它是由管理員預先創建好的,用於存儲虛擬用戶的認證信息。奇數行是賬號,偶數行是密碼。
啟用虛擬用戶模式:
啟用虛擬用戶一般通過這三個選項即可完成:
-
local_enable:虛擬用戶可以理解為是一種特殊的系統用戶,所以需要開啟 local_enable=YES選項。
-
guest_enable:所有非匿名登錄的用戶都會被當作虛擬用戶,然後映射為guest_username 指定的系統用戶。
-
guest_username:指定將虛擬用戶映射為某個系統用戶
虛擬用戶許可權配置:
虛擬用戶許可權配置就有很多配置方法了,只要有這三種方式:
方法一:和系統用戶擁有同等權利,這種方式是通過 virtual_use_local_privs 選項指定,
方法二:在沒啟用virtual_use_local_privs 選項的情況下,這個時候虛擬用戶將預設具有與匿名用戶相同的許可權,這就是為什麼用匿名用戶的配置可以實現虛擬用戶的配原因。
方法三:這種情況就是通過 ser_config_dir 選項定義子配置文件,給每個虛擬用戶定義不同的許可權。
官網文檔說了,沒有啟用virtual_use_local_privs,和匿名用戶相同的許可權,這就是可以通過匿名用戶選項可以配置虛擬用戶許可權的原因
![](https://img2023.cnblogs.com/blog/1519088/202311/1519088-20231108190950086-255161129.png)
FTP 匿名用戶配置流程
(1)創建數據目錄
預設情況下,vsftpd中的匿名用戶有兩個,anonymous和ftp。匿名用戶登錄FTP伺服器時,他們的起始目錄通常是由特定的匿名FTP用戶的家目錄決定的。大多數Linux發行版中,這個目錄是/var/ftp或/srv/ftp,具體是多少可以通過 getent passwd ftp 查看
getent passwd ftp
![](https://img2023.cnblogs.com/blog/1519088/202311/1519088-20231109104701299-1391521380.png)
如果需要更改初始的數據目錄,通過 anon_root 選項可以修改,在匿名用戶登陸後(登錄時也會先進入預設的起始目錄)將嘗試更改的目錄。
# 創建數據目錄
sudo mkdir -p /ftp_data/anon_data
# 更改文件許可權
chown root:root /ftp_data
shmod 755 /ftp_data
chown ftp:ftp /ftp_data/anon_data
![](https://img2023.cnblogs.com/blog/1519088/202311/1519088-20231109102721073-1162606544.png)
說明:
對匿名用戶來說,預設是不允許對家目錄擁有寫許可權的,雖然有一個 allow_writeable_chroot=YES 選項,但是這個選項對匿名用戶不生效。所以如果要讓匿名用戶操作服務端數據,一種做法就是在指定的數據目錄下再創建一個目錄,客戶的數據存放在數據目錄的子目錄中。
(2)修改配置文件
配置匿名用戶的時候,改這些配置就行了,其它保持預設即可。
sudo vim /etc/vsftpd.conf
# 開啟匿名用戶登錄
anonymous_enable=YES
no_anon_password=YES
# 匿名用戶許可權配置 這裡是給了所有許可權
write_enable=YES
anon_upload_enable=YES
anon_umask=022
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
anon_world_readable_only=YES
# 數據目錄設置
anon_root=/ftp_data
chroot_local_user=YES
allow_writeable_chroot=YES
# 日誌設置 顯示詳細的日誌信息
xferlog_enable=YES
xferlog_std_format=NO
log_ftp_protocol=YES
# 連接設置(同一個區域網內不用設置)
# 接受從任何IP地址發起的被動模式數據連接,即使該IP地址與發起FTP控制連接的IP地址不同。(負載均衡情況有用)
pasv_promiscuous=YES
# 指定了被動模式下vsftpd告訴FTP客戶端的外部IP地址。,客戶端需要用它來建立數據連接(如果伺服器處於NAT後面需要指定為公網IP地址)
pasv_address=47.104.130.81
說明:
當客戶端位於負載均衡器後面時,控制連接(即FTP命令)可能通過一個IP地址來建立,而數據連接(用於傳輸文件)可能來自另一個IP地址。預設情況下,vsftpd出於安全考慮要求數據連接必須來自與控制連接相同的IP地址。如果啟用了負載均衡,這個預設行為會導致數據連接被拒絕,因為IP地址不匹配。設置pasv_promiscuous=YES可以使vsftpd接受來自任何IP地址的數據連接,從而解決了這個問題。
如果FTP伺服器位於NAT(網路地址轉換)設備後面,那麼伺服器上的FTP服務可能無法正確知道自己的公網IP地址。在被動模式下,伺服器需要告訴客戶端一個公網IP地址來建立數據連接。如果沒有設置pasv_address,伺服器可能會錯誤地發送它的私有(內網)IP地址,客戶端在互聯網上是無法使用這個地址的。通過設置pasv_address為伺服器的公網IP地址,您確保了客戶端接收到正確的信息,從而可以成功建立數據連接。
(3)重啟服務生效
sudo systemctl restart vsftpd.service
FTP 系統用戶配置流程
(1)創建用於登錄FTP伺服器的系統用戶並且指定數據目錄
useradd -m -s /usr/bin/rbash -d /data/ ftpadmin
passwd ftpadmin
為了加強安全性,防止給予用戶完整的shell訪問許可權可能會帶來安全問題。所以為用戶指定登錄shell為rbash,即限制性的bash shell,限制用戶能夠運行的命令。
(2)修改配置文件
相較於匿名用戶的許可權配置,本地用戶的許可權配置就簡單很多了。直接通過 write_enable 選項就可以開啟修改服務端數據的許可權了。
sudo vim /etc/vsftpd.conf
# 啟用系統用戶模式
local_enable=YES
# 許可權配置
write_enable=YES
# 指定數據目錄
local_root=/data
chroot_local_user=YES
allow_writeable_chroot=YES
# 連接配置(區域網內不用管)
pasv_promiscuous=YES
pasv_address=47.104.130.81
# 日誌配置
xferlog_enable=YES
xferlog_std_format=NO
log_ftp_protocol=YES
# 登錄名單配置
# user_list中的用戶允許登錄
userlist_enable=YES
# 指定哪些用戶可以登錄服務端
userlist_file=/etc/vsftpd.user_list
# 如為YES,表示禁止列表中的用戶訪問FTP伺服器
userlist_deny=NO
(3)創建允許連接的名單
sudo vim /etc/vsftpd.user_list
ftpadmin
(4)重啟服務
systemctl restart vsftpd.service
FTP 虛擬用戶配置流程
(1)創建用戶
useradd -r -m -d /ftp_data -s /sbin/nologin ftpuser
(2)生成生成Berkeley DB 資料庫文件
先創建一個文本文件,奇數行是用戶名,偶數行是密碼。然後通過db-util工具包提供的db_load工具實現Berkeley DB 資料庫文件。
# 編輯文本文件
sudo vim ~/vusers
tom
Abc123
bob
123456
alice
redhat
# 生成DB文件
sudo db_load -T -t hash -f ~/vusers /etc/vsftpd/vusers.db
(3)編寫PAM規則文件
vsftpd支持PAM插件,當用戶嘗試登錄FTP服務時,vsftpd會通過PAM調用pam_userdb.so模塊。後者會檢查用戶提供的用戶名和密碼是否與/etc/vsftpd/vusers資料庫中的記錄匹配。如果認證成功,用戶將被允許登錄。
在安裝vsftpd的時候,在/etc/pam.d目錄下生成了一個預設的規則文件vsftpd,可以直接基於這個文件添加驗證規則。
sudo vim /etc/pam.d/vsftpd
auth required pam_userdb.so db=/etc/vsftpd/vusers
account required pam_userdb.so db=/etc/vsftpd/vusers
![](https://img2023.cnblogs.com/blog/1519088/202311/1519088-20231109164033084-1274960119.png)
(4)修改配置
將若幹個虛擬用戶映射為一個系統用戶,且虛擬用戶擁有系統用戶的許可權配置方法:
sudo vim /etc/vsftpd.conf
# 虛擬用戶可以理解為是一種特殊的系統用戶,所以需要開啟 local_enable=YES選項。
local_enable=YES
guest_enable=YES
# 指定映射的用戶
guest_username=ftpuser
# 開啟許可權
write_enable=YES
local_umask=022
# 虛擬用戶擁有和系統用戶同樣的許可權
virtual_use_local_privs=YES
# 數據目錄管理
local_root=/ftp_data
chroot_local_user=YES
allow_writeable_chroot=YES
# 指定用於驗證的PAM規則文件,不用加全路徑,會預設到/etc/pam.d下找
pam_service_name=vsftpd
(5)重啟服務
sudo systemctl restart vsftpd.service
虛擬用戶許可權細緻化管理:
根據官方配置文檔我們可知,當 virtual_use_local_privs=NO 時(預設就是NO),虛擬用戶將使用與匿名用戶相同的許可權,也就是可以通過匿名用戶的一些許可權配置選項來配置虛擬用戶的許可權。
所以如果不想給虛擬用戶系統用戶的所有許可權,可以通過匿名用戶的相關配置來指定許可權。
例如:給虛擬用戶配置所有許可權
sudo vim /etc/vsftpd.conf
# 虛擬用戶可以理解為是一種特殊的系統用戶,所以需要開啟 local_enable=YES選項。
local_enable=YES
guest_enable=YES
# 指定映射的用戶
guest_username=ftpuser
# 開啟許可權
write_enable=YES
local_umask=022
anon_upload_enable=yes
anon_mkdir_write_enable=yes
anon_other_write_enable=yes
anon_world_readable_only=NO
# 連接設置(同一個區域網內不用設置)
# 接受從任何IP地址發起的被動模式數據連接,即使該IP地址與發起FTP控制連接的IP地址不同。(負載均衡情況有用)
pasv_promiscuous=YES
# 指定了被動模式下vsftpd告訴FTP客戶端的外部IP地址。,客戶端需要用它來建立數據連接(如果伺服器處於NAT後面需要指定為公網IP地址)
pasv_address=47.104.130.81
# 日誌設置 顯示詳細的日誌信息
xferlog_enable=YES
xferlog_std_format=NO
log_ftp_protocol=YES
# 數據目錄管理
local_root=/ftp_data
chroot_local_user=YES
allow_writeable_chroot=YES
# 指定用於驗證的PAM規則文件,不用加全路徑,會預設到/etc/pam.d下找
pam_service_name=vsftpd