[FrontPage] [TitleIndex] [WordIndex

This is a read-only archived version of wiki.centos.org

在 CentOS 5 上通过 VSFTPD 及 MySQL 应用虚拟户口

0.0.1. 采用虚拟用户对比本地用户的好处

  1. 在数据库内存储用户名称及口令,就算对 Unix 的安全性模式不熟识的管理员亦能作出管理。
  2. 除了为新用户初次创建子目录,你无须分享系统的 root 权限。通过 sudo 及一些脚本,你可以避免无限地将系统的 root 权限赋予那些看管系统的非管理级用户。没错,你甚至可以单单授权给 MySQL 外的 root 用户权限去修改 vsftpd 的 ACL 数据库,藉此提高安全性,纵使这种做法已经超越了本文章的范围。

  3. 你无须将拥有指令壳的本地户口给那些只需访问 FTP 的用户。正因如此,你减低了暴露於骇客前的机会,从而降低被入侵的风险。对於那些像 ftp 以纯文本作登录凭证的协议来说,这点尤其重要。

  4. 所有用户的数据都存储在同一目录树内,按需要选择性地采用个别用户的 ACL 设置。备份及恢复的目标便简化为目录树内的子集,而不像缺省的模式般把本地 FTP 户口及指令壳户口夹杂在 /home/ 目录下。

MySQL 的安全性模式可以通过用户级的 ACL 权限保护它的数据库;根据惯例,MySQL 内的 root 用户是 ACL 数据库的超级用户,他被赋予权限读出、写入、及修改该数据库。我们亦会跟随这个惯例,在这个样例中采用 MySQL 的 root 用户。这个户口将会拥有自己的口令(有别於系统的 root 户口)。

这样做能防止 mysql 被入侵后,泄漏可用来入侵系统 root 户口的凭证,进而操控服务器。此外,这亦能防范口令从 MySQL 数据库备份中被解读出来,或者管理员错误地使用纯文本作为数据库的口令。一条简单的原则是:切勿在拥有特殊权限的户口「重用」口令。

1. 先决条件 -> 函式库:pam_mysql.so

你会须要 VSFTPD 及 MySQL(假如它们仍未被安装)。以系统的 root 身份,执行以行指令来安装标准 CentOS 软件库内的组件:

# yum install vsftpd mysql-server 

接著,引导仍未被执行的 mysqld:

# /sbin/service mysqld restart 

请为 MySQL 数据库的 root 用户设置一个口令(假若你仍未如此做):

# mysqladmin -u root password 'yourrootsqlpassword' 

请把你为 MySQL 的 root 用户所设的口令替换 'yourrootsqlpassword'(不需括号)。

1.1. 为 vsftpd 创建 MySQL 数据库

从此起你已不再需要系统的 root 权限。请进入 MySQL 的指令壳:

$ mysql -u root -p 

请输入 yourrootsqlpassword —— 请注意:你在 MySQL 中的 root 用户口令应该是别的,而不应该是 yourrootsqlpassword 。

现在於 MySQL 的指令壳内为虚拟的 vsftpd 用户创建一个数据库:

mysql> CREATE DATABASE vsftpd;
mysql> GRANT SELECT ON vsftpd.* TO 'vsftpd'@'localhost' IDENTIFIED BY  'vsftpdpassword';
mysql> FLUSH PRIVILEGES; 

继续在 MySQL 的指令壳内,改用刚创建的数据库,然后创建所需的列表(当中只有一个列表,包含著用户名称及 MD5 加密的口令)。

mysql> USE vsftpd;
mysql> CREATE TABLE `accounts` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `username` VARCHAR( 30 ) NOT NULL ,
 `pass` VARCHAR( 50 ) NOT NULL ,
 UNIQUE (`username`)
 ) ENGINE = MYISAM ; 

现在你可以离开 MySQL 的指令壳:

mysql> exit; 

1.2. 设置 VSFTPD

创建一位名叫 vsftpd、隶属於 users 群组的非特殊用户(主目录位於 /home/vsftpd)。vsftpd 可以采用这位用户的身份来执行,进一步减低系统的风险。我们的虚拟用户的 FTP 目录将会在 /home/vsftp 目录之内(例如:/home/vsftpd/user1、/home/vsftpd/user2、等)或根据 VSFTPD个别用户配置文件 而定。

# useradd -G users -s /bin/false -d /home/vsftpd  vsftpd 

接著修改 VSFTP 的设置。首先,将原先的 /etc/vsftpd.conf 文件备份:

# cp -v /etc/vsftpd/vsftpd.conf   /etc/vsftpd/vsftpd.conf-orig 

然后作出修改:我们会先倒空现有的文件,然后打开它来编辑

# > /etc/vsftpd/vsftpd.conf
# vi /etc/vsftpd/vsftpd.conf 

vsftpd.conf 内的设置(将它们抄进文件内):

# 拒绝 ANONYMOUS 用户
anonymous_enable=NO
# 允许拥有写入权限(0755)的本地用户
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
# 如果你想记录 vsftpd 的动静,请除去 log_ftp_protocol 的注释
# log_ftp_protocol=YES
connect_from_port_20=YES
# 如果你没有采用以上的 log_ftp_protocol 行,请除去 xferlog_file 及
# xferlog_std_format 的注释 —— 它们是互相排除的
# 当 xferlog_enable=YES 及 xferlog_std_format=YES 时所采用的文件名称
# 警告 —— 更改这个文件名影响 /etc/logrotate.d/vsftpd.log
#xferlog_file=/var/log/xferlog
#
# xferlog_std_format 切换记录是放进 vsftpd_log_file 还是 xferlog_file 文件内。
# NO 写入 vsftpd_log_file,YES 写入 xferlog_file
# xferlog_std_format=YES
#
# 你可以更改工作阶段闲置时限的缺省值(以秒计算)。
#idle_session_timeout=600
#
# 你可以更改连接时限的缺省值(以秒计算)。
#data_connection_timeout=120
#
# 请为指定一个在系统上是完全被隔离、没有特权、及可供 ftp 服务器使用的用户。
nopriv_user=vsftpd
chroot_local_user=YES
listen=YES
# 在这里我们采用 vsftpd 的凭证模块来检查用户名称及口令
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
# 在这里 vsftpd 会允许 vsftpd 这个用户登录 /home/vsftpd/$USER 这个目录
guest_enable=YES
guest_username=vsftpd
local_root=/home/vsftpd/$USER
user_sub_token=$USER
virtual_use_local_privs=YES
user_config_dir=/etc/vsftpd/vsftpd_user_conf 

借着 user_config_dir 这个选项,你可以为个别用户配置文件指定一个目录,用来交换区某些总体设置。这纯属选择性,你可决定是否应用该功能。

# mkdir /etc/vsftpd/vsftpd_user_conf 

举个例说:你想 user1 的主目录位於 /home/vsftpd/user1 以外的地方,请创建 vsftpd 的个别用户配置文件

# vi /etc/vsftpd/vsftpd_user_conf/user1 

并将设置放在其中:

dirlist_enable=YES
download_enable=YES
# user1 可访问的完整目录路径,请按你所需作出修改
local_root=/home/users/user1
write_enable=YES 

要让这位用户登录,你必须创建 user1 这个目录!

# mkdir /home/users/user1 

还有就是将读、写的权限赋予 user1:

# chmod 700 /home/users/user1
# chown vsftpd.users /home/users/user1 

於是 user1 的主目录便在 /home/users/users1 而不是 /home/vsftpd/user1,你更可以按需要在个别用户配置文件内作出修改。

现在你必须设置 PAM,使它利用 MySQL 数据库来验证你的虚拟 FTP 用户,而不是采用缺省的 /etc/password/etc/shadow

# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd-orig
# cat /dev/null > /etc/pam.d/vsftpd
# vi /etc/pam.d/vsftpd 

<!> 问题:为何在这里用 cat?之前便用了一个更简单的方法来倒空文件。是否有 SELinux、或权限方面的理由而不能以 mvtouch 取代?若假如此,为何不说清楚并描述所需的值?

/etc/pam.d/vsftpd 的内容(:当你复制它时应该只有 3 行):

#%PAM-1.0
 session       optional        pam_keyinit.so       force revoke
 auth required pam_mysql.so user=vsftpd passwd=vsftpdpassword  host=localhost db=vsftpd table=accounts usercolumn=username   passwdcolumn=pass crypt=3
 account required pam_mysql.so user=vsftpd passwd=vsftpdpassword  host=localhost db=vsftpd table=accounts usercolumn=username  passwdcolumn=pass crypt=3

请确定你已经将 MySQL 的 vsftpdpassword 口令改为你在「为 vsftpd 创建 MySQL 数据库」内所设置的那一个

现在是要令这一切在 CentOS 下运作的最微妙部份!

<!> 问题:这段编辑备注应该在这里出现吗?

你需要 pam_mysql.so 这个函式库,但它并不包含在 CentOS 的安装或 YUM 内,因此你需要用 RPM 安装它(或 EPEL 软件库 …… 或任何你喜欢的方法)。

rpm -Uvh pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm

它安装时应该不会导致警告或错误 …… 否则 …… 我推荐你利用 google 寻找器来找个方法安装它!

<!> 问题:这段编辑备注应该在这里出现吗?

安装完成后,你应该可以找到:

# ls -al /lib/security/pam_m*
-rwxr-xr-x 1 root root  8024 Sep  4 00:51 /lib/security/pam_mail.so
-rwxr-xr-x 1 root root 15848 Sep  4 00:51 /lib/security/pam_mkhomedir.so
-rwxr-xr-x 1 root root  3892 Sep  4 00:51 /lib/security/pam_motd.so
-rwxr-xr-x 1 root root 36920 Feb 28  2008 /lib/security/pam_mysql.so 

它就在这个样例的最后一行!(可能会有更多文件,但上面的清单应该都存在)

以下步骤对於以 MySQL 数据库来验证虚拟用户是非常重要的

现在我们要创建首位虚拟用户

你可以用 MySQL 指令壳将用户加进数据库内:

$ mysql -u root -p 

这输入口令 …… 然后在 SQL 指令壳内:

mysql> USE vsftpd; 

采用 vsftpd 这个数据库

mysql> INSERT INTO accounts (username, pass) VALUES('user1', md5('secret')); 

现在你应该有一位用户在数据库内:

mysql> select * from accounts;
 +----+-----------+----------------------------------+
 | id | username  | pass                             |
 +----+-----------+----------------------------------+
 |  1 | user1     | 5ebe2294ecd0e0f08eab7690d2a6ee69 |
 +----+-----------+----------------------------------+
 1 rows in set (0.00 sec)
mysql> exit; 

<!> 注:口令的散值只作说明之用,实际数值可能会有差别

现时 user1 的主目录位於 /home/vsftpd/user1。可惜 vsftpd 不会自动创建未存在的目录。因此现在你要以 root 身份创建它,并设置 vsftpd 及 users 这个群组为它的拥有人

# mkdir /home/vsftpd/user1
# chown vsftpd:users /home/vsftpd/user1 

现在重新引导 VSFTPD

# /sbin/service vsftpd restart 

你应该可以通过任何乎合 RFC 规范的 FTP 客户端登录这个 FTP 服务器。

<!> 注:上面引述的配置文件同时用 21 及 20 号 FTP 端口(作操控及数据连接);有些网络设置(早期 Windows 有关静态 FTP 的 互联网选项;某些 NAT 的设计;某些代理服务器)不能通过第二个端口。若是如此,配置文件便须要有以下修订,而 FTP 服务器须要重新引导:

# connect_from_port_20=YES
connect_from_port_20=NO 

2. 如何在将来有需要时加入更多用户……只须简单的 2 步:

  1. 将新用户加进数据库:譬如 user12 与 secret12 这个口令(你亦可以创建电邮地址般的户口作登录之用,例如: user12@example.com ):

    进入数据库的指令壳;

    $ mysql -u root -p 

    然后在 SQL 指令壳执行:

    mysql> USE vsftpd;
    mysql>INSERT INTO accounts (username, pass) VALUES('user12', md5('secret12'));
    mysql> exit; 
  2. 新增 user12 的主目录,这个步骤需要系统的 root 权限:

    # mkdir /home/vsftpd/user12
    # chown vsftpd:users /home/vsftpd/user12 

Translation of revision 11


2023-09-11 07:23