或許你沒有特別注意過這件事,其實當我們在各個網站下載檔案的時候,FTP (File Transfer Protocol,檔案傳輸協定) 一直默默的在背後與其他的協定一同支撐著這個網路世界。
真要說起這個輩份大約跟 BBS 同等資深的老傢伙,可是不像 BBS 一樣 「老兵不死,只是逐漸凋零」,在台灣只剩 PTT 一支獨秀。
它的本事不大,就只專門負責一件事:檔案的傳送與接收,其他功能什麼都不會;可是偏偏在許多提供大容量檔案、免帳號密碼的下載服務站台,卻又缺它不可。
而 vsFTPd (Very Secure File Transport Protocol Daemon),這個號稱自己是最安全,也是最快的 FTP Server 服務,更是多年來在各大 Linux 發行版的套件庫中,絕對不可或缺的一支套件。
目前最新版本是在 2015/07 釋出的 3.0.3 版,其實我們也可以看到,這真的是個非常穩定的套件,在 2012/04 釋出 3.0.0 版之後,過了 3 年之後,才微改版二次而已。
簡單的說,主要的優點有三個:
- 安全性
- 高效能
- 可靠性
而高效能跟可靠性到底有多強呢?
官方提到了這個實際例子,曾經在一台伺服器上,24 小時內讓 1500 個使用者同時上線,總流量大約傳輸了 2.6TB 左右。
事前準備
我們是以 CentOS 7.0 x86_64 Minimal 版為基礎,安裝步驟請參閱 CentOS 7.0 不完全安裝手冊 系列文章。
- CentOS 7.0 不完全安裝手冊 - 簡介
- CentOS 7.0 不完全安裝手冊 - 事前準備
- CentOS 7.0 不完全安裝手冊 - Step 1 系統安裝選單
- CentOS 7.0 不完全安裝手冊 - Step 2 選擇初始語言
- CentOS 7.0 不完全安裝手冊 - Step 3 設定「網路與主機名稱」
- CentOS 7.0 不完全安裝手冊 - Step 4 設定「日期時間」
- CentOS 7.0 不完全安裝手冊 - Step 5 設定「鍵盤配置」
- CentOS 7.0 不完全安裝手冊 - Step 6 設定「語言支援」
- CentOS 7.0 不完全安裝手冊 - Step 7 設定「安裝來源」
- CentOS 7.0 不完全安裝手冊 - Step 8 設定「軟體選擇」
- CentOS 7.0 不完全安裝手冊 - Step 9 設定「安裝目的地」
- CentOS 7.0 不完全安裝手冊 - Step 10 開始複製檔案
安裝服務
我們從 CentOS 官方套件庫直接安裝就可以了。
sudo yum -y install vsftpd
這次使用的版本是 3.0.2。
啟動服務
不必修改任何設定值,就可以正常的啟動 vsFTPd 服務。
sudo systemctl restart vsftpd
預設的 FTP 根目錄在 /var/ftp。
我們可以視需求,決定是否讓服務在開機時就自動啟動。
sudo systemctl enable vsftpd
主設定檔
主設定檔及相關設定檔的預設儲存目錄在 /etc/vsftpd。
先來看一下主設定檔的內容。
sudo vi /etc/vsftpd/vsftpd.conf
所有的參數說明都可以在 vsFTPd online manual page 中找到,乍看之下參數似乎很多,其實這是個很容易維護的服務,需要什麼功能,就一個蘿蔔一個坑的填進去就好了。
man 5 vsftpd.conf
全域設定
# 選擇以 IPv4 + IPv6 的獨立服務模式運作,listen (IPv4) 跟 listen_ipv6 (IPv4 + IPv6) 同時只能啟用一種listen = NO
listen_ipv6 = YES
# 指定傳輸命令用的通訊埠
listen_port = 21
# 不允許主動式傳輸使用 TCP 20 埠來傳輸資料,修改成 TCP 2020 埠
connect_from_port_20 = NO
ftp_data_port = 2020
connect_from_port_20 = NO
ftp_data_port = 2020
# 允許被動式傳輸,並指定可使用的通訊埠範圍為 TCP 60101 到 60200 埠
pasv_enable = YESpasv_min_port = 60101
pasv_max_port = 60200
# 變更匿名者上傳的檔案,將擁有者改為 user999 帳號
chown_uploads = YES
chown_username = user999
# 指定主日誌檔的位置
vsftpd_log_file = /var/log/vsftpd.log
# 記錄所有上傳下載的行為,並指定傳輸記錄日誌檔的位置
xferlog_enable = YES
xferlog_file = /var/log/xferlog
# 傳輸記錄日誌檔採用詳細記錄模式,並且不使用相容於 wu-ftp 的格式
xferlog_std_format = NO
log_ftp_protocol=YES
# 主動式傳輸在 60 秒後未連線成功就斷線
connect_timeout = 60
# 被動式傳輸在 60 秒後未連線成功就斷線
accept_timeout = 60
# 在傳輸資料時,連續 120 秒 未傳輸任何資料就斷線
data_connection_timeout = 120
# 登入後,連續 600 秒未執行任何命令操作就斷線
idle_session_timeout = 600
# 允許同時 10 個用戶端連進行連線
max_clients = 10
# 同一個 IP 允許建立 2 個連線
max_per_ip = 2
# 允許登入失敗 3 次
max_login_fails = 3
# 啟用上傳功能
write_enable = YES
# 啟用下載功能
download_enable = YES
# 登入成功後的歡迎訊息,顯示一小段文字或是從純文字檔讀取,同時只能使用一種
ftpd_banner = Welcome to my FTP site.
banner_file = /etc/vsftpd/banner
# 以用戶端的本地時間為準
use_localtime = YES
use_localtime = YES
# 支援 TCP Wrappers (/etc/hosts.allow 與 /etc/hosts.deny)
tcp_wrappers = YES
# 指定 PAM 服務對應的模組名稱為 vsftpd (在 /etc/pam.d/ 裡)
pam_service_name = vsftpd
本機使用者
# 允許本機使用者登入local_enable = YES
# 限制本機使用者的最大傳輸速度為 10Mbps (0 代表不限制)
local_max_rate = 10000000
# 禁止離開家目錄,並指定不受限制的使用者清單
chroot_local_user = YES
chroot_list_enable = YES
chroot_list_file = /etc/vsftpd/chroot_list
# 變更根目錄之後,開放根目錄的寫入權限
allow_writeable_chroot = YES
# 限制可登入的本機使用者,選擇以白名單來管理,並指定允許登入的使用者清單
userlist_enable = YES
userlist_deny = NO
userlist_file - /etc/vsftpd/user_list
# 新建目錄的預設權限 = 755 (full 777 - umask 022),新增檔案的預設權限為 644 (full 666 - umask 022)
local_umask = 022
# 變更本機使用者登入後的預設根目錄
local_root = /var/ftp
匿名使用者
# 允許匿名者登入anonymous_enable = YES
# 限制匿名者的最大傳輸速度為 5Mbps (0 代表不限制)
anon_max_rate = 5000000
anon_max_rate = 5000000
# 匿名者登入不需要輸入密碼
no_anon_password = NO
anon_world_readable_only = YES
# 不允許匿名者擁有寫入之外的權限,如:重新命名、建立目錄、上傳 ...
anon_other_write_enable = NO
# 不允許匿名者建立新的目錄
anon_mkdir_write_enable = NO
# 不允許匿名者上傳
anon_upload_enable = NO
# 建立白名單,僅允許在清單裡的 E-Mail 做為密碼登入
secure_email_list_enable = YES
email_password_file = /etc/vsftpd/email_passwords
# 建立黑名單,禁止在清單裡的 E-Mail 做為密碼登入
deny_email_enable = YES
banned_email_file = /etc/vsftpd.banned_emails
# 匿名者新建目錄的預設權限 = 700 (full 777 - umask 077),新增檔案的預設權限為 600 (full 666 - umask 077)
anon_umask = 077
其他相關設定
防火牆
別忘了開啟防火牆的通訊埠,共分為控制命令跟資料傳輸的兩種用途。- 控制命令
預設是 TCP 21 Port。 - 資料傳輸
主動模式預設是 TCP 20 Port。
被動模式的話,則是需要管理者自行定義一個範圍。
sudo firewall-cmd --reload
如果有啟用被動模式的話,再加上指派給它的通訊埠範圍。
sudo firewall-cmd --zone=public --add-port=60101-61200/tcp
sudo firewall-cmd --reload
SELinux
跟 FTP 服務有關的規則如下,詳細說明請參 Linux man page - ftpd_selinux(8)。getsebool -a | grep ftp
- ftp_home_dir
- ftpd_anon_write
- ftpd_connect_all_unreserved
- ftpd_connect_db
- ftpd_full_access
- ftpd_use_cifs
- ftpd_use_fusefs
- ftpd_use_nfs
- ftpd_use_passive_mode
- httpd_can_connect_ftp
- httpd_enable_ftp_server
至少是否啟用這些規則,就得視實際需求來決定了。
chroot_local_user = YES 時,必須允許存取使用者的家目錄。
sudo setsebool -P ftp_home_dir 1
anon_upload_enable = YES 時,必須開放匿名者的寫入權限。
sudo setsebool -P ftpd_anon_write 1
允許 FTP 服務的完整存取權限。
sudo setsebool -P allow_ftpd_full_access 1
相關設定檔
/etc/vsftpd/ftpusers這個檔案用來列出絕對禁止登入 FTP Server 的本機使用者,預設的名單有 root 跟一些常見的本機服務帳號,像是 mail、sync、shutdown ... 之類的。
/etc/vsftpd/user_list
這個檔案要配合主設定檔的 userlist_deny 參數使用。
- userlist_deny = NO,白名單模式
只有在這個名單上的本機使用者才可以登入,其他人無法登入。 - userlist_deny = YES,黑名單模式
只有在這個名單上的本機使用者才禁止登入,其他人不受限制。
用戶端連線
先用 ftp client 指令在本機測試。
ftp localhost
在未修改主設定檔的狀況下,我們可以看到 root 無法登入,一般使用者及匿名者可以登入。
一般來說,除非在操作 Bash 且無法切換的狀況下,我們很少直接用指令來操作,通常會下載圖形介面的 FTP Client 程式,例如:FileZilla。
將 FileZilla 下載並安裝完畢之後,我們同樣試著連線到 vsFTPd Server 看看,發現本機使用者可以正常的連線,並且上傳檔案。
而匿名者預設則是可以下載,但是無法上傳。
而 root 的確無法連線。
注意事項
- 在主設定檔開放存取或寫入權限之後,卻忘了修改檔案系統裡的目錄權限、檔案權限、擁有者及擁有群組,或是忘了改 SELinux 的設定值,當然就會發生無法存取或無法寫入的問題。
- 主設定檔裡的很多設定值是有相依性的關係,有些會甚至會互相衝突,運作不正常的時候,別忘了再檢查一下。
- 匿名者以 E-Mail 為密碼的管理機制儘量少用,它僅僅是聊備一格,標準防君子不防小人的功能。
參考資料
圖片來源
- https://pixabay.com
更新紀錄
- 2016/8/26 撰文。
[sudo firewall-cmd --zone=public --add-port=60101-61200/tcp]應該要改為以下
回覆刪除[sudo firewall-cmd --permanent --zone=public --add-port=60101-61200/tcp]
不然不會永久有效。