在 CentOS 5 上通过 VSFTPD 及 MySQL 应用虚拟户口
0.0.1. 采用虚拟用户对比本地用户的好处
- 在数据库内存储用户名称及口令,就算对 Unix 的安全性模式不熟识的管理员亦能作出管理。
除了为新用户初次创建子目录,你无须分享系统的 root 权限。通过 sudo 及一些脚本,你可以避免无限地将系统的 root 权限赋予那些看管系统的非管理级用户。没错,你甚至可以单单授权给 MySQL 外的 root 用户权限去修改 vsftpd 的 ACL 数据库,藉此提高安全性,纵使这种做法已经超越了本文章的范围。
你无须将拥有指令壳的本地户口给那些只需访问 FTP 的用户。正因如此,你减低了暴露於骇客前的机会,从而降低被入侵的风险。对於那些像 ftp 以纯文本作登录凭证的协议来说,这点尤其重要。
所有用户的数据都存储在同一目录树内,按需要选择性地采用个别用户的 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。
vsftpd 的 PAM 设置放置在 /etc/pam.d/vsftpd。请照以下方法将它备份并如下创建一个新文件:
# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd-orig # cat /dev/null > /etc/pam.d/vsftpd # vi /etc/pam.d/vsftpd
问题:为何在这里用 cat?之前便用了一个更简单的方法来倒空文件。是否有 SELinux、或权限方面的理由而不能以 mv 及 touch 取代?若假如此,为何不说清楚并描述所需的值?
/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 软件库 …… 或任何你喜欢的方法)。
请找寻 pam_mysql 这个 RPM 组件并下载它(你可以简单地用 wget),截至本文,它被收录在 pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm
然后安装它:
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 这个数据库
现在创建 user1 这个虚拟用户,并设置 secret 这个口令(它会被 MySQL 的 MD5 函式来加密然后存储):
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 步:
将新用户加进数据库:譬如 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;
新增 user12 的主目录,这个步骤需要系统的 root 权限:
# mkdir /home/vsftpd/user12 # chown vsftpd:users /home/vsftpd/user12
Translation of revision 11