要對外提供檔案服務,除了在區域網路用的 Samba 之外,最常用的就屬 FTP Server 了。常見在 Linux 環境上用的 FTP Server 很多,舉凡像是 wu-ftpd, pureftpd, vsftpd 和 proftpd 都可以。wu-ftpd 是我第一個用、也用最久的服務,以前玩 FreeBSD 都用它來分享,但據說樹大招風、安全性堪慮,所以後來在 LinkStation 上面我一開始裝的是人家推薦的 vsftpd。vsftpd 顧名思義是 Very Secure 的 FTP Daemon,之前的經驗也很不錯,但是最討厭的,就是沒有一些簡易的查詢功能。假設我開 FTP Server,想知道現在有幾個人連進來、在做什麼,我只能去查 Log 檔。後來我又試用了另外一套 proftpd,嗯!果然是 Professional 的 FTPD,設定和參數複雜好多,為兼顧安全還有很多防堵機制,支援 Virtual Site 和類似 Apaceh .ftpaccess 的目錄權限控管機制,當然,最重要的也附了幾個公用程式供查詢使用,所以我就改用 proftp 囉!不過本文仍然保留兩種 FTP Server 的安裝和設定說明,要簡單的就裝 vsftpd,要複雜深入一點的就裝 proftpd,任君選擇(但是為了安全起見,兩個只挑一個就好,不要通通裝啊)。
1. vsftpd
在更新過 Package List 之後 (apt-get update),開始安裝 vsftpd:
apt-get install vsftpd
啊?這樣就裝好了?接下來改設定檔:
nano /etc/vsftpd.conf
...
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
local_umask=022
以上簡單的設定內容是,第一,不允許匿名的使用者登入,第二,允許本機其他合法帳號用 FTP 登入,第三,允許寫入的動作,最後一個,透過 FTP 登入後寫入檔目錄和檔案權限的設定。022 代表的是只有寫入的帳號自己能夠修改,其他人不能動,如果要同群組使用者都能變動的話,就要改成 002。其他詳細的參數請參閱鳥哥的說明。(真是草率)
接著重新啟動 vsftpd 就搞定了:
/etc/init.d/vsftpd restart
2. proftpd
一樣記得先更新 List,然後開始安裝 (Debian 官網也有說明,或是參考 proftpd 安裝使用手冊),不過切記裝過 vsftpd 再執行以下步驟是會有衝突的:
apt-get install proftpd
安裝過程會問你要裝成開機執行 (inetd) 還是手動執行 (Standalone) 的模式,請選 Standalone 的(如果選錯,一樣可以用 dpkg-reconfigure 來重新設定)。接下來會有些訊息,大意上是會幫你增加一個使用者 proftpd、把該帳號加到 nogroup 群組、程式裝到 /var/run/proftpd 目錄,並且又幫你建立匿名 FTP 用的帳號 (ftp)、群組 (nogroup) 和目錄 (/home/ftp),裝完試圖啟動服務的時候,可能會有以下的錯誤訊息(如果你有設 Host name,那 'localhost' 就會顯示你設定的名稱):
Starting ftp server: proftpd - IPv6 getaddrinfo 'localhost' error: Name or service not known
這個 IPv6 的問題有兩個解決方法,一個是透過設定檔關閉對 IPv6 的支援,另一個是在 /etc/hosts 裡面修改一筆記錄如下(把紅字部分改成你的 Server Name):
fe00::0 ip6-localnet localhost
無論如何,即使有錯誤訊息,FTP Server 也在跑了,在改設定之前我們先停掉服務,如果裝成 Standalone 模式,則用以下命令:
/etc/init.d/proftpd stop
如果是裝成 inetd 的開機啟動,則比較麻煩,要先找出 inetd 的 Process ID (ps aux | grep inetd)、砍掉 Process 才行 (kill -9 pid)。接下來修改設定檔:
nano /etc/proftpd/proftpd.conf
以下是我修改的部分內容,可以參考:
#======================= 預設設定 =======================
# Includes DSO modules
Include /etc/proftpd/modules.conf
MultilineRFC2228 on
DefaultServer on
ShowSymlinks on
DisplayChdir .message true
ListOptions "-l"
DenyFilter \*.*/
#======================= 站台設定 =======================
# 伺服器的名稱和啟動模式
ServerName "LinkStation"
ServerType standalone
# 伺服器啟動的服務帳號和群組
User proftpd
Group nogroup
# 連接埠
Port 21
# PassivePorts 49152 65534
# IPv6 支援
UseIPv6 off
# 關閉 Ident 和使用者網域反查
IdentLookups off
UseReverseDNS off
# 使用本地時間
SetEnv TZ :/etc/localtime
TimesGMT off
# 設定支援下載續傳、上傳續傳、支援 FXP
AllowStoreRestart on
AllowRetrieveRestart on
AllowForeignAddress on
# 預設檔案複寫設定
AllowOverwrite on
# 顯示站台歡迎訊息
DeferWelcome off
# 設定使用者登入和登出會看到的訊息檔
DisplayLogin /etc/proftpd/welcome.msg
DisplayQuit /etc/proftpd/logout.msg
# 指定站台系統 Log 位置
SystemLog /var/log/proftpd/proftpd.log
# 自己定義 Log 格式,紀錄登入 (login.log) 和傳檔 (transfer.log) 的細節
# TransferLog /var/log/proftpd/xferlog
LogFormat myxfer "%{%Y/%m/%d %H:%M:%S}t [%u] \"%m %f\" (%bB/%TS)"
LogFormat myauth "%{%Y/%m/%d %H:%M:%S}t [%u] \"%r\": %S (%a)"
ExtendedLog /var/log/proftpd/login.log auth myauth
ExtendedLog /var/log/proftpd/transfer.log read,write myxfer
#======================= 外掛模組 =======================
# 控制帳號下載容量限制模組
<IfModule mod_quotatab.c>
QuotaEngine off
</IfModule>
# 控制帳號上傳下載比例模組
<IfModule mod_ratio.c>
Ratios off
</IfModule>
# 安全性模組 (For Reducing Timing Attack)
<IfModule mod_delay.c>
DelayEngine on
</IfModule>
# 控制模組
<IfModule mod_ctrls.c>
ControlsEngine off
ControlsMaxClients 2
ControlsLog /var/log/proftpd/controls.log
ControlsInterval 5
ControlsSocket /var/run/proftpd/proftpd.sock
</IfModule>
# 管理模組
<IfModule mod_ctrls_admin.c>
AdminControlsEngine off
</IfModule>
# 語言編碼模組,關閉 LangEngine 預設會用 UTF-8
<IfModule mod_lang.c>
LangEngine off
</IfModule>
#======================= 連線和傳輸限制 =======================
# 最大連線數
MaxInstances 30
# 預設踢掉斷線時間,當沒有傳檔、連線停頓 10 分鐘或動作閒置 20 分鐘就斷線
TimeoutNoTransfer 600
TimeoutStalled 600
TimeoutIdle 1200
# 同主機只允許 2 個登入、同帳號只允許 3 個登入、最多只允許 5 個連線,以及其失敗的訊息
MaxClientsPerHost 2 "一台主機最多只允許 2 個登入!"
MaxHostsPerUser 3 "一個帳號最多允許 3 個登入!"
MaxClients 5 "連線數超過上限!"
# 設定使用者群組 (ftpuser) 的下載頻寬 (200K)
TransferRate RETR 200 group ftpuser
#======================= 存取設定 =======================
# 預設上傳目錄和檔案的讀寫權限,預設是 022,改成 002 表示屬同群組的帳號都可以更改
Umask 002
# 不允許 root 登入
RootLogin off
# 允許被設定成不得由遠端登入的帳號 (invalid shell) 能 FTP 進來
RequireValidShell off
# 只要不屬於 ftpuser 群組的人,可以離開自己的預設根目錄
DefaultRoot ~ ftpuser
# 預設關閉所有 SITE 命令以策安全
<Limit SITE_CHMOD>
DenyAll
</Limit>
以上請根據實際的需求狀況來調整,詳細參數也可以參考官方文件。
雖然我的設定檔裡大多已經附了中文註解,但有些東西可是精心調整過的,在這還是要說明一下(紅色的部份)。首先先看站台設定、登入和登出會看到的訊息,其中 welcome.msg & logout.msg 兩個訊息檔可以包含一些系統、登入和下載的狀況,以下是我做的登入歡迎訊息範例檔 (/etc/proftpd/welcome.msg,會顯示登入位址、伺服器時間、硬碟可用空間、目前路徑和連線數量):
Welcome %U from %R to %L site !
Current Time: %T
Available Capacity: %F KB
Current Directory: %C
Current/Max Allow Connection: %N/%M
以下則是登出的訊息檔 (/etc/proftpd/logout.msg,會顯示連線完,總共上傳和下載的檔案和容量):
Upload: %{total_bytes_in} bytes, %i files
Download: %{total_bytes_out} bytes, %o files
Bye Bye, %U from %R !
此外,「監看」FTP 狀態對開站是很重要的,除了預設的 SystemLog (/var/log/proftpd/proftpd.log),我自己定義了 Log 格式,搞了登入紀錄 (login.log) 和傳檔細節 (transfer.log) 的 Log 檔、取消原有的 TransferLog,讓系統的登入和使用者抓檔紀錄分開,也優化了裡面的格式,所以想看看誰沒事來登入、在 try 你的 FTP 站台,查看登入紀錄就行 (tac /var/log/proftpd/login.log | less),想知道誰貪婪了你什麼檔案,查看傳檔細節就能一目了然 (tac /var/log/proftpd/transfer.log | less)。如果常用這兩個命令的話,也可以直接在 /etc/profile 裡面新增兩筆 alias。
再來看看外掛模組的部份。需要特別解釋的,是關於 FTP 語系編碼的問題,之前提到我重灌的 Debian,用的都是標準 UTF-8 編碼,自然 FTP Server 供檔也要完全支援 UTF-8,首先要掛 mod_lang、讓 FTP Client 能自動偵測 FTP 站的編碼方式,所以在 FTP 程式連進來時,它能透過這個機制瞭解站台目錄和檔名的編碼方式,轉成正確的方式避免看到亂碼。接下來設定 FTP 語言編碼模組的預設值 (LangDefault zh_TW.UTF-8),這樣站台就能完全支援 UTF-8 囉!(當然 FTP Server 支援還不夠,FTP Client 抓檔程式一定也要支援,在這強力推薦一套 Freeware: FileZilla,不但完全支援 UTF、什麼中文日文檔名都沒問題,而且比照 CuteFTP 有的功能一樣都不少,重點還是免費 Open 的 Freeware,算是開站抓檔支援性最棒的工具!)最後是連線數量、傳輸頻寬的限制,不過以上都有詳細的範例和中文說明,設定調整應該不是什麼問題~
設定檔都搞定就可以啟動服務了。如果是 Standalone 就是以下命令:
/etc/init.d/proftpd start
如果是裝成 inetd 的,就重新執行:
/usr/sbin/inetd
另外在裝 proftpd 完,系統也多了幾個公用程式,像是 ftpshut,可以用來定期開關 FTP 服務(參數和用法請看鳥哥的教學文章),而 ftpcount 則是顯示目前 FTP Server 的連線數量,最後 ftpwho 可以顯示有誰正在線上、正在做什麼,這些實用的公用程式有助於監看服務的狀態(當然,也可以透過上面提到的自訂 Log 檔內容來知道)。
最後,要來討論帳號和權限的問題。我的作法是有一個 FTP 管理者的帳號 (admin),它沒有合法的 Shell (/bin/false),登入後目錄就是 FTP 的根目錄 (/home/ftp),它和其他服務的帳號 (samba, mldonkey, www) 和一般使用者都屬於同一個群組 (users),整個 FTP 根目錄權限都是同群組可讀寫 (chmod -R g+w /home/ftp),而且目錄權限都屬於 FTP 管理者 (chown -R admin:users /home/ftp/*)。所以我自己使用 FTP 的時候,都用這個帳號來登入,不但可以管理目錄,也可以和其他服務的檔案分享。由於我不打算開放匿名登入,匿名這一段的設定就跳過。最後要設定一些「親朋好友」的帳號,彼此之間的檔案才能互通有無,我的作法是另外設定一個群組 (ftpuser),然後新增 FTP 專用的帳號都設到這個群組,一方面在做 FTP 限制的時候可以用群組來做,另外因為 ftpuser 和 users 分屬不同帳號,所以只能讀取分享的目錄檔案無權刪除修改,只要目錄設定好,以後只要新增帳號就可以開放 FTP 給大家使用了。
有了以上的目錄權限安排,又新增一個專用的群組 (groupadd ftpuser,可以看到,我上面的設定檔有些限制就是對這個群組下的),假設要新增一個 FTP 專用的測試帳號 ftptest,命令如下:
useradd -s /bin/false -g ftpuser -d /home/ftp ftptest
這個帳號只能用 FTP 登入,受限於 ftpuser 的權限限制,登入後會在 /home/ftp 這個 FTP 根目錄下,而目錄存取權限就單純取決於實際的群組和帳號目錄權限。拿上面設定檔的範例來看,這個群組的成員,有下載頻寬限制 (TransferRate RETR 200 group ftpuser,200K),除了 FTP 目錄,也不允許離開預設根目錄 (DefaultRoot ~ ftpuser),像這樣在管理上,就有了很大的彈性。除了實體帳號對目錄存取的權限外,proftpd 也有自己對目錄存取設限的語法,以上面範例的狀況來看,既然我開放整個 FTP 目錄 (/home/ftp) 讓「會員」存取,但可能下面有幾個目錄,是不准 18 歲以下的人「看到」的,假設有個目錄叫 /home/ftp/AV、我不想給帳號 ftptest 這個人看到,只要在設定檔最後面補上這一段設定:
# 限制特定目錄不給看
<Directory /home/ftp/AV>
<Limit All>
DenyUser ftptest
</Limit>
</Directory>
這樣帳號 ftptest 就完全看不到 AV 的目錄了。還有一個例子實際存取權限和 proftpd 設定混用的狀況,像是 Upload 目錄、希望大家都夠上傳寫入檔案,因此必須開放該目錄的寫入權限:
chmod -R o+w /home/ftp/Upload/
但開放寫入權限、就沒法避免所有人去砍檔案(A 上傳到 Upload 區的檔案可能被 B 給砍掉),上面提到我有個 FTP 管理者的帳號 (admin),它屬於一般使用者群組 (users),我希望除了該群組的成員外其他帳號在該目錄都沒有砍檔權限(即使是上傳的那個人),只要在設定檔最後面補上這一段設定:
# 限制上傳目錄不給砍檔和更名
<Directory /home/ftp/Upload>
<Limit RNFR RNTO RMD DELE>
AllowGroup users
DenyAll
</Limit>
</Directory>
這樣就阻擋了一般 FTP 會員(屬於 ftpuser 群組)砍檔的權利,賦予一般使用者(屬於 users 群組,包含 admin 管理員帳號)管理上傳區的能力。以上是 FTP Server 安裝設定的詳細步驟,其實要提供服務都很簡單,但比較麻煩的是服務之間目錄檔案的權限和帳號設定,我利用的關鍵是 Linux 同群組開放完全存取權限、搭配 FTP Server 提供的彈性,而 FTP 其他使用者是用另外獨立的群組來套用限制,這些邏輯在我其他安裝到 LinkStation 上的服務都是共通的,也是我 try & error 多次調整出來的經驗(一般介紹文都不提),搞定之後不但有快速高效率的檔案分享服務,和其他像網路芳鄰等服務混用的時候也不會綁手綁腳,實際使用上也才更有彈性。
回應: 8