一、需求

1、系统帐号和虚拟帐号

这是一个相当复杂的需求,系统上一些采集系统走的ftp进行采集的。历史积累下来的,最早都是直接在OS上创建系统帐号再ftp登录(shell大部分设置为/bin/false或/sbin/nologin,也部分使用的bash和csh)。后来由于系统安全加固使用了pam_tally2模块,这就导致默认的vsftpd模块会调用系统认证,导致触发pam_tally2策略时会被锁定,影响业务采集使用 。通过测试发现虚拟帐号会解决被锁定的问题—- 这个好理解,虚拟帐户调用不涉及系统模块的调用,所以不会被锁,即使映射的主帐号被锁,也照样可以使用。

2、相对路径和绝对路径

默认使用系统帐号时,ftp登陆时看到的是全路径,如zabbix帐号通过ftp登陆后pwd查看到家目录是/home/zabbix。这就是绝对路径‘;当使用虚拟帐号时,默认指定local_root,比如也是/home/zabbix,虚拟帐号名为ftptest,当使用这个帐号登陆后,pwd查看到为/ (实际是/home/zabbix),这就是相对路径。

3、需求

系统最终想都改造成虚拟帐号,但于涉及的帐号太多,一次性搞定显然不现实,需要一个过渡阶段,过渡过程中,需要满足如下需求:

  • a: 系统帐号和虚拟帐号都可以登陆;
  • b: 系统帐号登陆后,显示的是绝对路径;
  • c: 虚拟帐号登陆后,即有绝对路径的也有相对路径的。

二、系统帐号和业务帐号共存

实现这个功能的关键是vsftpd pam里的配置,直接拿本地原始配置和虚拟用户配置叠加显然不行。这里的关键是control_flag,control_flag可以用required也可以用sufficient,使用required需要所有内容都满足才行,当我们前两条配置虚拟用户登录验证通过后(虚拟配置在上,系统认证在下配置时),继续向下面的配置条目进行验证,验证是否是本地用户,发现不是,结果报错。

使用Sufficient时,如果标记为 sufficient 的模块成功并且先前没有 Required 或 sufficient 模块失败,则忽略堆栈中的所有其余模块并返回成功。实现两者同时登陆的/etc/pam.d/vsftpd文件配置如下:

1auth sufficient /lib64/security/pam_userdb.so db=/etc/vsftpd/ftpuser
2account sufficient /lib64/security/pam_userdb.so db=/etc/vsftpd/ftpuser
3session    optional     pam_keyinit.so    force revoke
4auth       required     pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
5auth       required     pam_shells.so
6auth       include      password-auth
7account    include      password-auth
8session    required     pam_loginuid.so
9session    include      password-auth  

三、相对路径和绝对路径

对于虚拟用户来说,登陆后是否为绝对路径的关系参数是virtual_use_local_privs  ,当设置为YES时,和系统帐号权限一致,登陆后查看到的是类似于/home/用户名 这样的路径(与local_root参数设置的一致),当设置为NO时,看到的/ 相对路径。

两个测试用户的配置示例如下:

 1linux-ou3x:~ # cat /etc/vsftpd/vsftpd_user_conf/test
 2guest_enable=YES
 3local_root=/home/snsserver
 4anon_world_readable_only=NO
 5write_enable=YES
 6anon_upload_enable=YES
 7anon_mkdir_write_enable=YES
 8anon_other_write_enable=YES
 9guest_username=snsserver
10anon_umask=022
11virtual_use_local_privs=YES
12linux-ou3x:~ # cat /etc/vsftpd/vsftpd_user_conf/test2
13guest_enable=YES
14local_root=/home/snsserver2
15anon_world_readable_only=NO
16write_enable=YES
17anon_upload_enable=YES
18anon_mkdir_write_enable=YES
19anon_other_write_enable=YES
20guest_username=snsserver2
21anon_umask=022
22#virtual_use_local_privs=YES

vsftpd.conf的配置如下:

 1linux-ou3x:~ # grep -v '^#' /etc/vsftpd.conf
 2dirmessage_enable=YES
 3ftpd_banner="Authorized users only. All activity may be monitored and reported!"
 4anonymous_enable=NO
 5anon_world_readable_only=YES
 6syslog_enable=YES
 7connect_from_port_20=YES
 8pam_service_name=vsftpd
 9listen=YES
10ssl_enable=NO
11pasv_min_port=30000
12pasv_max_port=30010
13write_enable=YES
14use_localtime=YES
15local_enable=YES
16local_umask=022
17ascii_upload_enable=YES
18ascii_download_enable=YES
19user_config_dir=/etc/vsftpd/vsftpd_user_conf

注:上面的示例还需要注意chroot_local_user参数,当其值为YES时,在rhel7下,普通用户和虚拟帐户登陆到看到的路径都是"/",如果设置为NO后,看到的是实际的路径,如/home/zabbix或/home/zabbix/vuser1

四、实现效果

最终效果如下:

vsftp-complex
vsftp-complex

相对路径看到的URL后面直接是/,绝对路径是路径信息。

五、踩过的坑

1、系统用户登陆后,无法写入自身家目录

这个是由于全局配置中使用guest_enable=YES,如果在全局配置中又指定了guest_username,则此时任一个系统帐号登陆后都使用的是该用户的权限,而且pwd看到的是相对路径。当不指定guest_username时,默认映射的guest_username是ftp用户。所认全局和局部参数一定要做好切分,不然使用系统帐号登陆就没有意义了。

2、虚拟用户映射多个用户

在曾经很长的一段时间,我都认为多个虚拟用户只能映射成一个系统帐号。如,test test2映射成www用户,而不能实现test映射www,test2映射nginx 。显然,这种认为是错误的,同上面一样,之前由于配置的是全局配置,且在局部设置里又未设置这些参数。(如果全局和局部都设置了相同的参数,在适用到局部用户时,局部参数会覆盖全局参数)

PAM模块使用参数IBM论坛相关文档