我花了一个多小时在网上寻找答案,但令人惊讶的是,没有一个适合我的问题。
我有一个小型专用服务器,上面托管了一些东西。主要是:一个 Owncloud 服务器和一些我和我朋友的网站(主要是 Wordpress、MediaWiki 等东西……)。
我将 Nginx 用于不同的网站(每个网站一个 conf.d 文件)。
对于每个需要 php 的站点,我都会创建一个 php-fpm 池。
对于每个站点:
- 我创建了一个用户:[website_user]。
- 我在其主目录中创建了一个 public_html 目录。
- 如果有必要,我会允许用户通过 sftp 访问该目录。
- 我将 php-fpm 池配置为在 [website_user] 下运行。
- 我将每个网站的文件设置为由 [website_user]:[nginx] 用户拥有
- 我将每个网站的文件权限设置为 750
这是好的做法吗?这种模式是否存在缺陷?
我的 Owncloud 托管了一些非常敏感的信息(即使它们是加密的,而且它“只是”一个私人服务器:我不是 CIA 或大公司)。
我是否应该在 Chroot 中为 Owncloud 运行另一个 Nginx 服务器,或者我的设置是否足够安全?
答案1
一切正确(在不同的用户下运行 PHP-FPM 池),但有少数例外。
假设您的 NGINX 工作进程作为 运行nginx
,而 PHP-FPM 池作为 运行foo
。
从列表顶部向下,问题如下:
我将每个网站的文件设置为由 [website_user]:[nginx] 用户拥有
错误。如果 PHP 脚本创建了一些文件(例如处理上传),那么该文件可能归foo:foo
。因此,无法保证 NGINX 以后能够读取它。
foo:foo
因此最好的方法是从一开始就拥有所有文件。
现在要做的神奇的事情是让运行 NGINX 工作进程的用户foo
成为用户组成员复杂吗?其实不然:
usermod -a -G foo nginx
这将使nginx
用户成为foo
网站用户组(补充)。换句话说,nginx
用户现在属于以下组:nginx
和foo
。网站用户foo
只是的成员foo
。
对于将在另一个 PHP-FPM 池中以用户身份运行的另一个网站bar
,您将执行相同的操作:将nginx
用户添加到用户组bar
。
通过这种方式,您现在可以通过调整设置的组部分非常灵活地定义 NGINX 可以看到和看不到的内容chmod
。
如果您现在想要,您可以拥有限制最少的 chmod,它适用0750
于目录和0640
文件。然后 NGINX 可以看到所有内容,PHP-FPM 也可以看到。在站点文件中设置它的简单方法:
chmod -R u=rwX,g=rX,o= /path/to/site/dir
我使用X
,以便仅在目录上设置可执行(即在目录上下文中遍历)位。因此,0750
当文件为 时,您最终只会对目录进行所需的操作0640
。
但你可以轻松地进行更多限制。比如,NGINX 不应该读取,/config.php
因为它仅由 PHP 用户读取,不需要由 NGINX“读取”,因此你可以轻松地执行以下操作:
chmod 0600 config.php
并且它仍将按预期工作。
如果你没有在 NGINX 配置中做任何文件存在性检查(例如 no if (-f $request_filename) {
),那么你甚至可以在每个 PHP 文件上设置相同的设置0600
,甚至0400
可以为锁定配置设置 :) 例如,参见我的帖子Magento 锁定配置。
答案2
我冒昧地添加了一些我认为非常有趣的内容,但奇怪的是,网络上几乎没有涉及过这些内容。
几年来,人们一直建议在使用池进行共享托管时禁用 OPcache。一个众所周知的安全问题是 OPcache 允许池的 PHP 进程访问另一个池的文件,即使用户对这些文件没有任何权限。
事实证明,这个错误已经修复,但是:
- 它还没有真正被宣传过
- 默认设置未启用它。
因此,如果您的 PHP 版本是最新的(PHP7 <7.0.14 和 PHP5 <5.6.29),您可以在共享主机池环境中安全地启用 OPcache,只要您将这些选项添加到您的设置中:
opcache.validate_permission=1
opcache.validate_root=1
opcache.use_cwd=1