vsftpd(Very Secure FTP Daemon)提供了两种级别的用户访问:匿名访问和用户访问.用户访问可分为本地用户与虚拟用户.
  虚拟用户是将用户名和口令保存在数据库文件或数据库服务器中.这样做可以有效的保护系统帐号的安全.
配置如下:
编辑/etc/vsftpd/vsftp.conf配置文件:
[root@station1 ~]# cat /etc/vsftpd/vsftpd.conf | grep -v ^# | grep -v ^$
anonymous_enable=NO
local_enable=YES
write_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
chroot_local_user=YES
listen=YES
guest_enable=YES
guest_username=virtual
user_config_dir=/etc/vsftpd/vsftpd_config
pam_service_name=vsftpd_virtual
userlist_enable=YES
tcp_wrappers=YES
[root@station1 ~]#
创建用户配置文件:
[root@station1 ~]# cd /etc/vsftpd/
[root@station1 vsftpd]# mkdir vsftpd_config
[root@station1 vsftpd]# cp vsftpd.conf vsftpd_config/test1
[root@station1 vsftpd]# cp vsftpd.conf vsftpd_config/test2
[root@station1 vsftpd]#
虚拟用户test1配置文件:
[root@station1 vsftpd]# cat vsftpd_config/test1 | grep -v ^# | grep -v ^$
local_enable=YES
write_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
chown_uploads=YES
chown_username=root
xferlog_std_format=YES
chroot_local_user=YES
listen=YES
guest_enable=YES
guest_username=virtual
anon_world_readable_only=NO
max_clients=100
max_per_ip=2
pam_service_name=vsftpd_virtual

userlist_enable=YES
tcp_wrappers=YES
[root@station1 vsftpd]#
虚拟用户test2配置文件:
[root@station1 vsftpd]# cat vsftpd_config/test2 | grep -v ^# | grep -v ^$
anonymous_enable=NO
local_enable=YES
write_enable=YES
anon_upload_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
chroot_local_user=YES
listen=YES
guest_enable=YES
guest_username=ftpuser
anon_world_readable_only=NO
anon_other_write_enable=YES
anon_mkdir_write_enable=YES
anon_max_rate=300000
pam_service_name=vsftpd_virtual

userlist_enable=YES
tcp_wrappers=YES
[root@station1 vsftpd]#
创建本地用户用于虚拟用户的映射:
[root@station1 ~]# useradd -d /var/ftp/ftpuser -s /sbin/nologin ftpuser
[root@station1 ~]# useradd -d /var/ftp/virt -s /sbin/nologin virtual
创建虚拟用户与密码数据库文件:
[root@station1 vsftpd]# cat virt_users
test1
admin
test2
admin
[root@station1 vsftpd]# db_load -T -t hash -f virt_users vsftpd_login.db
[root@station1 vsftpd]# chmod 600 vsftpd_login.db
修改用户认证方式:
[root@station1 ~]# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd_virtual
[root@station1 ~]# vim /etc/pam.d/vsftpd_virtual
[root@station1 ~]# cat /etc/pam.d/vsftpd_virtual
#%PAM-1.0
auth       required     /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login
account    required     pam_userdb.so db=/etc/vsftpd/vsftpd_login

[root@station1 ~]# /etc/init.d/vsftpd restart
Shutting down vsftpd:                                      [  OK  ]
Starting vsftpd for vsftpd:                                [  OK  ]
测试虚拟用户:
[root@station1 ~]# lftp localhost -u test1
Password:
lftp test1@localhost:~> ls        
-rw-r--r--    1 0        0               0 Jun 03 09:15 test
drwxr-xr-x    2 0        0            4096 Jun 03 10:16 test1
-rw-------    1 508      509             0 Jun 03 10:03 test2
lftp test1@localhost:/> user test2
Password:
lftp test2@localhost:~> ls
-rw-r--r--    1 0        0               0 Jun 03 10:26 ftpuser
lftp test2@localhost:/> mkdir test
mkdir ok, `test' created
lftp test2@localhost:/> ls
-rw-r--r--    1 0        0               0 Jun 03 10:26 ftpuser
drwx------    2 509      510          4096 Jun 03 10:29 test
lftp test2@localhost:/> cd test/
lftp test2@localhost:/test> put install.log
36847 bytes transferred
lftp test2@localhost:/test> ls
-rw-------    1 509      510         36847 Jun 03 10:43 install.log
lftp test2@localhost:/test>

使用mysql数据库验证方式:
[root@station1 ~]# /usr/local/mysql/bin/mysqld_safe --user=root&
[1] 4500
[root@station1 ~]# Starting mysqld daemon with databases from /usr/local/mysql/var
[root@station1 ~]# /usr/local/mysql/bin/mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.0.56-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database vsftp;
Query OK, 1 row affected (0.00 sec)

mysql> use vsftp
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> create table users(username char(10) NOT NULL UNIQUE,password char(20) NOT NULL);
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
+-----------------+
| Tables_in_vsftp |
+-----------------+
| users           |
+-----------------+
1 row in set (0.00 sec)

mysql> describe users;
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| username | char(10) | NO   | PRI | NULL    |       |
| password | char(20) | NO   |     | NULL    |       |
+----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into users values('ftpuser1',password('admin'));
Query OK, 1 row affected (0.00 sec)

mysql> select * from users;
+----------+------------------+
| username | password         |
+----------+------------------+
| ftpuser1 | 43e9a4ab75570f5b |
+----------+------------------+
1 row in set (0.00 sec)

mysql> grant select,insert on vsftp.users to ftpadmin@localhost identified by 'admin';
Query OK, 0 rows affected (0.00 sec)

mysql> quit

[root@station1 ~]# vim /etc/pam.d/vsftpd_virtual
[root@station1 ~]# cat /etc/pam.d/vsftpd_virtual
#%PAM-1.0
#auth       required    /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login
#account    required    pam_userdb.so db=/etc/vsftpd/vsftpd_login

auth required pam_mysql.so user=ftpadmin passwd=admin host=localhost db=vsftp table=users usercolumn=name passwdcolumn=passwd crypt=2
account required pam_mysql.so user=ftpadmin passwd=admin host=localhost db=vsftp table=users usercolumn=name passwdcolumn=passwd crypt=2
[root@station1 ~]#


附:
crypt():
       0 (or "plain") = No encryption.  Passwords stored in plaintext.
                        HIGHLY DISCOURAGED.

       1 (or "Y")     = Use crypt(3) function.

       2 (or "mysql") = Use MySQL PASSWORD() function. It is possible
                        that the encryption function used by PAM-MySQL
                        is different from that of the MySQL server, as
                        PAM-MySQL uses the function defined in MySQL's
                        C-client API instead of using PASSWORD() SQL function
                        in the query.
                       
       3 (or "md5")   = Use plain hex MD5.

       4 (or "sha1")  = Use plain hex SHA1.