我们运行Web服务器,我们有以下情况:
所有用户必须具有对/ var / www / mysite的读写权限。 我们目前通过拥有/ var / www / site到www-data这个组来完成这个任务。 然后我们在组上设置write + setgid位,以确保所有子目录具有相同的权限。
现在,这一切都运行良好一段时间,但我们有以下scheme的问题:
bower install
包。 运行bower install
的用户第一次bower install
了public/bower_components
目录,并且没有设置setgid位 public/scripts/src
javascript缩小为public/scripts/dist
并且第一个运行gulp build
用户拥有这些文件 在这两种情况下, find path/to/dir -type d -exec chmod g+ws {} \;
是否缓解了这个问题,但是有可能首先解决这个问题吗? 我们已经在/var/www/mysite
目录中设置了setgid位,那么为什么bower install
不能遵循这个权限设置?
如果没有,是否有更好的方法来解决这个问题? 我们曾想过在部署自动化过程中设置一些位,但是如果用户忘记了setgid位,我们认为自动化部署也可能会陷入困境。
Posix ACL是唯一明确的优雅方式,这是我处理共享读/写资源冲突的方式,尤其是在基于Web的系统上。 这是一个运行的例子。
在我的例子中,我有一个名为/var/www/html/share
。 另外我有用户alice
, bob
, deploy
和bower
首先,我创build了一个名为html
的组,然后将用户添加到该组中。
groupadd html for i in alice bob deploy bower; do usermod -a -G html $user; done
现在,我已经添加了一个文件ACL对这个html
组到该文件夹。
setfacl -mg:html:rwx /var/www/html/share setfacl -d -mg:html:rwx /var/www/html/share
第二个命令很重要,它会导致inheritance的发生。
现在,我们可以testing这个的行为。
# for user in alice bob bower deploy; do \ sudo -u $user touch "/var/www/html/share/file_${user}" \ done [root@localhost html]# ls -l /var/www/html/share/ total 0 -rw-rw-r--+ 1 alice alice 0 May 13 23:08 file_alice -rw-rw-r--+ 1 bob bob 0 May 13 23:08 file_bob -rw-rw-r--+ 1 bower bower 0 May 13 23:08 file_bower -rw-rw-r--+ 1 deploy deploy 0 May 13 23:08 file_deploy [root@localhost html]#
乍看起来,文件的所有权似乎都很简单,并且不允许一个用户与另一个用户进行交互。 但是,我们可以使用getfacl
来查看ACL,其中显示了更多信息。
# getfacl file_Al getfacl: file_Al: No such file or directory [root@localhost share]# getfacl file_alice # file: file_alice # owner: alice # group: alice user::rw- group::rx #effective:r-- group:html:rwx #effective:rw- mask::rw- other::r--
你可以看到, html
组有控制这些文件。
注意:标准的unix GROUP权限表示针对权限的掩码。 由于它是rw
文件,对于ACL也是有效的,尽piperwx
授予了实际的权限。
让其他用户可以修改/删除这些文件。
# sudo -u alice /bin/bash [alice@localhost share]$ pwd /var/www/html/share [alice@localhost share]$ echo "hello world" >>file_alice [alice@localhost share]$ echo "hello world" >>file_bob [alice@localhost share]$ echo "hello world" >>file_deploy [alice@localhost share]$ echo "hello world" >>file_bower [alice@localhost share]$ ll total 16 -rw-rw-r--+ 1 alice alice 12 May 13 23:15 file_alice -rw-rw-r--+ 1 bob bob 12 May 13 23:15 file_bob -rw-rw-r--+ 1 bower bower 12 May 13 23:15 file_bower -rw-rw-r--+ 1 deploy deploy 12 May 13 23:15 file_deploy [alice@localhost share]$ rm file_deploy
最后,棘手的一点。 当爱丽丝做一个目录时会发生什么?
[alice@localhost share]$ mkdir dir_alice; [alice@localhost share]$ ls -l total 12 drwxrwxr-x+ 1 alice alice 0 May 13 23:16 dir_alice -rw-rw-r--+ 1 alice alice 12 May 13 23:15 file_alice -rw-rw-r--+ 1 bob bob 12 May 13 23:15 file_bob -rw-rw-r--+ 1 bower bower 12 May 13 23:15 file_bower [alice@localhost share]$ getfacl dir_alice # file: dir_alice # owner: alice # group: alice user::rwx group::rx group:html:rwx mask::rwx other::rx default:user::rwx default:group::rx default:group:html:rwx default:mask::rwx default:other::rx
因为我们将-d
传递给setfacl
它指示新的目录也inheritance(并将inheritance应用到更多的子目录)。 所以,现在作为用户deploy
我们可以添加和编辑该新子目录内的现有文件。
[alice@localhost share]$ touch dir_alice/file_indir_alice [alice@localhost share]$ exit exit # sudo -u deploy /bin/bash [deploy@localhost share]$ cd /var/www/html/share/dir_alice/ [deploy@localhost dir_alice]$ touch file_indir_deploy [deploy@localhost dir_alice]$ rm file_indir_alice [deploy@localhost dir_alice]$
你混淆了sticky和setgid的语义。
当多个用户被允许在该目录中创build文件和目录时,会使用目录上的粘性位,但只允许更改他们自己创build的那些内容,不允许混淆其他用户创build的内容。 /tmp
目录是这个典型的用例。
粘性位不被子目录inheritance。 为了达到预期的目的,没有必要inheritance它。 除了创build者之外,在粘性目录中创build的子目录默认情况下都是禁止的。
目录上的setgid位表示在该目录内创build的文件和目录从该目录inheritance组,而不是获取创build它的当前用户组。 setgid位由在setgid目录内创build的新目录inheritance。
setgid位可以实现您尝试实现的一部分目标。 它将实现目录和文件的整个层次结构将具有相同组的部分(除非明确地被重写)。
但是,这并不能保证所有内容都可以被小组写入。 这可以通过umask设置来实现。
umask表示一组位,不能在新创build的文件和目录中设置。 umask的典型值是0077
。 在你的情况下,你希望这些目录是可写的,这意味着你想要0002
,这意味着创build的内容对于组外的每个人都是可读的,或者说0007
,这意味着创build的内容对于组外的每个人都是不可访问的。
您需要确保umask在创build新文件或目录之前的某个时间点被设置。 umask由subprocessinheritance。 注意在特定目录之外创build的文件,因为umask也在其他地方应用,所以在其他地方创build的任何东西仍然可以由组写入,即使这是与/var/www
层次结构中使用的不同的组。
您可以尝试通过使其仅附加到chattr来重置根目录的权限:
chattr +a /var/www/mysite