2007-09-27

FTP Server 的安裝設定 (vsftpd & proftpd)

要對外提供檔案服務,除了在區域網路用的 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

ken 提到...

請教一下,小弟依照大哥的方法安裝了vsftpd,但是新增的帳號卻無法連進去ftp server中,用ssh連進去,直接輸入
ftp localhost
畫面出現

LinkStation:~# ftp localhost
NcFTP 3.2.0 (Aug 05, 2006) by Mike Gleason (http://www.NcFTP.com/contact/).
Connecting to 127.0.0.1...
(vsFTPd 2.0.5)
Login incorrect.
Sleeping 20 seconds...

也無法輸入帳號、密碼,不知是哪邊做錯了呢??

Abin 提到...

To Jui-Chien:
首先,你會用 ncftp 這個 ftp client 嗎?看起來你的 vsftp 有跑起來,你做錯的地方是,你 ncftp 語法錯誤(請先 google 看一下這個程式的用法)。
ncftp 和傳統 ftp 不一樣,它會要求你一定要先填入帳號才能登入,像是 ncftp -u 帳號 localhost,再則該帳號不能是 root。所以,如果你新增了帳號,你應該用 ncftp -u 你新增的帳號名稱 localhost,接著才會要你輸入密碼,然後成功登入。以上和 vsftp 都沒有關係。

ken 提到...

多謝大哥的回覆,小弟在windows端使用cuteftp來登入ftp,出現帳號密碼無法登入的現象??
但是若是開啟匿名登入,就沒有問題!
不知帳號部分該是如何設定呢??
我的作法是如同大哥所講的先新增一個使用者ken

useradd -s /bin/false -g users -d /share ken

更改目錄權限
chown -R ken /share/*
chgrp -R users /share/*

設定帳號 ken 的密碼
passwd ken

設定完成後,就是無法登入??
不知是哪邊做錯了呢??

ken 提到...

您好,小弟再度測試,發現FTP的服務應該是有啟動,但是帳號碼碼驗證不通過,已檢查過帳號確實有建立,有可能是密碼設定有問題!
passwd ken
這樣設定密碼不對嗎??

FTP登入畫面

LinkStation:/# ftp -u ken localhost
NcFTP 3.2.0 (Aug 05, 2006) by Mike Gleason (http://www.NcFTP.com/contact/).
Connecting to 127.0.0.1...
(vsFTPd 2.0.5)
Logging in...
Password requested by 127.0.0.1 for user "ken".

Please specify the password.

Password: ******
Login incorrect.
Could not open host localhost: username and/or password was not accepted for login.

ncftp>

ken 提到...

您好,改用proftpd就可以了!
不過卻有中文、Unicode顯示的問題!

Abin 提到...

To Jui-Chien:
文中我就說我是用 ProFTP 了。在 Linux 上中文目錄和 UTF 的問題一直都在,雖然現在漸漸也都有解決方案,不過在 LinkStation 上 Debian 跑的版本仍不能根絕,要根絕就要自己拿 Source Code Build 看看。不過,大部分 Big5 的中文還是都可以用(至少我都沒問題),將就著用還可以。

ken 提到...

多謝大哥不厭其煩的指教,小弟是根本不懂linux的,是跟著大哥的教學一步一步的改機,主要還是要使用p2p軟體,省點電費吧!
看來ftp就將就點用吧!謝謝!

Benson 提到...

教學的內容非常的詳細
非常的有參考價值
謝謝

張貼留言

歡迎留言或發表意見,不過要理性不做人身攻擊。匿名的朋友得到回應的速度會比較慢喔~
發問相關的禮貌和規矩請先參考這篇文章,不當留言、和本文無關的回應可能會被直接刪除無視喔!