转自:http://litvip.com/2011/03/08/200

上一篇vsftpd虚拟用户的文章里,我们的虚拟用户信息保存在文件里,如果有大量的ftp用户,显然管理非常不方便,

因此本篇将介绍如何把用户信息保存到mysql里。

第一步,因为同样是基于PAM方式验证用户,所以我们先安装mysql_pam,由于该软件标准的yum源里没有,

需要我们自己下载安装。

1
2
3
4
[root@test src]#wget ftp://ftp.pbone.net/mirror/centos.karan.org/el5/extras/testing/i386/RPMS/pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm
[root@test src]# rpm -ivh pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm
準備中...                ########################################### [100%]
   1:pam_mysql              ########################################### [100%]

第二步,创建vsftpd用的数据库,我们命名为vsftpd,并创建用户信息和日志2个表,分别命名为users,log。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@test ~]# mysql -u admin -p
Enter password:
......
mysql> create database vsftpd;
Query OK, 1 row affected (0.01 sec)
  
mysql> use vsftpd;
Database changed
mysql> create table users (
    -> id INT AUTO_INCREMENT NOT NULL,
    -> username VARCHAR(30) BINARY UNIQUE NOT NULL,
    -> password VARCHAR(128) BINARY NOT NULL,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)
  
mysql> create table log (
    -> message VARCHAR(255),
    -> username VARCHAR(30),
    -> pid int(11),
    -> host VARCHAR(128),
    -> rhost VARCHAR(128),
    -> logtime timestamp
    -> );
Query OK, 0 rows affected (0.01 sec)

注意,密码的位数我设置的128位,你不要设置的太短了,因为加密后的字符串很长,如果太短,有可能导致后面的

部分被截掉(插入的时候会有Data truncated for column这样的警告),登录的时候当然就会提示密码不正确哦!

接下来,我们先插入test001和test002两个测试用户,密码采用MD5加密。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> insert into users(`username`,`password`) values ('test001',md5('test001'));
Query OK, 1 row affected, 1 warning (0.01 sec)
  
mysql> insert into users(`username`,`password`) values ('test002',md5('test002'));
Query OK, 1 row affected, 1 warning (0.01 sec)
  
mysql> select * from users users;
+----+----------+--------------------------------+
| id | username | password                       |
+----+----------+--------------------------------+
|  1 | test001  | fa820cc1ad39a4e99283e9fa555035 |
|  2 | test002  | 351523b8e6eb36ae5115205886f36f |
+----+----------+--------------------------------+
2 rows in set (0.01 sec)

接下来,我们创建一个专门的mysql用户mysqlftp(密码ftp123),用于vsftpd增删改查数据库。

1
2
mysql> GRANT SELECT,UPDATE,INSERT,DELETE ON vsftpd.* TO 'mysqlftp'@'localhost' IDENTIFIED BY 'ftp123';
Query OK, 0 rows affected (0.01 sec)

第三步,该创建pam文件了,默认已经有了/etc/pam.d/vsftpd,

我们创建一个/etc/pam.d/vsftpd.mysql,内容如下(只有2行,但是有点长哦,你不要人为换行哟):

1
2
auth required pam_mysql.so user=mysqlftp passwd=ftp123 host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=3 sqllog=1 logtable=log logmsgcolumn=message logusercolumn=username logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=logtime
account required pam_mysql.so user=mysqlftp passwd=ftp123 host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=3 sqllog=1 logtable=log logmsgcolumn=message logusercolumn=username logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=logtime

有必要对上面的一些参数做下简单的解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
user     登录mysql的用户名(我们追加的专用用户)
passwd   登录mysql的密码
host     MySQL服务器名
db       数据库名
table    表名
usercolumn  用户名字段
passwdcolumn    密码字段
crypt   加密方式
    0:plain,即明文
    1:crypt加密
    2:用MySQL的PASSWD()函数加密
    3:MD5加密(我们用的这个)
    4:SHA1加密
sqllog          是否输出日志,1输出,0不输出
logtable        保存日志的表名
logmsgcolumn    日志主信息(比如AUTHENTICATION SUCCESS,QUERYING SUCCESS这样的)
logusercolumn   用户名字段
logpidcolumn    pid信息(即用户连接ftp后的进程ID)
loghostcolumn   host名信息保存字段(我们的ftp服务器)
logrhostcolumn  远程host名保存字段(请求连接的客户端)
logtimecolumn   登录时间保存字段

创建完了之后,你需要把/etc/vsftpd/vsftpd.conf里的

1
pam_service_name=vsftpd

改成

1
pam_service_name=vsftpd.mysql

第四步,配置vsftpd的主配置文件/etc/vsftpd/vsftpd.conf。我们先进行一下约定:

vsftpd虚拟用户专用主目录:/home/vftp

userx登录后的主目录:/home/vftp/userx

/etc/vsftpd/vsftpd.conf的主要内容和上篇vsftpd本地用户一致,我们将追加如下内容。

1
2
3
4
5
6
virtual_use_local_privs=YES
guest_enable=YES
guest_username=vftp
user_sub_token=$USER
local_root=/home/vftp/$USER
user_config_dir=/etc/vsftpd/virtual_user_conf

      第1行:让虚拟用户和local用户一样(设置了write_enable=YES,虚拟用户就有写权限),默认是和匿名用户一样的。

      第2行:把所有的用户都作为guest处理

      第3行:guest账户名

      第4行:为每一个虚拟用户自动生成一个主目录(基于一个模板),但是要注意,他并不是实际的在系统里创建,而是把chroot路径字串告诉客户端。

      如果没有这句,结合第5句设置,可能会出下面的错误,看到后面那个$USER了吧,这个设置就会让$USER变成对应的用户名。

1
500 OOPS: cannot change directory:/home/vftp/$USER

      第5行:统一虚拟用户的主目录,即登录后的chroot目录。

      第6行:对于每个用户各自的设定,如果你要最不同的用户做不同的限制,那么就你就要去

      这个参数定义的目录下去创建以每个用户名命名的文件,追加你对该用户的设定。

第五步,追加geust账户和虚拟用户的目录。

因为虚拟用户的用户名和秘密被单独保存在mysql数据库里,所以vsftpd需要用一个系统用户的身份来读取数据库来完成验证,

就是我们上面设置中guest_username=vftp定义的。但是为了系统安全,我们用下面的命令创建该用户。

1
2
[root@test ~]# useradd -M -d /home/vftp -c "Ftp Guest" -s /sbin/nologin vftp
[root@test ~]# mkdir /home/vftp && chown vftp:vftp /home/vftp

接下来,创建虚拟用户目录和个别设定目录:

1
2
3
[root@test ~]# mkdir /home/vftp/{test001,test002}
[root@test ~]# chown vftp -R /home/vftp/
[root@test ~]# mkdir /etc/vsftpd/virtual_user_conf

重启vsftpd。

1
[root@test ~]# /etc/init.d/vsftpd restart

现在你可以用测试用户来登录你的ftp服务器了。

注1:如果你不需要保存日志信息,那么日志表log就不要创建了,/etc/pam.d/vsftpd.mysql里

两行里从sqllog=1(包括自己)开始后面的信息都不要。

注2:如果你的ftp服务器还是不好用,要确认/var/log/secure日志和/var/log/vsftpd.log,

根据错误信息来找解决方案。

注3:当然,你会发现现在这样,追加用户和删除用户还是不太方便,需要插入数据,创建用户的主目录,

那么你就可以根据你的需求写个简单的shell或者perl脚本来实现,那就事半功倍了。

附:vsftpd完整配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=NO
ascii_upload_enable=YES
ascii_download_enable=YES
connect_from_port_20=YES
ftpd_banner=Welcome to use my test ftp server.
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
listen=YES
pam_service_name=vsftpd.mysql
userlist_enable=YES
userlist_deny=YES
tcp_wrappers=YES
pasv_enable=YES
pasv_min_port=60000
pasv_max_port=60500
ssl_enable=YES
rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem
force_local_logins_ssl=NO
force_local_data_ssl=NO
virtual_use_local_privs=YES
guest_enable=YES
guest_username=vftp
user_sub_token=$USER
local_root=/home/vftp/$USER
user_config_dir=/etc/vsftpd/virtual_user_conf