[CentOS 7] 傳輸檔案的好伙伴,老當益壯的 FTP 伺服器 - vsFTPd

by 8月 26, 2016 1 意見        

或許你沒有特別注意過這件事,其實當我們在各個網站下載檔案的時候,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 年之後,才微改版二次而已。
(話說,有沒有可能是作者太忙,或是沒新梗的八卦......XD)

簡單的說,主要的優點有三個:
  1. 安全性
  2. 高效能
  3. 可靠性
安全性的部份,沒有實際遇到,可能無法難以驗證,不過像是 Redhat、SuSE、Debian、FreeBSD、KDE ... 這些大型商業公司或非營利組織,也是 vsFTPd 來架設 FTP Server,相信應該有一定的水準在。

而高效能跟可靠性到底有多強呢?
官方提到了這個實際例子,曾經在一台伺服器上,24 小時內讓 1500 個使用者同時上線,總流量大約傳輸了 2.6TB 左右。


事前準備


我們是以 CentOS 7.0 x86_64 Minimal 版為基礎,安裝步驟請參閱 CentOS 7.0 不完全安裝手冊 系列文章。

安裝服務


我們從 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

# 允許被動式傳輸,並指定可使用的通訊埠範圍為 TCP 60101 到 60200 埠
pasv_enable = YES
pasv_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

# 支援 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

# 匿名者登入不需要輸入密碼
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 --permanent --zone=public --add-service=ftp
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 撰文。

Heracles Jam,江湖人稱「海公公」

IT 技術家 - 創站部落客

一個常用 Windows、慣用 macOS、愛用 Linux 的 3C 阿宅
現職 MIS / 業界講師 / 資訊顧問 / 部落客

1 則留言 :

  1. [sudo firewall-cmd --zone=public --add-port=60101-61200/tcp]應該要改為以下
    [sudo firewall-cmd --permanent --zone=public --add-port=60101-61200/tcp]
    不然不會永久有效。

    回覆刪除