在 CentOS 5 上透過 VSFTPD 及 MySQL 應用虛擬戶口
0.0.1. 採用虛擬用戶對比本地用戶的好處
- 在資料庫內儲存用戶名稱及密碼,就算對 Unix 的安全性模式不熟識的管理員亦能作出管理。
除了為新用戶初次建立子目錄,你無須分享系統的 root 權限。透過 sudo 及一些腳本,你可以避免無限地將系統的 root 權限賦予那些看管系統的非管理級用戶。沒錯,你甚至可以單單授權給 MySQL 外的 root 用戶權限去修改 vsftpd 的 ACL 資料庫,藉此提高安全性,縱使這種做法已經超越了本文章的範圍。
你無須將擁有指令殼的本地戶口給那些只需存取 FTP 的用戶。正因如此,你減低了暴露於駭客前的機會,從而降低被入侵的風險。對於那些像 ftp 以純文字作登入憑證的協議來說,這點尤其重要。
所有用戶的資料都儲存在同一目錄樹內,按需要選擇性地採用個別用戶的 ACL 設定。備份及復原的目標便簡化為目錄樹內的子集,而不像預設的模式般把本地 FTP 戶口及指令殼戶口夾雜在 /home/ 目錄下。
MySQL 的安全性模式可以透過用戶級的 ACL 權限保護它的資料庫;根據慣例,MySQL 內的 root 用戶是 ACL 資料庫的超級用戶,他被賦予權限讀出、寫入、及修改該資料庫。我們亦會跟隨這個慣例,在這個範例中採用 MySQL 的 root 用戶。這個戶口將會擁有自己的密碼(有別於系統的 root 戶口)。
這樣做能防止 mysql 被入侵後,洩漏可用來入侵系統 root 戶口的憑證,進而操控伺服器。此外,這亦能防範密碼從 MySQL 資料庫備份中被解讀出來,或者管理員錯誤地使用純文字作為資料庫的密碼。一條簡單的原則是:切勿在擁有特殊權限的戶口「重用」密碼。
1. 先決條件 -> 函式庫:pam_mysql.so
你會須要 VSFTPD 及 MySQL(假如它們仍未被安裝)。以系統的 root 身份,執行以行指令來安裝標準 CentOS 軟件庫內的套件:
# yum install vsftpd mysql-server
接著,啟動仍未被執行的 mysqld:
# /sbin/service mysqld restart
請為 MySQL 資料庫的 root 用戶設定一個密碼(假若你仍未如此做):
# mysqladmin -u root password 'yourrootsqlpassword'
請把你為 MySQL 的 root 用戶所設的密碼替代 'yourrootsqlpassword'(不需括號)。
1.1. 為 vsftpd 建立 MySQL 資料庫
從此起你已不再需要系統的 root 權限。請進入 MySQL 的指令殼:
$ mysql -u root -p
請輸入 yourrootsqlpassword —— 請注意:你在 MySQL 中的 root 用戶密碼應該是別的,而不應該是 yourrootsqlpassword 。
現在於 MySQL 的指令殼內為虛擬的 vsftpd 用戶建立一個資料庫:
mysql> CREATE DATABASE vsftpd; mysql> GRANT SELECT ON vsftpd.* TO 'vsftpd'@'localhost' IDENTIFIED BY 'vsftpdpassword'; mysql> FLUSH PRIVILEGES;
繼續在 MySQL 的指令殼內,改用剛建立的資料庫,然後建立所需的列表(當中只有一個列表,包含著用戶名稱及 MD5 加密的密碼)。
mysql> USE vsftpd; mysql> CREATE TABLE `accounts` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `username` VARCHAR( 30 ) NOT NULL , `pass` VARCHAR( 50 ) NOT NULL , UNIQUE (`username`) ) ENGINE = MYISAM ;
現在你可以離開 MySQL 的指令殼:
mysql> exit;
1.2. 設定 VSFTPD
建立一位名叫 vsftpd、隸屬於 users 群組的非特殊用戶(主目錄位於 /home/vsftpd)。vsftpd 可以採用這位用戶的身份來執行,進一步減低系統的風險。我們的虛擬用戶的 FTP 目錄將會在 /home/vsftp 目錄之內(例如:/home/vsftpd/user1、/home/vsftpd/user2、等)或根據 VSFTPD個別用戶設定檔 而定。
# useradd -G users -s /bin/false -d /home/vsftpd vsftpd
接著修改 VSFTP 的設定。首先,將原先的 /etc/vsftpd.conf 檔案備份:
# cp -v /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf-orig
然後作出修改:我們會先倒空現有的檔案,然後開啟它來編輯:
# > /etc/vsftpd/vsftpd.conf # vi /etc/vsftpd/vsftpd.conf
vsftpd.conf 內的設定(將它們抄進檔案內):
# 拒絕 ANONYMOUS 用戶 anonymous_enable=NO # 允許擁有寫入權限(0755)的本地用戶 local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES # 如果你想記錄 vsftpd 的動靜,請除去 log_ftp_protocol 的註釋 # log_ftp_protocol=YES connect_from_port_20=YES # 如果你沒有採用以上的 log_ftp_protocol 行,請除去 xferlog_file 及 # xferlog_std_format 的註釋 —— 它們是互相排除的 # 當 xferlog_enable=YES 及 xferlog_std_format=YES 時所採用的檔案名稱 # 警告 —— 更改這個檔名影響 /etc/logrotate.d/vsftpd.log #xferlog_file=/var/log/xferlog # # xferlog_std_format 切換記錄是放進 vsftpd_log_file 還是 xferlog_file 檔案內。 # NO 寫入 vsftpd_log_file,YES 寫入 xferlog_file # xferlog_std_format=YES # # 你可以更改工作階段閒置時限的預設值(以秒計算)。 #idle_session_timeout=600 # # 你可以更改連線時限的預設值(以秒計算)。 #data_connection_timeout=120 # # 請為指定一個在系統上是完全被隔離、沒有特權、及可供 ftp 伺服器使用的用戶。 nopriv_user=vsftpd chroot_local_user=YES listen=YES # 在這裡我們採用 vsftpd 的憑證模塊來檢查用戶名稱及密碼 pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES # 在這裡 vsftpd 會允許 vsftpd 這個用戶登入 /home/vsftpd/$USER 這個目錄 guest_enable=YES guest_username=vsftpd local_root=/home/vsftpd/$USER user_sub_token=$USER virtual_use_local_privs=YES user_config_dir=/etc/vsftpd/vsftpd_user_conf
借著 user_config_dir 這個選項,你可以為個別用戶設定檔指定一個目錄,用來置換某些總體設定。這純屬選擇性,你可決定是否應用該功能。
無論如何,現在就建立這個目錄:
# mkdir /etc/vsftpd/vsftpd_user_conf
舉個例說:你想 user1 的主目錄位於 /home/vsftpd/user1 以外的地方,請建立 vsftpd 的個別用戶設定檔:
# vi /etc/vsftpd/vsftpd_user_conf/user1
並將設定放在其中:
dirlist_enable=YES download_enable=YES # user1 可存取的完整目錄路徑,請按你所需作出修改 local_root=/home/users/user1 write_enable=YES
要讓這位用戶登入,你必須建立 user1 這個目錄!
# mkdir /home/users/user1
還有就是將讀、寫的權限賦予 user1:
# chmod 700 /home/users/user1 # chown vsftpd.users /home/users/user1
於是 user1 的主目錄便在 /home/users/users1 而不是 /home/vsftpd/user1,你更可以按需要在個別用戶設定檔內作出修改。
現在你必須設定 PAM,使它利用 MySQL 資料庫來驗證你的虛擬 FTP 用戶,而不是採用預設的 /etc/password 及 /etc/shadow。
vsftpd 的 PAM 設定放置在 /etc/pam.d/vsftpd。請照以下方法將它備份並如下建立一個新檔案:
# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd-orig # cat /dev/null > /etc/pam.d/vsftpd # vi /etc/pam.d/vsftpd
問題:為何在這裡用 cat?之前便用了一個更簡單的方法來倒空檔案。是否有 SELinux、或權限方面的理由而無法以 mv 及 touch 取代?若假如此,為何不說清楚並描述所需的值?
/etc/pam.d/vsftpd 的內容(註:當你複製它時應該只有 3 行):
#%PAM-1.0 session optional pam_keyinit.so force revoke auth required pam_mysql.so user=vsftpd passwd=vsftpdpassword host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3 account required pam_mysql.so user=vsftpd passwd=vsftpdpassword host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3
請確定你已經將 MySQL 的 vsftpdpassword 密碼改為你在「為 vsftpd 建立 MySQL 資料庫」內所設定的那一個
現在是要令這一切在 CentOS 下運作的最微妙部份!
問題:這段編輯備註應該在這裡出現嗎?
你需要 pam_mysql.so 這個函式庫,但它並不包含在 CentOS 的安裝或 YUM 內,因此你需要用 RPM 安裝它(或 EPEL 軟件庫 …… 或任何你喜歡的方法)。
請找尋 pam_mysql 這個 RPM 套件並下載它(你可以簡單地用 wget),截至本文,它被收錄在 pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm
然後安裝它:
rpm -Uvh pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm
它安裝時應該不會導致警告或錯誤 …… 否則 …… 我建議你利用 google 搜尋器來找個方法安裝它!
問題:這段編輯備註應該在這裡出現嗎?
安裝完成後,你應該可以找到:
# ls -al /lib/security/pam_m* -rwxr-xr-x 1 root root 8024 Sep 4 00:51 /lib/security/pam_mail.so -rwxr-xr-x 1 root root 15848 Sep 4 00:51 /lib/security/pam_mkhomedir.so -rwxr-xr-x 1 root root 3892 Sep 4 00:51 /lib/security/pam_motd.so -rwxr-xr-x 1 root root 36920 Feb 28 2008 /lib/security/pam_mysql.so
它就在這個範例的最後一行!(可能會有更多檔案,但上面的清單應該都存在)
以下步驟對於以 MySQL 資料庫來驗證虛擬用戶是非常重要的
現在我們要建立首位虛擬用戶
你可以用 MySQL 指令殼將用戶加進資料庫內:
$ mysql -u root -p
這輸入密碼 …… 然後在 SQL 指令殼內:
mysql> USE vsftpd;
採用 vsftpd 這個資料庫
現在建立 user1 這個虛擬用戶,並設定 secret 這個密碼(它會被 MySQL 的 MD5 函式來加密然後儲存):
mysql> INSERT INTO accounts (username, pass) VALUES('user1', md5('secret'));
現在你應該有一位用戶在資料庫內:
mysql> select * from accounts; +----+-----------+----------------------------------+ | id | username | pass | +----+-----------+----------------------------------+ | 1 | user1 | 5ebe2294ecd0e0f08eab7690d2a6ee69 | +----+-----------+----------------------------------+ 1 rows in set (0.00 sec) mysql> exit;
註:密碼的散值只作說明之用,實際數值可能會有差別
現時 user1 的主目錄位於 /home/vsftpd/user1。可惜 vsftpd 不會自動建立未存在的目錄。因此現在你要以 root 身份建立它,並設定 vsftpd 及 users 這個群組為它的擁有人:
# mkdir /home/vsftpd/user1 # chown vsftpd:users /home/vsftpd/user1
現在重新啟動 VSFTPD
# /sbin/service vsftpd restart
你應該可以透過任何乎合 RFC 規格的 FTP 客戶端登入這個 FTP 伺服器。
註:上面引述的設定檔同時用 21 及 20 號 FTP 埠(作操控及數據連線);有些網絡設置(早期 Windows 有關靜態 FTP 的 互聯網選項;某些 NAT 的設計;某些代理伺服器)不能通過第二個連接埠。若是如此,設定檔便須要有以下修訂,而 FTP 伺服器須要重新啟動:
# connect_from_port_20=YES connect_from_port_20=NO
2. 如何在將來有需要時加入更多用戶……只須簡單的 2 步:
將新用戶加進資料庫:譬如 user12 與 secret12 這個密碼(你亦可以建立電郵地址般的戶口作登入之用,例如: user12@example.com )﹕
進入資料庫的指令殼;
$ mysql -u root -p
然後在 SQL 指令殼執行:
mysql> USE vsftpd; mysql>INSERT INTO accounts (username, pass) VALUES('user12', md5('secret12')); mysql> exit;
新增 user12 的主目錄,這個步驟需要系統的 root 權限:
# mkdir /home/vsftpd/user12 # chown vsftpd:users /home/vsftpd/user12
Translation of revision 11