我们在工作中一直遇到一个问题。我们在共享主机上设置了许多网站,我们的 cms 向这些网站写入许多文件,并允许网站的用户上传文件等。
问题是,当用户在网站上传文件时,该文件的所有者将成为网络服务器,因此我们无法通过 FTP 更改权限等。
有几种解决方法,但我们真正需要的是,如果可能的话,在服务器上创建的新文件和目录上设置固定所有者。例如,php 不是以用户 apache 的身份写入文件,而是以父目录的所有者的身份写入文件。
我不确定这是否可能(我从未见过这样做。)有什么想法吗?
我们显然无法获得 apache 服务器的登录名,而且我怀疑我们也无法进入 apache 组。
也许我们需要一种方法来允许 apache 至少设置一个文件的组,这样我们就可以在 php 中将组设置为我们的 ftp 用户,并为任何写入的文件设置 664 和 775?
干杯,约翰。
答案1
POSIX ACL 允许您设置可继承的 ACL。如果您为目录设置了默认 ACL,则在创建新文件时,该 ACL 会沿堆栈向下继承。
$ sudo mkdir /tmp/acltest
$ ls -ld /tmp/acltest
drwxr-xr-x 2 root root 4096 2011-01-13 20:39 /tmp/acltest
$ touch /tmp/acltest
touch: setting times of `/tmp/acltest': Permission denied
此时我的用户 (daniel) 无法在此目录中创建文件。我为目录设置了默认 acl,并在顶级目录上设置了用户 acl(默认适用于在此目录中创建的文件/目录,而不是实际目录本身)
$ sudo setfacl -m d:u:daniel:rwx /tmp/acltest/
$ sudo setfacl -m u:daniel:rwx /tmp/acltest/
现在,我可以创建一个文件:
$ touch /tmp/acltest/foo
$ ls -la /tmp/acltest/foo
-rw-r--r-- 1 daniel daniel 0 2011-01-13 20:41 /tmp/acltest/foo
此外,我可以对其他用户在此目录中创建的文件执行任何我想执行的操作:
$ sudo mkdir /tmp/acltest/foo2
$ ls -ld /tmp/acltest/foo2
drwxrwxr-x+ 2 root root 4096 2011-01-13 20:49 /tmp/acltest/foo2
$ sudo touch /tmp/acltest/foo2/bar
$ ls -la /tmp/acltest/foo2/bar
-rw-rw-r--+ 1 root root 0 2011-01-13 20:43 /tmp/acltest/foo2/bar
正常的 unix 权限不允许我触及这一点,但是 ACL 却另有规定:
$ getfacl /tmp/acltest/foo2/bar
# file: tmp/acltest/foo2/bar
# owner: root
# group: root
user::rw-
user:daniel:rwx #effective:rw-
group::r-x #effective:r--
mask::rw-
other::r--
请注意,该文件位于 /tmp/acltest 目录的子目录中,因此正常的 unix 权限不允许我对该文件执行任何操作。
事实上,用户 daniel 可以对此文件做任何他们想做的事情:
$ mv /tmp/acltest/foo2/bar /tmp/acltest/foo2/bar2
$ ls -la /tmp/acltest/foo2/
total 8
drwxrwxr-x+ 2 root root 4096 2011-01-13 20:49 .
drwxrwxr-x+ 3 root root 4096 2011-01-13 20:43 ..
-rw-rw-r--+ 1 root root 0 2011-01-13 20:43 bar2
请注意,默认 acl 只会在创建新文件和目录时传播。您需要执行一次递归设置操作来设置所有内容,然后您的默认 acl 将接管。
为了使用用户 acl,您需要确保您的文件系统在 /etc/fstab 中使用 acl 选项进行挂载。
总结POSIX ACL 将允许您设置沿文件系统树传播的粘性用户/组权限。
编辑:格式化和安装选项
答案2
acl 可能非常危险 - 而且支持情况各不相同。更好的解决方案是使用组粘性位,并使文件可由组写入。
问题是,当用户在网站上传文件时,该文件的所有者将成为网络服务器,因此我们无法通过 FTP 更改权限等。
这毫无意义——用户怎么能成为网络服务器?或者你是想描述一下发生了什么PHP 安全模式禁用 gid 检查?在这种情况下,解决方案可能是使用带有 safe_mode_gid 的粘性组位,但是 safe_mode 功能已弃用并且您应该寻找一个不依赖于它的其他解决方案。
许多网站都建立在共享主机上
您是否拥有主机的 root 访问权限?如果没有,那么您绝对应该考虑迁移到专用或虚拟主机,在那里您可以实际控制这些内容 - 如果您无法更改配置,那么您的仅有的选项是使用共享帐户。
您还应该停止使用 FTP——它是一场安全噩梦,而且很难实现自动化。
答案3
我解决此类问题的唯一方法是让 root 运行常规 cronjob,设置 webserver 目录中文件的权限。这有点丑陋,但效果不错。
答案4
您可以使用 fsniper,而不是运行 cronjobs 来更改所有权:http://freshmeat.net/projects/fsniper
fsniper 监控目录中的新文件(通过 inotify)并立即触发脚本,而不是定期触发。