强制所有者创建的文件和文件夹

Mar*_*sen 29 filesystems permissions debian

我有一个目录,其中包含多个用户之间共享的数据。对该目录及其下的任何内容的访问将由该目录的组控制,该组将添加到相关用户中。因此,我创建了文件夹“粘性组”chmod g+s集。该目录将包含一个包含目录和文件的树结构,文件总数可能有几百万。这些文件会相当小,我预计不会超过 50MB。

我的问题是文件或目录的所有者仍然是创建它的用户。因此,即使我应该从访问组中删除该用户,我也不会完全删除他的访问权限。

所以:

我是否错过了其他选项以确保所有文件和子目录具有相同的所有者?

我希望我可以定期使用 cron-job 浏览整个目录,但这让我觉得对于本质上是一次 pr-file 命令的效率低下。

我找到了一个使用 INotify的示例,但我觉得它需要高维护,因为它需要编写脚本。

我一直无法弄清楚 ACL 是否可以帮助我强制所有权。

有没有更聪明的方法来做到这一点?

我想要的是有一个可以通过向用户添加组来共享的目录。在此目录中创建的任何内容都从其父级继承权限方案。如果有比我正在尝试的更好的方法,我会全神贯注。

Joh*_*ith 16

“自动”设置默认所有者将需要一个setuid行为类似于setgid. 然而,虽然这可以在 FreeBSD 上配置,但其他 UNIX 和 Linux 系统只是忽略u+s. 但是,在您的情况下,可能有另一种解决方案。

我想要的是有一个可以通过向用户添加组来共享的目录。在此目录中创建的任何内容都从其父级继承权限方案。如果有比我正在尝试的更好的方法,我会全神贯注。

所以,基本上,据我所知,您希望使用组机制来控制对目录的访问。但是,这不需要您限制整个目录结构中的权限。实际上,目录--x执行位可能正是您所需要的。让我给你举个例子。假如说...

  • 控制group_dir目录访问的组是ourgroup。
  • 只有ourgroup组内的人可以访问group_dir。
  • user1并且user2属于ourgroup.
  • 默认 umask 是 0022。

...考虑以下设置:

drwxrws---    root:ourgroup   |- group_dir/
drwxr-sr-x    user1:ourgroup  |---- group_dir/user1_submission/
drwxr-sr-x    user2:ourgroup  |---- group_dir/user2_submission/
-rw-r--r--    user2:ourgroup  |-------- group_dir/user2_submission/README
Run Code Online (Sandbox Code Playgroud)

在这里,让我们假设每个项目都是由其所有者创建的。

现在,在这个设置中:

  • 中的每个人都可以自由浏览所有目录ourgroup。组中的任何人都可以在组内的任何位置group_dir(但不能更深)创建、移动、删除文件。
  • 任何不在的人ourgroup都会被封锁在group_dir,因此将无法操纵它下面的任何东西。例如,user3(他不是 的成员ourgroup)无法读取group_dir/user2_submission/README(即使他r--对文件本身有权限)。

但是,在这种情况下有一个小问题:由于典型的 umask,用户创建的项目不能被组的其他成员操作。这就是 ACL 的用武之地。通过设置默认权限,您将确保尽管有 umask 值,但一切正常:

$ setfacl -dRm u::rwX,g::rwX,o::0 group_dir/
Run Code Online (Sandbox Code Playgroud)

此调用设置:

  • rw(x)所有者的默认权限。
  • rw(x)组的默认权限。
  • 其他人默认没有权限。请注意,由于其他人group_dir无论如何都无法访问,因此他们的权限低于它并不重要。

现在,如果我创建一个项目user2:

$ touch group_dir/user2_submission/AUTHORS
$ ls -l group_dir/user2_submission/AUTHORS
rw-rw----    user2:ourgroup    group_dir/user2_submission/AUTHORS
Run Code Online (Sandbox Code Playgroud)

有了这个 ACL,我们可以尝试重建我们之前的结构:

drwxrws---+    root:ourgroup   |- group_dir/
drwxrws---+    user1:ourgroup  |---- group_dir/user1_submission/
drwxrws---+    user2:ourgroup  |---- group_dir/user2_submission/
-rw-rw----+    user2:ourgroup  |-------- group_dir/user2_submission/README
Run Code Online (Sandbox Code Playgroud)

同样,每个项目都是由其所有者创建的。

此外,如果您想为使用该目录的人提供更多的功能/安全性,您可能需要考虑一些棘手的问题。例如,这将阻止user1删除user2_submission(因为他有-w-权限group_dir):

$ chmod +t group_dir/
Run Code Online (Sandbox Code Playgroud)

现在,如果user1尝试删除user2的目录,他会得到一个可爱的Operation not permitted. 但是请注意,虽然这可以防止 中的目录结构修改group_dir,但它下面的文件和目录仍然可以访问:

user1@host $ rm -r user2_submission
Operation not permitted

user1@host $ >     user2_submission/README
user1@host $ file  user2_submission/README
user2_submission/README: empty (uh-oh)
Run Code Online (Sandbox Code Playgroud)

另一件需要考虑的事情是我们使用的 ACL 设置了默认权限。因此,项目的所有者可以更改与其关联的权限。例如,user2可以完美运行...

$ chown g= user2_submission/ -R
or
$ chgrp nobody user2_submission -R
Run Code Online (Sandbox Code Playgroud)

...因此使组中的任何人都无法访问他的完整提交目录。

但是,由于您最初愿意向rws组中的任何人授予完全访问权限,因此我假设您信任这些用户,并且您不会期望他们进行太多恶意操作。


小智 7

有一种更聪明的方法可以做到这一点。它使用 set-gid 和默认acls的组合。显然,您将需要启用 acl 的文件系统。假设您要共享的目录位于/var/grpdir并且组成员sharing应该能够访问它。

chown root:sharing /var/grpdir
chmod 2770 /var/grpdir #other can't read or traverse into the directory, set-gid is set
setfacl -d -m u::rwX,g::rwX,o::0 /var/grpdir
Run Code Online (Sandbox Code Playgroud)

默认 ACL 由在具有默认 ACL 的目录中创建的子目录继承。所以这意味着,在其中创建的任何文件/var/grpdir都将sharing通过目录的 setgid 位将其组设置为。此外,它将继承默认的 acls,这将覆盖默认的 linux 样式权限,因为我们没有为特定用户或组指定 ACL。这意味着创建的所有文件都具有所有权<user>:sharing和权限rw-rw----。目录将是相同的,除了它们还将自己的默认 ACL 设置为与其父目录 ( /var/grpdir)相同,当然还有为用户和组设置的可执行位。如果您从sharing组中删除用户,他们将无法访问该目录(也无法访问其中的任何文件,即使他们拥有这些文件)。

与使用 cronjob 定期更正权限不同,权限始终同步,因为它们会使用新创建的文件和目录自动更新。这个解决方案是轻量级的;不需要守护进程,并且一举纠正权限时 IO 也不会出现峰值。