VSFTP 在两台主机上虚拟用户的实现

实验环境
    主机1:    172.16.66.82   【VSFTP服务器】
        OS:        CentOS 6.6
        vsftp:        vsftpd-2.2.2-12.el6_5.1.x86_64    
        pam_mysql:    pam_mysql-0.7-0.12.rc1.el6.x86_64
    主机2:    172.16.66.81    【数据库服务器,存储用户账号密码】
        OS:        CentOS 6.6
        DB:        MariaDB-5.5.40

一、vsftp虚拟用户简介:

    虚拟用户的特点是只能访问服务器为其提供的FTP服务,而不能访问系统的其它资源。所以,如果想让用户对FTP服务器站内具有写权限,但又不允许访问系统其它资源,可以使用虚拟用户来提高系统的安全性。
    虚拟用户本身不是系统账号,但所有的虚拟用户会被同意映射为一个指定的系统账号,访问的共享位置即为此系统账号的家目录;

    各虚拟用户可被赋予不同的访问权限;
        通过匿名用户的权限控制参数进行指定
    
    虚拟用户账号的存储方式: (此文件需要被编码成hash模式才能被访问)
        文件存储:编辑文件
        关系型数据库存储:(以后新增用户账号,只需要使用insert 就可以添加)
            即时查询数据库完成用户认证           
                (如果使用mysql数据库,pam要依赖于pam-mysql这个模块)
   
二、Vsftpd服务器端配置

1、安装vsftp、pam_mysql
    [root@1inux yum.repos.d]# yum install vsftp -y

    [root@1inux yum.repos.d]# yum install pam_mysql -y

[root@1inux yum.repos.d]# yum install pam_mysql -y
Loaded plugins: fastestmirror, refresh-packagekit, security
Setting up Install Process
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package pam_mysql.x86_64 1:0.7-0.12.rc1.el6 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=========================================================================================================================================
 Package                         Arch                         Version                                   Repository                  Size
=========================================================================================================================================
Installing:
 pam_mysql                       x86_64                       1:0.7-0.12.rc1.el6                        epel                        38 k
Transaction Summary
=========================================================================================================================================
Install       1 Package(s)
Total download size: 38 k
Installed size: 88 k
Downloading Packages:
pam_mysql-0.7-0.12.rc1.el6.x86_64.rpm                                                                             |  38 kB     00:00     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : 1:pam_mysql-0.7-0.12.rc1.el6.x86_64                                                                                   1/1 
  Verifying  : 1:pam_mysql-0.7-0.12.rc1.el6.x86_64                                                                                   1/1 
Installed:
  pam_mysql.x86_64 1:0.7-0.12.rc1.el6                                                                                                    
Complete!


2、查看生成的文件

[root@1inux yum.repos.d]# rpm -ql pam_mysql
/lib64/security/pam_mysql.so
/usr/share/doc/pam_mysql-0.7
/usr/share/doc/pam_mysql-0.7/COPYING
/usr/share/doc/pam_mysql-0.7/CREDITS
/usr/share/doc/pam_mysql-0.7/ChangeLog
/usr/share/doc/pam_mysql-0.7/NEWS
/usr/share/doc/pam_mysql-0.7/README


-------------------------------------------------
三、数据库端配置

1、配置数据库: 

[root@1inux ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.40-MariaDB-log MariaDB Server
Copyright (c) 2000, 2014, Oracle, Monty Program Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE vsftpd;    //创建数据库
Query OK, 1 row affected (0.03 sec)
MariaDB [(none)]> use vsftpd;        //使用vsftpd数据库
Database changed
MariaDB [vsftpd]> GRANT SELECT ON vsftpd.* TO vsftp@'172.16.%.%' IDENTIFIED BY '1inux';    //创建用户并授权
Query OK, 0 rows affected (0.08 sec)
MariaDB [vsftpd]> FLUSH PRIVILEGES;        //刷新授权表
Query OK, 0 rows affected (0.04 sec)
MariaDB [vsftpd]> 
MariaDB [vsftpd]> use vsftpd;
Database changed
MariaDB [vsftpd]> CREATE TABLE users (
    -> id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(50) BINARY NOT NULL,
    -> password CHAR(48) BINARY NOT NULL);
Query OK, 0 rows affected (0.13 sec)
MariaDB [vsftpd]> 
MariaDB [vsftpd]> DESC users;            //查看表结构
+----------+------------------+------+-----+---------+----------------+
| Field    | Type             | Null | Key | Default | Extra          |
+----------+------------------+------+-----+---------+----------------+
| id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name     | varchar(50)      | NO   |     | NULL    |                |
| password | char(48)         | NO   |     | NULL    |                |
+----------+------------------+------+-----+---------+----------------+
3 rows in set (0.03 sec)
MariaDB [vsftpd]> 
MariaDB [vsftpd]> INSERT INTO users (name,password) VALUES ('ifeng',password('1inux')),('sina',password('1inux'));    //插入数据
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0
MariaDB [vsftpd]> select * from users;        //查询
+----+-------+-------------------------------------------+
| id | name  | password                                  |
+----+-------+-------------------------------------------+
|  1 | ifeng | *169BFAD5D66C67244E29295DA36B9B1C89731999 |
|  2 | sina  | *169BFAD5D66C67244E29295DA36B9B1C89731999 |
+----+-------+-------------------------------------------+
2 rows in set (0.00 sec)
MariaDB [vsftpd]>


四、在vsftp服务器上配置pam_mysql


1、建立pam认证所需文件
    # vim /etc/pam.d/vsftpd.mysql
    添加如下两行:

auth required pam_mysql.so user=vsftp passwd=1inux host=172.16.66.81 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftp passwd=1inux host=172.16.66.81 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
[root@1inux vsftpd]# cat /etc/pam.d/vsftpd.mysql 
auth required pam_mysql.so user=vsftp passwd=1inux host=172.16.66.81 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftp passwd=1inux host=172.16.66.81 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
[root@1inux vsftpd]#

更多详情:参考 /usr/share/doc/pam_mysql-0.7/README

2、修改vsftpd的配置文件,使其适应mysql认证

建立虚拟用户映射的系统用户及对应的目录

[root@1inux vsftpd]# useradd -s /sbin/nologin -d /var/ftproot vuser
[root@1inux vsftpd]# chmod go+rx /var/ftproot
[root@1inux vsftpd]#

3、请确保/etc/vsftpd.conf中已经启用了以下选项

anonymous_enable=YES        //这一项必须有
local_enable=YES
write_enable=YES
anon_upload_enable=NO
anon_mkdir_write_enable=NO
chroot_local_user=YES

而后添加以下选项

guest_enable=YES
guest_username=vuser

并确保pam_service_name选项的值如下所示

pam_service_name=vsftpd.mysql

4、重启vsftpd服务

[root@1inux vsftpd]# service vsftpd restart
Shutting down vsftpd:                                      [  OK  ]
Starting vsftpd for vsftpd:                                [  OK  ]
[root@1inux vsftpd]# netstat -tnlp | grep :21
tcp        0      0 0.0.0.0:21                  0.0.0.0:*                   LISTEN      107395/vsftpd       
[root@1inux vsftpd]#

5、设置开机启动vsftp

[root@1inux vsftpd]#  chkconfig vsftpd on
[root@1inux vsftpd]#  chkconfig --list vsftpd
vsftpd             0:off    1:off    2:on    3:on    4:on    5:on    6:off
[root@1inux vsftpd]#


至此,基于虚拟用户的vsftp已经搭建完成,可以使用客户端进行测试

[root@1inux ~]# ftp 172.16.66.82
Connected to 172.16.66.82 (172.16.66.82).
220 (vsFTPd 2.2.2)
Name (172.16.66.82:root): ifeng        //虚拟账号
331 Please specify the password.
Password:
230 Login successful.            //成功登陆
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

此时虽然基于虚拟用户的服务器已经搭建完成,但此时所有用户都具有相同的权限,并且,此时的虚拟用户权限很小

五、配置虚拟用户具有不同的访问权限

    vsftpd可以在配置文件目录中为每个用户提供单独的配置文件以定义其ftp服务访问权限,每个虚拟用户的配置文件名同虚拟用户的用户名。配置文件目录可以是任意未使用目录,只需要在vsftpd.conf指定其路径及名称即可。

1、配置vsftpd所有虚拟用户的配置文件目录

[root@1inux vsftpd]# vim vsftpd.conf
添加如下选项

user_config_dir=/etc/vsftpd/vusers_config

2、创建所需要目录,并为虚拟用户提供配置文件

[root@1inux vsftpd]# mkdir /etc/vsftpd/vusers_config
[root@1inux vsftpd]# cd /etc/vsftpd/vusers_config
[root@1inux vusers_config]# touch ifeng sina

3、若让每个虚拟用户具有不同的权限,可以修改虚拟用户配置文件目录下对应的以用户名定义的文件,

    虚拟用户对vsftpd服务的访问权限是通过匿名用户的相关指令进行的。比如,如果需要让ifeng用户具有上传文件、创建删除目录及文件的权限,可以修改/etc/vsftpd/vusers_config/ifeng文件,在里面添加如下选项即可。

anon_upload_enable={YES|NO}
anon_mkdir_write_enable={YES|NO}
anon_other_write_enable={YES|NO}
eg:
[root@1inux vusers_config]# vim /etc/vsftpd/vusers_config/ifeng
[root@1inux vusers_config]# cat !$
cat /etc/vsftpd/vusers_config/ifeng
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
-----------------------------------------------------
验证:
[root@1inux ~]# ftp 172.16.66.82
Connected to 172.16.66.82 (172.16.66.82).
220 (vsFTPd 2.2.2)
Name (172.16.66.82:root): ifeng
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (172,16,66,82,86,176).
150 Here comes the directory listing.
226 Directory send OK.
ftp> mkdir ifengdir        //创建目录
257 "/ifengdir" created        //显示创建目录成功
ftp> lcd /etc
Local directory now /etc
ftp> put fstab
local: fstab remote: fstab    //上传fstab文件
227 Entering Passive Mode (172,16,66,82,72,107).
150 Ok to send data.
226 Transfer complete.
1127 bytes sent in 9.4e-05 secs (11989.36 Kbytes/sec)
ftp> ls                    //通过ls已经可以看到刚才我们创建的目录及上传的文件都已经存在
227 Entering Passive Mode (172,16,66,82,34,156).
150 Here comes the directory listing.
-rw-------    1 504      504          1127 May 02 02:32 fstab
drwx------    2 504      504          4096 May 02 02:31 ifengdir
226 Directory send OK.
ftp> delete fstab        //删除文件
250 Delete operation successful.
ftp> rmdir ifengdir        //删除目录
250 Remove directory operation successful.
ftp> ls                //OK, 文件及目录已经成功删除
227 Entering Passive Mode (172,16,66,82,116,128).
150 Here comes the directory listing.
226 Directory send OK.
ftp>


注:如在配置过程种出现错误,应多参考日志文件:
[root@1inux vsftpd]# tail /var/log/secure
[root@1inux vsftpd]# tail /var/log/message


不同虚拟用户,拥有自己独立的虚拟目录 

若要不同用户拥有自己的独立ftp目录可以在其用户配置文件中添加如下:

local_root=/ftp/userdir          //但虚拟用户对此目录应该拥有读写权限


若要某虚拟用户只有下载权限可以在其用户配置文件中添加如下内容:

anon_world_readable_only=NO (使download用户的能下载,也只能下载;写成YES,将不能列出文件和目录)



补充:
*********************************************************
注:在搭建好数据库后应先在另一台主机上尝试是否能连接成功,以便更快速的搭建
[root@1inux ~]# mysql -uvsftp -h172.16.66.81 -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 5.5.40-MariaDB-log MariaDB Server
Copyright (c) 2000, 2014, Oracle, Monty Program Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
| vsftpd             |
+--------------------+
3 rows in set (0.01 sec)
MariaDB [vsftpd]> select ('abc');
+-----+
| abc |
+-----+
| abc |
+-----+
1 row in set (0.00 sec)
MariaDB [vsftpd]> select password('abc');        //password  加密
+-------------------------------------------+
| password('abc')                           |
+-------------------------------------------+
| *0D3CED9BEC10A777AEC23CCC353A8C08A633045E |
+-------------------------------------------+
1 row in set (0.00 sec)
MariaDB [vsftpd]> 
*********************************************************