Linux · 2013-12-03

Ubuntu下使用Pure-ftpd 透過 MySQL管理虛擬FTP用戶帳號

應用趨勢
Pure-ftpd是一個很方便管理的FTP伺服器
我們利用它來提供基本的FTP服務是很容易的
在 Ubuntu 下它有幾個安裝類型選擇
(他們間彼此互斥..只能裝一類)

1.原始而單純的用法(和系統的實體帳號有關)
這種用法您只要安裝 pure-ftpd 就好了
sudo apt-get install pure-ftpd

2.配合 MySQL資料庫 作為認證的用法(和系統實體帳號無關)
這種用法您要安裝 pure-ftpd-mysql
sudo apt-get install pure-ftpd-mysql

3.配合 PostgreSQL資料庫 作為認證的用法(和系統實體帳號無關)
這種用法您要安裝 pure-ftpd-postgresql
sudo apt-get install pure-ftpd-postgresql

4.配合 LDAP資料庫 作為認證的用法(和系統實體帳號無關)
這種用法您要安裝 pure-ftpd-ldap
sudo apt-get install pure-ftpd-ldap

其實 proftpd 也有類似的作法..它可以提供的配合類型
還要多2種
proftpd-mod-ldap proftpd-mod-pgsql
proftpd-mod-mysql proftpd-mod-sqlite
proftpd-mod-odbc

OK 瞭解 FTP 伺服器的應用趨勢後
我們再回過神來專注在 我們今天的主題之內
利用 pure-ftpd-mysql 去建立一個具有虛擬帳號管理功能的FTP伺服器

虛擬帳號

先談談虛擬帳號,為何不要用真實帳號
在使用 Linux 主機時,有人要傳送檔案到伺服器上
一般我們會開立一個實體帳號,讓這個使用者使用
而這樣的作法,通常讓這個帳號可以登入到主機內,
而這些帳號,通常也是駭客下手的目標之一
(一般的使用者注重安全的程度通常遠低於系統管理員)

當然的,他也能在上面執行一些程式或作其他的事。
一般Linux主機是難以被攻擊的,但是如果攻擊者
有這樣的權限,可以合法的進到主機內時,他要取得
最高管理員的權限只是時間的問題了。
所以一般的管理員不輕易的將實體帳號開設出去。
因此建立一個只讓虛擬帳號可以上傳下載的 FTP 伺服器
變的更能符合資訊安全的須求。

OK!瞭解了這些背景,我們就向實作的階段出發吧!

實作過程

一、基本設定

1.Ubuntu 下安裝 pure-ftpd-mysql
打開終端機或連線到您的 Ubuntu 主機
輸入下列指令
sudo apt-get install pure-ftpd-mysql
它就會將必要的相關套件一併裝上

2.設定安全性
PS:接下的操作您只要複製英文指令到終端機內執行即可
sudo -i
先變為 root

echo “yes” > /etc/pure-ftpd/conf/ChrootEveryone
意思是建立一個ChrootEveryone的檔案內容為yes
就是限制 FTP 登入後的帳號只能在自己的家目錄內活動

echo “no” > /etc/pure-ftpd/conf/PAMAuthentication
不由PAM認證,僅單純的透過MySQL去認證
如果這裡改為”yes”,則實體帳號者也能登入。

echo “no” > /etc/pure-ftpd/conf/UnixAuthentication
不由系統認證,僅單純的透過MySQL去認證

echo “yes” > /etc/pure-ftpd/conf/NoAnonymous
不讓匿名用戶登入

echo “yes” > /etc/pure-ftpd/conf/CreateHomeDir
登入後沒有家目錄會自行建立(似乎只能用在實體帳號上)

上述配置後請重新啟動
/usr/bin/service pure-ftpd-mysql restart

上述綠色部分為您要在終端機輸入的指令
到目前為止是沒有任何人可以登入FTP的,
因為我們連資料庫的連線都還沒設定,PureFTP根本還連不到資料庫,
更不用說可以取到資料表的帳號資料去認證了。

二、資料庫設定與配置

資料庫連線的配置檔在/etc/pure-ftpd/db/mysql.conf 內
(檔案內所有前面有#號的行表示是註解)
所以這個檔案雖然內容很多,但其實只有下面幾行才是被使用到的設定:
下面是一個 Ubuntu 系統安裝 pure-ftpd-mysql 後
在/etc/pure-ftpd/db/mysql.conf 內資料庫連線配置檔的預設值。

MYSQLSocket /var/run/mysqld/mysqld.sock
MYSQLUser root
MYSQLPassword rootpw
MYSQLDatabase pureftpd
MYSQLCrypt cleartext
MYSQLGetPW SELECT Password FROM users WHERE User=”\L”
MYSQLGetUID SELECT Uid FROM users WHERE User=”\L”
MYSQLGetGID SELECT Gid FROM users WHERE User=”\L”
MYSQLGetDir SELECT Dir FROM users WHERE User=”\L”

以下我們逐行解說其設定內容:
MYSQLSocket /var/run/mysqld/mysqld.sock
這行說明 MySQL 接口的位置,除非您是自行編譯的..否則不須改變它。

MYSQLUser root
這行是指連線到資料庫的帳號,我們可以依照採用root帳號即可。

MYSQLPassword rootpw
這行是指連線到資料庫帳號所用的密碼,您要配合您的資料庫密碼作改變
這是基本用法下..您唯一要變更的地方。

MYSQLDatabase pureftpd
這行是指連線到資料庫後,要使用的資料庫名稱,如果您依本文操作您也不須作改變。

MYSQLCrypt cleartext
這行是指虛擬用戶的密碼,要使用何者編碼方式,如果您依本文操作您也不須作改變。
可用的設定值有下面幾個
cleartext 明碼(不額外編碼) md5 使用MD5編碼加密 crypt 用DES編碼加密
password MySQL的編碼加密
any 指可以視資料庫欄位定義而自動擇用md5、crypt或 password三種編碼方式。

接下4行設定都是資料庫語法。
MYSQLGetPW SELECT Password FROM users WHERE User=”\L”
上述表示當虛擬帳號符合User欄位時,選取登入者的密碼欄。

MYSQLGetUID SELECT Uid FROM users WHERE User=”\L”
上述表示當虛擬帳號符合User欄位時,選取登入者的使用者ID。
當使用者登入後儲存檔案都會有這種使用者ID、為了安全性起見
您要避免用系統使用的ID。

MYSQLGetGID SELECT Gid FROM users WHERE User=”\L”
上述表示當虛擬帳號符合User欄位時,選取登入者的群組ID。

MYSQLGetDir SELECT Dir FROM users WHERE User=”\L”
上述表示當虛擬帳號符合User欄位時,選取登入者的家目錄(檔案存取目錄)。
這意味著我們可以在資料表的 Dir 欄位內,任意設定使用者的檔案存取目錄。
好夢幻的功能,真令人激賞。

上述的用法都只用到了”\L”,而”\L”表示通過認證後的使用者帳號。
除了”\L”外,pure-ftpd 還提供了 \I、\P、\R、\D 四個符號。
分別表示如下:
\I (目的)虛擬帳號連線的IP
\P (目的)虛擬帳號連線通訊埠(21埠)
\R (來源)虛擬帳號從那個IP連線過來的
\D (來源)虛擬帳號從那個IP連線過來的,同上,但以數位表示。

依上述所言,我們認證的資料庫 pureftpd 內,
須有一個資料表叫users,資料表內
至少須具有五個欄位 User,Password,Uid,Gid,Dir
這樣才能運作起來,下面為整理出的建表語法。

CREATE TABLE `users` (
`User` varchar(16) NOT NULL DEFAULT ”,
`Password` varchar(64) NOT NULL DEFAULT ”,
`Uid` varchar(11) NOT NULL DEFAULT ‘-1’,
`Gid` varchar(11) NOT NULL DEFAULT ‘-1’,
`Dir` varchar(250) NOT NULL DEFAULT ”,
PRIMARY KEY (`User`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

搞清楚這些先前知識後,接著我們要開始來建立資料庫及資料表了

[操作指令]
mysql -u root -p
Enter password: (輸入資料庫root密碼後按確定)

在大於提示符下輸入
CREATE DATABASE pureftpd;[按確定]
USE pureftpd;[按確定]

將建表語法複製貼上後再按確定

回顧這部分我們僅須做3個動作

1.改設定檔內的資料庫密碼
2.登入到資料庫內建立一個pureftpd資料庫
3.建立資料表

這三部分都完成了,您可以重新啟動pureftp伺服器
service pure-ftpd-mysql restart

接著您可以簡便的利用phpMyAdmin去建立帳號
再利用建立的帳號測試登入看看。

If you want to use uid and gid of www-data, it doesn’t work. Because by fault in Debian the minimum uid is 1000. You will see the following error.

Client side:

$ ftp example.com
Connected to example.com.
220———- Welcome to Pure-FTPd [privsep] [TLS] ———-
220-You are user number 1 of 50 allowed.
220-Local time is now 14:28. Server port: 21.
220-This is a private system – No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (example.com:haoyu): site.example.com
331 User site.example.com OK. Password required
Password:
530 Sorry, but I can’t trust you
Login failed.
Remote system type is UNIX.
Using binary mode to transfer files.
Server side in /var/log/ftp.log:

Sep 17 14:46:25 sd-xxxxx pure-ftpd: ([email protected]) [INFO] New connection from defxx-x-xx-xxx-xx-xxx.fbx.proxad.net
Sep 17 14:46:32 sd-xxxxx pure-ftpd: ([email protected]) [WARNING] Can’t login as [site.example.com]: account disabled
The solution is to modify /etc/pure-ftpd/conf/MinUID value from 1000 to 33. I suggest to disable PAM authentication (system user login) by write “no” in file /etc/pure-ftpd/conf/PAMAuthentication. :!:Don’t forget to restart Pure-FTPd server.

[ERROR] Home directory not available – aborting

Even you have put ‘yes’ in /etc/pure-ftpd/conf/CreateHomeDir, Pure-FTPd will not create the user root directory, and you got ”[ERROR] Home directory not available – aborting” in your syslog. The solution is change the owner to root of the last existing directory in the home path. For example:
The user root directory is /home/ftp/user01 and /home/ftp should own be root

# ls -al /home/
# drwxr-xr-x 4 root ftp 4096 jui 4 21:57 ftp