我正在给出安装 VPS Web 服务器(Debian 8 + Apache 2 + PHP 5.6)的第一步,并且需要一些有关文件/文件夹权限的帮助。
我已经找到了一些关于这个主题的类似主题(不完全相同),而且都是 4 或 5 岁的。其中一些指出了使用已弃用的 PHP 方法的解决方案。也许今天有一些新的方法或解决方案。
好吧,Apache 2 是在www-data
用户/组中运行的。因此,我创建了一个名为 的用户webadmin
,将其放入www-data
组中并将其配置为主网站文件夹的所有者:
adduser webadmin
usermod -a -G www-data webadmin
chown -R webadmin:www-data /var/www/website.com
我还更改了权限公共_html像这样的文件夹:
find /var/www/website.com/public_html -type f -exec chmod 644 {} +
find /var/www/website.com/public_html -type d -exec chmod 755 {} +
find /var/www/website.com/public_html -type d -exec chmod g+s {} +
并创建了将接收上传文件的文件夹(仅限静态文件 - 图像):
mkdir /var/www/website.com/public_html/uploads
chown webadmin:www-data /var/www/website.com/public_html/uploads
chmod 774 /var/www/website.com/public_html/uploads
现在,发生了什么:我使用 SFTP 上传的所有文件夹和 PHP/Html 文件(记录为webadmin
)当然会成为webadmin
所有者。当我使用 PHP 创建子文件夹并上传图像时,它们将用户www-data
作为所有者。在这种情况下,我遇到了一些权限问题,例如通过 SFTP 删除文件。
webadmin
我可以指定 Apache 作为用户和组运行www-data
,但我认为我可能会遇到安全问题(不是吗?)。请问,是否有标准和最佳实践来配置服务器或 PHP 脚本来创建文件夹并上传文件以避免此问题?
答案1
您的问题是新文件不可组写。而不是使用设置gid在目录上设置组,使用前交叉韧带s这提供了更大的灵活性。
这默认访问控制列表新文件和目录继承条目,授予 ACL 中定义的权限。要设置一个默认访问控制列表webadmin
允许组输入rwx
:
setfacl -m default:g:webadmin:rwx /var/www/website.com/public_html/uploads
在该目录中创建的新文件对于 group 来说是可读可写的webadmin
。
如果 ACL 不是一个选项,你需要改变掩码,它确定新文件的默认 UNIX 权限。新人的明智选择掩码是002
(世界可写位屏蔽)和007
(所有世界权限位屏蔽,即只有组和所有者有权访问)。
设置阿帕奇掩码,将systemd单元文件复制到/ETC:
cp /lib/systemd/system/apache2.service /etc/systemd/system/
配置掩码通过/etc/systemd/system/apache2.service
附加UMask=<umask>
到[Service]
部分。请注意,这会影响 Apache 创建的所有文件。
改变掩码为了sftp仅当您需要更改从 PHP/Apache 上传的文件/目录时才需要。默认 umask022
创建文件组和全局可读,但组不可写。配置默认值的最简单方法掩码为了sftp与pam_umask
。
应用您的自定义掩码仅适用于特定组中的用户并且仅在使用时sftp,附加/etc/pam.d/sshd
:
session [default=1 success=ignore] pam_succeed_if.so user notingroup <yourgroup>
session optional pam_umask.so umask=<umask>
第一条规则告诉 pam 如果用户不在组中则跳过下一条规则<yourgroup>
,即仅当用户在组中时才应用下一条规则<yourgroup>
。第二条规则将 umask 设置为<umask>
。
附录:请注意,移动的现有文件mv
保留其原始权限和所有权。您可以通过复制文件来应用 umask 和目录 setgid/ACL 的默认权限cp -d
。
答案2
标准的好处是通常有很多可供选择。
感谢您考虑权限并防止您的网络服务器 uid 能够写入除上传内容之外的文件。我确实希望您已经完全禁用了上传目录中的 php 执行。目前,您的模型存在一些缺陷,因为您正在将 apache 添加到具有额外特权的组中。但这只是问题的一部分——但我偏离了你问的问题。
您创建的用户意味着您拥有该设备的 root 权限(您应该明确提及这一点)。但您没有说您使用的是自己的软件还是现成的软件包。后者会产生一些复杂性,因为定制它可能会影响您应该进行的定期修补。如果 apache 是您打算在目标上拥有高度控制权限的唯一 uid,那么您可以通过将 apache 的文件访问权限设置为“其他”而不是用户或组来解决问题。
或者,为了向其他帐户提供对上传内容的访问权限,只需使用 umask 000/chmod 将文件更改为 666。请注意,move_uploaded_file() 实际上会创建一个副本并删除原始文件,并且重要的是,文件创建遵循 umask。因此,任何正确编写的 php 都可以将 http 上传的内容存储为世界可读可写,而无需通过为网络服务器设置 umask 000 来更改任何代码。
或者,您可以编写一个 shell 脚本来将 http 上传内容的权限更改为允许您使用普通用户帐户操作内容的权限,然后授予您的网络服务器 uid 通过 sudo 调用该脚本的权限。这需要由您的代码在 move_uploaded_file() 之后调用。
或者,一个相当丑陋的解决方案是在链接到脚本的上传目录上放置一个 inotify 监视来修复权限(例如使用因克朗)
作为最后的手段,您可以在上传目录上运行常规 cron 作业来修复权限。
我建议使用掩码方法。