本文在参考网络上部分前辈的一些经验后,加入自身实践所做。感谢前辈们的分享精神。
一、Ftp账号的三种实现方式
1.匿名用户;2.本地用户;3.虚拟用户(数据库存储用户信息)
二、 虚拟用户账号是如何实现验证
用MySQL数据库进行虚拟用户认证,它利用数据库来提供用户及其认证,将Ftp的账号映射于系统用户,从而避免了使用系统用户。
三、系统环境
OS:Ubuntu 12.04LTS
Other: gcc4.6
mysql-5.1.68.tar.gz
proftpd-1.3.5rc2.tar.gz
本文中用到的MySQL和ProFTPd都是源码编译安装。
注意1:请确保gcc版本较新。通过apt-getinstall build-essential安装最新的gcc。
注意2:本文的操作全部在控制台root权限下进行。
四、安装MySQL-5.1(熟悉的话可忽略)
注意1:请确保MySQL是5.1或者以下版本。
apt-get方式下载安装的MySQL-5.5中的libmysqlclient.so.18与ProFTPd不兼容。
注意2:请确保系统中已安装ncurses软件包,该包是编译安装MySQL不可缺少的。可以通过以下命令在线安装:
# apt-get install libncurses5-dev
1. 建立用户和工作组
建立工作组,组名为mysql
# groupadd mysql
建立用户,名为mysql,属于名为mysql的工作组
# useradd ?g mysql ?r mysql
2. 配置
解压mysql-5.1.68.tar.gz后进入解压出的目录中。
可以根据自身需要增加一些选项,这里只做一些简单的个性化配置,未配置的选项则为默认配置。
# ./configure \
--prefix=/usr/local/mysql \
--with-mysqld-user=mysql \
--localstatedir=/usr/local/mysql/data \
--with-unix-socket-path=/usr/local/mysql/tmp/mysql.socket
将MySQL安装在/usr/local/mysql目录中;用户指定为mysql;MySQL的数据文件保存在/usr/local/mysql/data目录中; socket文件安装在/usr/local/mysql/tmp/下,命名为mysql.socket。
3. 编译安装
# make
如果你系统中缺少ncurses包的话,将出现error;
# make install
4. 配置与相关设定。
(1)设置目录权限
# cd /user/local/mysql
把当前目录中所有文件的所有者设为root,所属组为mysql,请注意最后的一个”.”符号,表示当前目录。
# chown ?Rroot:mysql .
把data目录下的所有文件所有者设为root,所属组为mysql,请注意data目录为当前的/usr/local/mysql目录下的用于存放数据库文件的目录,如果尚未建立,请手动mkdir data。
# chown ?Rmysql:mysql data
将/usr/local/mysql目录下所有文件为工作组mysql所有。
# chgrp ?R mysql/usr/local/mysql
(2)建立my.cnf配置文件
复制预设配置文件即可。在mysql-5.1源码目录下:
# cp support-files/my-medium.cnf/etc/my.cnf
(3)建立GRANT表
# /usr/local/mysql/bin/mysql_install_db?user=mysql
(3)设置环境变量
# vim /etc/profile
加入 PATH=$PATH:$HOME/bin:/usr/local/mysql/bin:/usr/local/mysql/lib
重新启动后生效。
(4)手动启动mysql
# cd /usr/local/mysql/bin
# ./mysqld_safe?user= mysql &
初始化并测试你的mysql,&为后台执行的意思。
为数据库管理员设置密码(改密码仅对数据库有效),密码为123
# ./mysqladim ?uroot password 123
关闭服务
# ./mysqladim ?uroot ?p 123 shutdown其中123为数据库管理员root的密码
(5)加入随系统自动启动
将mysql的启动服务添加到系统服务中。
在mysql-5.1源码目录下:
# cp support-files/mysql.server/etc/init.d/mysql
# chmod +x/etc/init.d/mysql
# update-rc.dmysql defaults
自此,mysql服务将随系统启动而自动启动,并且可以通过
# service mysqlstart
# service mysqlstop
# service mysqlrestart
来进行更加方便的手动开始、停止、重启mysql服务。
(6)验证是否成功开启
# ps ?e|grep mysql
1664 pts/2 00:00:00 mysqld_safe
1690 pts/2 00:00:00 mysqld
# netstat ?ntulp|grepmysql
tcp 0 0 0.0.0.0:33060.0.0.0:* LISTEN 1690/mysqld
五、安装proftpd-1.3.5rc2
解压proftpd-1.3.5rc2.tar.gz,进入解压出来的源码目录。
(1) 安装前配置
# ./configure \
--prefix=/usr/local/proftpd \
--with-modules=mod_sql:mod_sql_mysql:mod_quotatab:mod_quotatab_sql\
--with-includes=/usr/local/mysql/include/mysql \
--with-libraries=/usr/local/mysql/lib/mysql
特别说明:
--with-includes和--with-libraries后要填上你的系统内MySQL的include和lib路径,请务必保证路径的正确,否则将会出错。
--prefix指定ProFTPd的安装位置。不加此项将会默认安装。
--with-modules允许ProFTP支持MySQL模块,并支持quotatab磁盘限额。一定要加。
(2) 编译安装
# make
# make install
安装完毕之后应该查看下模块信息
# /usr/local/proftpd/sbin/proftpd?l
请务必保证能够查看到:
mod_sql.c , mod_sql_mysql.c, mod_quotatab.c, mod_quotatab_sql.c
(3) 创建FTP系统用户和组(重要)
创建一个FTP用户和组,以后所有的其他FTP用户实际都是通过这个系统用户进行FTP
# groupadd ?g3001 ?r ftpgroup //建立工作组ftpgroup组id是3001
# mkdir/home/FTP //在/home目录下新建一个目录
# useradd ?u3001 ?g 3001 ?d /home/FTP ?r ftpuser
//建立系统用户ftpuser,用户id是3001,属于组id为3001的工作组,用户主目录/home/FTP
修改/home/FTP的属主与访问权限(重要)
# chown ?Rftpuser.ftpgroup /home/FTP
# chmod 755/home/FTP
注意:请牢记这里建立的系统用户名ftpuser和工作组ftpgroup,在之后的配置文件修改中将用到。如果在ProFTPd启动时,没有找到正确的指定用户和组的话,启动一定是失败的。
(4) proftpd.conf配置文件的编写和修改(非常重要,难点)
proftpd.conf配置文件在你proftpd的安装目录下的/etc目录下。本文中将proftpd安装在/usr/local/proftpd中,所以:
# cd /usr/local/proftpd/etc/proftpd.conf
# vim proftpd.conf
这里讲我的配置文件全文贴上:
######################################################
#服务器名称
ServerName "My_Ftp_Server"
#服务类型
ServerType standalone
DeferWelcome off
#防止IE,资源管理器文件乱码
MultilineRFC2228 on
#默认服务状态
DefaultServer on
#限制上传的文件格式
#PathDenyFilter xxx
ShowSymlinks on
TimeoutNoTransfer 600
TimeoutStalled 600
TimeoutIdle 1200
DisplayLogin welcome.msg
DisplayChdir .message true
ListOptions "-l"
DenyFilter \*.*/
# Set off todisable IPv6 support which is annoying on IPv4 only boxes.
UseIPv6 on
# If set on youcan experience a longer connection delay in many cases.
IdentLookups off
######################################################
#Use this to jail all users in their homes
####是否允许用户进入用户的主目录
# DefaultRoot ~
# Users requirea valid shell listed in /etc/shells to login.
# Use thisdirective to release that constrain.
#RequireValidShell off
# Port 21 is thestandard FTP port.
Port 21
# This is usefulfor masquerading address with dynamic IPs:
# refresh anyconfigured MasqueradeAddress directives every 8 hours
# DynMasqRefresh28800
MaxInstances 30
# Set the userand group that the server normally runs at.
####最关键的是权限控制部分,以什么用户和什么组来运行服务
#更改为你现有的组和用户,这里为了管理上的方便和安全性上考虑,建议新建一个ftp
#组和ftp用户
User ftpuser
Group ftpgroup
#设置对全局文件可以进行读写
AllowOverWriteon
# Umask 022 is agood standard umask to prevent new files and dirs
# (second parm)from being group and world writable.
Umask 022
# Normally, wewant files to be overwriteable.
AllowOverwrite on
# Uncomment thisif you are using NIS or LDAP via NSS to retrieve passwords:
#PersistentPasswd off
# This isrequired to use both PAM-based authentication and local passwords
# AuthOrder mod_auth_pam.c*mod_auth_unix.c
# Be warned: useof this directive impacts CPU average load!
# Uncomment thisif you like to see progress and transfer rate with ftpwho
# in downloads.That is not needed for uploads rates.
#
# UseSendFile off
#设置系统运行日志和文件传输日志,注意日志文件的位置,以后查看服务器的记录
TransferLog /var/log/proftpd/xferlog
SystemLog /var/log/proftpd/proftpd.log
# Logging onto/var/log/lastlog is enabled but set to off by default
#UseLastlog on
# In order tokeep log file dates consistent after chroot, use timezone info
# from/etc/localtime. If this is not set, andproftpd is configured to
# chroot (e.g.DefaultRoot or
# savingstimezone regardless of whether DST is in effect.
#SetEnv TZ:/etc/localtime
QuotaEngine on
Ratios off
# Delay enginereduces impact of the so-called Timing Attack described in
#http://www.securityfocus.com/bid/11430/discuss
# It is on bydefault.
DelayEngine on
ControlsEngine off
ControlsMaxClients 2
ControlsLog /var/log/proftpd/controls.log
ControlsInterval 5
ControlsSocket /var/run/proftpd/proftpd.sock
AdminControlsEngineoff
# Alternativeauthentication frameworks
#Include/etc/proftpd/ldap.conf
#Include/etc/proftpd/sql.conf
# This is usedfor FTPS connections
#Include/etc/proftpd/tls.conf
# Useful to keepVirtualHost/VirtualRoot directives separated
#Include/etc/proftpd/virtuals.con
# A basic anonymous configuration, no uploaddirectories.
#匿名登陆部分设置,我这里不允许匿名用户登录,全注释掉了
#
# User ftp
# Group ftp
# # We want clients to be able to login with"anonymous" as well as "ftp"
# UserAlias anonymousftp
# # Cosmetic changes, all files belongs to ftpuser
# DirFakeUser onftp
# DirFakeGroup on ftp
#
# RequireValidShell off
#
# # Limit the maximum number of anonymouslogins
# MaxClients 10
#
# # We want 'welcome.msg' displayed at login, and'.message' displayed
# # in each newly chdired directory.
# DisplayLogin welcome.msg
# DisplayChdir .message
#
# # Limit WRITE everywhere in the anonymouschroot
#
#
# DenyAll
#
#
#
# # Uncomment this if you're brave.
# #
# # #Umask 022 is a good standard umask to prevent new files and dirs
# # #(second parm) from being group and world writable.
# # Umask 022 022
#
#
# # DenyAll
# #
#
#
# # AllowAll
# #
# #
#
#
# Include othercustom configuration files
#Include /etc/proftpd/conf.d/
###########################################################################
#Quota磁盘限额部分设置
###########################################################################
#设置磁盘限额
QuotaDirectoryTally on
#设置测盘容量显示时的单位
QuotaDisplayUnits "Mb"
#打开磁盘限额引擎
QuotaEngine on
#设置磁盘限额日志文件
QuotaLog "usr/local/proftpd/var/quota"
#允许显示磁盘限额信息,ftp登陆后可执行quote site quota命令察看当前磁盘使用情#况
QuotaShowQuotas on
###########################################################################
#Mysql数据库部分设置
###########################################################################
#数据库访问日志文件位置,用于以后查看服务器访问状态
SQLLogFile "/var/log/proftpd/proftpd.sql.log
###########################################################################
#数据库连接
#我这里是要在MySQL中新建一个存放FTP数据认证表的数据库,名字将定为proftpd
#将在该库中建立相关的SQL认证表
#databaseName: proftpd
#hostName: localhost
#MySQl_port: 3306 MySQL的默认服务端口是3306
#SQL userName: ftp 数据库的用户名,将在MySQL中建立
#SQL userPwd: 123 数据库的用户密码
###########################################################################
SQLConnectInfoproftpd@localhost:3306 ftp 123
###########################################################################
#数据库认证方式,很重要,不要写错
# Backend为MySQL数据库认证方式,Plaintext为名文认证方式,前者优先
###########################################################################
SQLAuthTypes Backend Plaintext
###########################################################################
#指定用来做用户认证的表的有关信息
#指定ftp用户数据表的名字和其中的字段名,表名可以自定义,字段名不可动
#表名和字段名都是和接下来mysql中建立的数据表想对应的。
SQLUserInfo ftpuser userid passwduid gid homedir shell
SQLGroupInfo ftpgroup groupname gidmembers
###########################################################################
#指定是否必须为ftp用户指定一个系统shell,off表示不用指定,on反之。为了系统安#全应该指定为off
RequireValidShell off
###########################################################################
#数据库认证,校验数据表
#这个在ProFTPd的官网上有详细的解释,这里简单的说下groupsetfast,后面带有fast
#选项的话,将简化你的在数据库中用户组数据表内的信息。
#例如,使用fast选项之前的数据表,只能这么存
#|--------------------------------------------------|
#| GROUPNAME | GID | MEMBERS |
#|--------------------------------------------------|
#| group1 | 1000 | naomi |
#| group1 | 1000 | priscilla |
#| group1 | 1000 | gertrude |
#|--------------------------------------------------|
#使用fast选项之后的数据表,就可以这么存了:
# |--------------------------------------------------|
# | GROUPNAME | GID | MEMBERS |
#|--------------------------------------------------|
#| group1 | 1000 | naomi, priscilla, gertrude |
#|--------------------------------------------------|
SQLAuthenticate users groupsusersetfast groupsetfast
######################################################
#如果用户主目录不存在,则系统会根据用户在用户鼠标中的homedir字段的值新建一
#个目录,这里注意新版本ProFTPd这里是CreateHome,旧版本是SQLHomedirOnDemand
CreateHome on
###########################################################################
#指定磁盘限额模块使用的数据库信息,大家都是这么写的,我也不知道啥意思,好复
#杂的样子
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 quotalimits \
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 quotatallies \
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}'" quotatallies
SQLNamedQuery insert-quota-tally INSERT"%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTablesql:/get-quota-tally/update-quota-tally/insert-quota-tally
###########################################################################
这样十分重要的proftpd.conf配置文件就算修改完了,如果启动服务之后各种的访问错误的原因,绝大多数是跟这个文件里的配置不正确有关。
(5) 在MySQL数据库管理系统中建立FTP用户认证相关的数据表(非常重要)
登陆MySQL数据库管理系统
# mysql ?u root?p密码
建立FTP的管理数据库,库名为proftpd,这必须要与proftpd.conf中配置的内容一致。
# createdatabase proftpd;
建立一个访问proftpd的数据库用户,名为ftp,密码为123,这必须要与proftpd.conf中配置的内容一致。
# grant allprivileges on proftpd.* to ftp@”localhost” identified by “123”;
使用proftpd库
# use proftpd;
建立组验证表,表名为ftpgroup,这必须要与proftpd.conf中配置的内容一致。
create table ftpgroup (groupname TEXT NOT NULL,gidSMALLINT NOT NULL,members TEXT NOT NULL);
建立用户验证表,表名为ftpuser,这必须要与proftpd.conf中配置的内容一致。
create table ftpuser (userid TEXT NOT NULL,passwd TEXTNOT NULL,uid INT NOT NULL,gid SMALLINT NOT NULL,homedir TEXT,shell TEXT);
建立磁盘限额数据表,你不需要改动它的任何地方。
CREATE TABLE quotalimits (
name VARCHAR(30),
quota_type ENUM("user", "group","class", "all") NOT NULL,
per_session ENUM("false", "true")NOT NULL,
limit_type ENUM("soft", "hard")NOT NULL,
bytes_in_avail FLOAT NOT NULL,
bytes_out_avail FLOAT NOT NULL,
bytes_xfer_avail FLOAT NOT NULL,
files_in_avail INT UNSIGNED NOT NULL,
files_out_avail INT UNSIGNED NOT NULL,
files_xfer_avail INT UNSIGNED NOT NULL
);
quotalimits 表中各字段的含意:
quota_type 磁盘限额的鉴别
bytes_in_avail 上传最大字节数,就是FTP用户空间容量
bytes_out_avail 下载最大字节数
bytes_xfer_avail 总共可传输的文件的最大字节数(上传和下载流量)
files_in_avail 总共能上传文件的数目
files_out_avail 能从服务器上下载文件的总数目
files_xfer_avail 总共可传输文件的数目(上传和下载)
建立用户磁盘限额变动信息表,你不需要改动它的任何地方。
CREATE TABLE quotatallies (
name VARCHAR(30) NOT NULL,
quota_type ENUM("user", "group", "class", "all") NOT NULL,
bytes_in_used FLOAT NOT NULL,
bytes_out_used FLOAT NOT NULL,
bytes_xfer_used FLOAT NOT NULL,
files_in_used INT UNSIGNED NOT NULL,
files_out_used INT UNSIGNED NOT NULL,
files_xfer_used INT UNSIGNED NOT NULL
);
quotatallies表不需要作修改,由程序自动记录
数据表中数据初始化。
我们开始创建Ftp用户
INSERT INTO ftpuser (userid, passwd, uid, gid,homedir, shell) values ('hello', password('12345'), '3001', '3001', '/home/FTP/hello','' );
用户名为hello,密码为12345,做了加密。
/home/FTP/hello是用户主目录,我们已经事先建立好了/home/FTP目录,hello用户将在该用户访问服务器时自动创建。用户shell为空。
加入组验证表
INSERT INTO ftpgroup VALUES ('ftpgroup', 3001, 'ftpuser,hello');
members字段的多个成员要用逗号分隔。
建立初始用户磁盘限额信息,为用户hello,最多可以上传512MB,即分配了512MB的空间。最多可以下载512MB,最多可以上传1000个文件,下载1000个文件,文件的传输流量为5120KB,总共可以传输2000个文件。
INSERT INTO quotalimits (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) VALUES ('shine', 'user', 'true', 'soft', '51200000','51200000','5120000','1000','1000','2000');
(6) 配置ProFTPd的执行脚本
# vim proftpd;
脚本由不知名人写成,大家都直接拿来用了。
#!/bin/bash
FTPD_BIN=/usr/local/proftpd/sbin/proftpd
FTPD_COnF=/usr/local/proftpd/etc/proftpd.conf
PIDFILE=/usr/local/proftpd/var/proftpd.pid
if [ -f $PIDFILE ]; then
pid=`cat $PIDFILE`
fi
if [ ! -x $FTPD_BIN ]; then
echo "$0: $FTPD_BIN: cannotexecute"
exit 1
fi
case $1 in
start)
if [ -n "$pid" ]; then
echo "$0: proftpd [PID $pid] alreadyrunning"
exit
fi
if [ -r $FTPD_CONF ]; then
echo "Starting proftpd..."
$FTPD_BIN -c $FTPD_CONF
else
echo "$0: cannot start proftpd --$FTPD_CONF missing"
fi
;;
stop)
if [ -n "$pid" ]; then
echo "Stopping proftpd..."
kill -TERM $pid
else
echo "$0: proftpd notrunning"
exit 1
fi
;;
restart)
if [ -n "$pid" ]; then
echo "Rehashing proftpdconfiguration"
kill -HUP $pid
else
echo "$0: proftpd notrunning"
exit 1
fi
;;
*)
echo "usage: $0{start|stop|restart}"
exit 1
;;
esac
exit 0
注意脚本开头的三处路径一定要根据自己的proftpd实际安装路径设置。其他的地方不用改动。
# cp proftpd /etc/init.d/
# chmod +x/etc/init.d/proftpd
# chkconfig --addproftpd;
# chkconfig --level2345 proftpd on
以后可以通过
service proftpdstart
service proftpdstop
service proftpdrestart
更方便开始、停止、重启proftpd服务了。
(7) 设置环境变量
# vim/etc/profile
加入 PATH=$PATH:$HOME/bin:/usr/local/proftpd/sbin
重新启动后生效。
(8) 运行ProFTPd服务
设置好环境变量后,手动运行,执行命令
# proftpd
即可启动proftpd服务,会在proftpd.conf中配置的日志路径出生成日志文件。
若你想在控制台实时查看运行情况,则可以在启动时加入这条参数:
# proftpd ?n ?d5
六、验证性测试
在另一个控制台中输入
# ftp 192.168.126.131或者是ftp localhostname
根据提示输入用户名
输入密码
登陆成功后会出现logged in的字样。失败的话会出现相关的信息。
成功登陆的话,可以执行命令:
quote site quota
用来查看该用户的磁盘使用情况。
同样的也可以通过浏览器访问proftpd服务器。