我使用 Apache + SUexec 运行 Linux 服务器,其中所有虚拟主机 htdocs 文件夹均由特定用户拥有:
# ls /www/sites
drwxr-xr-x 4 vhost-sitea.com vhost-sitea.com 4096 Oct 13 16:45 www.sitea.com/
drwxr-xr-x 3 vhost-siteb.com vhost-siteb.com 4096 May 14 20:09 www.siteb.com/
drwxr-xr-x 5 vhost-sitec.com vhost-citec.com 4096 Nov 22 2013 www.sitec.com
drwxr-xr-x 3 vhost-sited.com vhost-sited.com 4096 Oct 25 2014 www.sited.com/
我希望这些网站的所有者能够通过 VSFTPD 连接并管理自己的文件夹。为此,每个虚拟用户都根据其网站命名为“user_a”、“user_b”(...)。
我的基于 Chroot 和虚拟用户的 VSFTPD 配置如下:
# cat /etc/vsftpd.conf
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
nopriv_user=vsftpd
virtual_use_local_privs=YES
guest_enable=YES
user_sub_token=$USER
local_root=/home/vsftpd/users/$USER # Overridden by user_config_dir below
chroot_local_user=YES
guest_username=vsftpd
user_config_dir=/etc/vsftpd/vsftpd_user_conf
用户配置文件为(例如,网站“www.sitea.com”的“user_a”):
# cat /etc/vsftpd/vsftpd_user_conf/user_a
local_root=/www/sites/www.sitea.com
write_enable=YES
现在我的问题是,当该用户尝试上传文件时,VSFTPD 使用“vsftpd”unix 用户,但上传失败,因为 www.sitea.com 文件夹和子文件夹归特定“vhost-sitea.com”用户所有(根据 SUexec 配置)。
您必须了解,在 SUexec 下,Apache“www-data”用户根本没有使用 www 虚拟文件夹权限,所以我不能简单地在“guest_username”指令中使用它。
有没有办法为每个登录的虚拟用户指定一个 VSFTP 守护进程用户,以便当虚拟“user_a”用户与 VSftp 连接时,VSFTPd 守护进程将在“vhost-sitea.com”用户下写入文件?
谢谢你的帮助,肯。
答案1
为了记录,我回答我自己:使用 bindfs 和强制文件所有者似乎是一个有趣的解决方法,因为我得到了以下结果:
# bindfs -u vsftpd /www/sites/www.sitea.com/ /home/vsftpd/users/user_a/mnt-www.sitea.com/
以下是要挂载的目录的权限:
# ll /www/sites/www.sitea.com/
total 20
drwxr-xr-x 5 vhost-sitea.com vhost-sitea.com 4096 Nov 10 20:42 ./
drwxr-xr-x 23 root root 4096 Nov 8 20:37 ../
drwx------ 2 vhost-sitea.com vhost-sitea.com 4096 Nov 8 20:43 .cache/
drwxr-xr-x 5 vhost-sitea.com vhost-sitea.com 4096 Nov 10 20:52 html/
drwxr-xr-x 2 vhost-sitea.com vhost-sitea.com 4096 Nov 10 20:42 packages/
现在让我们看看挂载点的权限:
# ll /home/vsftpd/users/user_a/mnt-www.sitea.com/
total 20
drwxr-xr-x 5 vsftpd vhost-sitea.com 4096 Nov 10 20:42 ./
dr-xr-xr-x 3 root root 4096 Nov 10 22:12 ../
drwx------ 2 vsftpd vhost-sitea.com 4096 Nov 8 20:43 .cache/
drwxr-xr-x 5 vsftpd vhost-sitea.com 4096 Nov 10 20:52 html/
drwxr-xr-x 2 vsftpd vhost-sitea.com 4096 Nov 10 20:42 packages/
然而,如果你们中的任何一个人有更好的解决方案,那可能会很有趣 - 比如说一个不那么“快速和肮脏”的解决方案:)
++
答案2
您必须设置 vsftpd 虚拟用户系统,将每个虚拟用户连接到不同的系统用户,因此guest_username
对于每个虚拟用户来说都必须不同,而不是唯一的。
你必须guest_username
在每个虚拟用户的配置文件中定义,不在主配置文件中。此外它的值必须是您在 suEXEC 配置中使用的系统用户,针对该特定虚拟主机。
例如,对于与系统用户 local_user 连接的虚拟用户 virtual_user ,在 /www/sites/local_user 中有一个 Apache 虚拟主机,/etc/vsftpd.conf
将是:
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
nopriv_user=vsftpd
virtual_use_local_privs=YES
guest_enable=YES
user_sub_token=$USER
local_root=/www/sites/$USER
chroot_local_user=YES
user_config_dir=/etc/vsftpd/vsftpd_user_conf
/etc/vsftpd/vsftpd_user_conf/virtual_user
仅包含一行:
guest_username=local_user
为了简化配置,我将包含 Apache 虚拟主机的文件夹命名为 local_user。这样,您只需在 /etc/vsftpd.conf 中设置一次 local_root,然后将其从每个虚拟用户配置文件中删除即可。