有一些很古老的教程,一般都是走編譯安裝路線的,本文是教你不需要編譯,而且随時都可以跟随 CentOS 更新 Proftpd 到最新版本,以避免可能的漏洞攻擊。利用 Proftpd 現成的配置以及設定好的各種子產品,可以實作 sftp 和 ssh 的結合,完美的實作虛拟使用者加密密碼存放于資料庫。
1. 安裝:
Proftpd 支援多種後端的資料庫存儲,在 CentOS7 上, 相關的軟體包有:
proftpd-devel.x86_64 : ProFTPD – Tools and header files for developers
proftpd-ldap.x86_64 : Module to add LDAP support to the ProFTPD FTP server
proftpd-mysql.x86_64 : Module to add MySQL support to the ProFTPD FTP server
proftpd-postgresql.x86_64 : Module to add PostgreSQL support to the ProFTPD FTP server
proftpd-sqlite.x86_64 : Module to add SQLite support to the ProFTPD FTP server
proftpd-utils.x86_64 : ProFTPD – Additional utilities
proftpd.x86_64 : Flexible, stable and highly-configurable FTP server
我們隻需要安裝
proftpd-mysql-1.3.5e-4.el7.x86_64
proftpd-1.3.5e-4.el7.x86_64
可以選擇安裝: proftpd-utils-1.3.5e-4.el7.x86_64
至于想了解包裡面的所有檔案, 可以用 # rpm -ql proftpd 這樣的指令來檢視。
2. 設定自動啟動:
# systemctl enable proftpd
# systemctl start proftpd
檢視狀态:
# systemctl status proftpd
3. 配置:
添加 ftp 使用者群組:
# groupadd -g 2001 ftpgroup
# useradd -u 2001 -g 2001 ftpuser
檢視基本子產品: # proftpd -l
檢視所有加載的子產品: # proftpd -vv
如果結果裡沒有看到 mod_sql_mysql,就對了, 那是因為我們還沒有把子產品加載。
檢視配置檔案的路徑: # proftpd -V , 可以看到 “Configuration File”指向 /etc/proftpd.conf
以下是我配置的一些核心的設定,其他沒有包含在裡面的,可以保留原來系統的配置。
LogFormat awstats “%t %h %u %m %f %s %b”
ExtendedLog /var/log/proftpd/transfer.log read,write awstats
TransferLog /var/log/proftpd/transfer.log
ServerLog /var/log/proftpd/server.log
ServerName “ProFTPD server”
ServerIdent on “FTP Server ready.”
ServerAdmin [email protected]
DefaultServer on
DefaultRoot ~ !adm
UseReverseDNS off
User ftpuser
Group ftpgroup
MaxInstances 20
UseSendfile off
LogFormat default “%h %l %u %t \”%r\” %s %b”
LogFormat auth “%v [%P] %h %t \”%r\” %s”
LoadModule mod_sql.c
LoadModule mod_sql_passwd.c
LoadModule mod_sql_mysql.c
LoadModule mod_quotatab.c
LoadModule mod_quotatab_sql.c
LoadModule mod_ctrls_admin.c
LoadModule mod_deflate.c
LoadModule mod_sftp.c
LoadModule mod_sftp_sql.c
LoadModule mod_vroot.c
<IfModule mod_vroot.c>
VRootEngine on
</IfModule>
<Global>
# 設定正确的時區,保證日志檔案裡的時間是目前時區。
SetEnv TZ “Asia/Shanghai”
Umask 022
# Allow users to overwrite files and change permissions
AllowOverwrite yes
<Limit ALL SITE_CHMOD>
AllowAll
</Limit>
ExtendedLog /var/log/proftpd/access.log WRITE,READ default
ExtendedLog /var/log/proftpd/auth.log AUTH auth
</Global>
# MySQL 相關的配置:
SQLBackend mysql
SQLEngine on
SQLAuthenticate on
SQLLogFile /var/log/proftpd/sql.log
# 這個 AuthTypes 網上的很多教程都是不對的。
SQLAuthTypes OpenSSL
SQLAuthenticate users* groups*
SQLConnectInfo MySQLUser@localhost MySQLDBName MySQLPassword
SQLUserInfo ftpuser userid passwd uid gid homedir shell
SQLGroupInfo ftpgroup groupname gid members
SQLMinUserGID 2001
SQLMinUserUID 2001
# SQLHomedirOnDemand on
# Update count every time user logs in
SQLLog PASS updatecount
# SQLLog PASS counter
SQLNamedQuery updatecount UPDATE “count=count+1, accessed=now() WHERE userid=’%u'” ftpuser
# Update modified everytime user uploads or deletes a file
SQLLog STOR,DELE modified
SQLNamedQuery modified UPDATE “modified=now() WHERE userid=’%u'” ftpuser
# User quotas
# ===========
#打開磁盤限額引擎
QuotaEngine on
#設定磁盤限額
QuotaDirectoryTally on
#設定測盤容量顯示時的機關
QuotaDisplayUnits Mb
#允許顯示磁盤限額資訊,ftp登陸後可執行 quote site quota 指令察看目前磁盤使用情#況
QuotaShowQuotas on
#設定磁盤限額日志檔案
QuotaLog “/var/log/proftpd/quota.log”
SQLNamedQuery get-quota-limit SELECT “name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = ‘%{0}’ AND quota_type = ‘%{1}'”
SQLNamedQuery get-quota-tally SELECT “name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = ‘%{0}’ AND quota_type = ‘%{1}'”
SQLNamedQuery update-quota-tally UPDATE “bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = ‘%{6}’ AND quota_type = ‘%{7}'” ftpquotatallies
SQLNamedQuery insert-quota-tally INSERT “%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}” ftpquotatallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
RootLogin off
RequireValidShell off
# =============== 配置 結束 ===============
4. MySQL 資料庫部分,可以直接儲存成 sql 檔案,用 mysql 資料庫名 < sql檔案 來導入表結構和示例使用者資料。
## 資料庫部分
CREATE TABLE `ftpgroup` (
`groupname` varchar(16) NOT NULL DEFAULT ”,
`gid` smallint(6) NOT NULL DEFAULT ‘2001’,
`members` varchar(16) NOT NULL DEFAULT ”,
KEY `groupname` (`groupname`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT=’ProFTP group table’;
INSERT INTO `ftpgroup` VALUES (‘ftpgroup’,2001,’ftpuser’);
CREATE TABLE `ftpquotalimits` (
`name` varchar(30) DEFAULT NULL,
`quota_type` enum(‘user’,’group’,’class’,’all’) NOT NULL DEFAULT ‘user’,
`per_session` enum(‘false’,’true’) NOT NULL DEFAULT ‘false’,
`limit_type` enum(‘soft’,’hard’) NOT NULL DEFAULT ‘soft’,
`bytes_in_avail` int(10) unsigned NOT NULL DEFAULT ‘0’,
`bytes_out_avail` int(10) unsigned NOT NULL DEFAULT ‘0’,
`bytes_xfer_avail` int(10) unsigned NOT NULL DEFAULT ‘0’,
`files_in_avail` int(10) unsigned NOT NULL DEFAULT ‘0’,
`files_out_avail` int(10) unsigned NOT NULL DEFAULT ‘0’,
`files_xfer_avail` int(10) unsigned NOT NULL DEFAULT ‘0’
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `ftpquotalimits` VALUES (‘exampleuser’,’user’,’true’,’hard’,15728640,0,0,0,0,0),(‘demo’,’user’,’false’,’soft’,104857600,0,0,0,0,0);
CREATE TABLE `ftpquotatallies` (
`name` varchar(30) NOT NULL DEFAULT ”,
`bytes_in_used` int(10) unsigned NOT NULL DEFAULT ‘0’,
`bytes_out_used` int(10) unsigned NOT NULL DEFAULT ‘0’,
`bytes_xfer_used` int(10) unsigned NOT NULL DEFAULT ‘0’,
`files_in_used` int(10) unsigned NOT NULL DEFAULT ‘0’,
`files_out_used` int(10) unsigned NOT NULL DEFAULT ‘0’,
`files_xfer_used` int(10) unsigned NOT NULL DEFAULT ‘0’
INSERT INTO `ftpquotatallies` VALUES (‘demo’,’user’,0,0,0,0,0,0);
CREATE TABLE `ftpuser` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`userid` varchar(32) NOT NULL DEFAULT ”,
`passwd` varchar(32) NOT NULL DEFAULT ”,
`uid` smallint(6) NOT NULL DEFAULT ‘2001’,
`homedir` varchar(255) NOT NULL DEFAULT ”,
`shell` varchar(16) NOT NULL DEFAULT ‘/sbin/nologin’,
`count` int(11) NOT NULL DEFAULT ‘0’,
`accessed` datetime NOT NULL DEFAULT ‘0000-00-00 00:00:00’,
`modified` datetime NOT NULL DEFAULT ‘0000-00-00 00:00:00′,
PRIMARY KEY (`id`),
UNIQUE KEY `userid` (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 COMMENT=’ProFTP user table’;
INSERT INTO `ftpuser` VALUES (1,’simon’,'{md5}md5password’,2001,2001,’/opt/ftphome/simon’,’/sbin/nologin’,0,’2018-02-18 19:48:48′,’0000-00-00 00:00:00′),(2,’simon2′,'{md5}uk7kAgOCIdt21o0YJ6grVg==’,2001,2001,’/opt/ftphome/simon2′,’/sbin/nologin’,4,’2018-02-18 20:35:04′,’0000-00-00 00:00:00′);
# =============== 資料庫部分 結束 ===============
5. 添加使用者的 shell 腳本,添加使用者需要插表,建立使用者目錄等,參照網上的腳本修改如下:
# cat /usr/local/bin/add_ftpuser.sh
#!/bin/bash
# Modified by Albert Xu <[email protected]>
#
usage () {
echo “”
echo ” USAGE: `basename $0` username user_home_dir “
echo ” e.g.: `basename $0` albertxu /opt/ftphome/albertxu “
echo ” Result:”
echo ” UserName: albertxu”
echo ” PassWord: N2Jy3Fqol”
exit
}
# == MySQL ========
MYSQL_USER=ftpd
MYSQL_PASS=MySQLP@ssw0rd
MYSQL_DB=ftpd
MYSQL_HOST=localhost
# ================
FTP_USER=ftpuser
FTP_UID=`id -u ${FTP_USER}`
FTP_GID=`id -g ${FTP_USER}`
FTP_GRP=`id -gn ${FTP_USER}`
# ===============
userid=$1
[ -z “${userid}” ] && usage
datetime=`date +”%Y-%m-%d %H:%M:%S”`
passwd=`mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1`
FTP_HOME=/opt/ftphome/${userid}
[ ! -d ${FTP_HOME} ] && mkdir -p ${FTP_HOME} && chown ${FTP_USER}.${FTP_GRP} ${FTP_HOME}
dst_passwd='{md5}’`/bin/echo -n “$passwd” | openssl dgst -binary -md5 | openssl enc -base64`
shell=’/sbin/nologin’
/bin/mysql -u ${MYSQL_USER} -p${MYSQL_PASS} -h ${MYSQL_HOST} ${MYSQL_DB} \
-e “INSERT INTO ftpuser (userid,passwd,uid,gid,homedir,shell,accessed) VALUES (‘$userid’,’$dst_passwd’,${FTP_UID},${FTP_GID},’${FTP_HOME}’,’/sbin/nologin’,’$datetime’);”
echo “UserName: $userid”
echo “PassWord: $passwd”
echo “userHome: ${FTP_HOME}”
echo “”
# =============== 添加使用者腳本 結束 ===============
6. 測試
重新開機 proftpd 服務後,用腳本添加使用者後,可以嘗試用 ftp 主機名 以及 ftp 主機名 22,端口來測試兩種方式的認證。
我們不需要在作業系統添加使用者,而是直接把使用者群組的配置通過資料庫實作,後端的資料庫使用者群組可以靈活的通過和其他應用整合,實作完美的安全 ftp 解決方案。 在 ftphome 的權限配置上,我們需要把所有 /opt/ftphome 下建立的使用者目錄群組的讀寫都設定為 ftpuser:ftpgroup 的 755 權限。在防火牆設定上,我們仍舊需要把 20/21 TCP 端口都打開。
很多人根據本教程可能會遇到資料庫連接配接問題,本人認為這些都是基本功,看過這個教程就應該明白資料庫的使用者怎麼設定了。