Nginx 中每个虚拟主机的用户

Nginx 中每个虚拟主机的用户

nginx 中每个虚拟主机配置不同的用户是否可行?

就像是

 server {
     user myprojectuser myprojectgroup;
     ...
 }

答案1

不是,因为 nginx 配置中的所有服务器节都由同一组工作进程提供服务。此外,从安全角度来看,您更好的像那样运行它,因为这意味着内容自动地不可被网络服务器写入(没有像这样的愚蠢行为chmod -R 0777),这样如果 nginx 中存在漏洞,则任何内容都不会受到威胁。

答案2

是的。为了提高安全性,可以这样做,并且建议这样做(请参阅末尾的原因)。

我们可以使用 Nginx 的反向代理功能来实现这一点。我们在单独的进程(和用户)上运行每个主机,作为单独的 Web 服务器运行。Nginx 监视标准 HTTP 端口(80/443)并将外部请求代理到适当的主机。

在 Nginx 上实现此目的主要有两种方法:

  • 代理密码:解决方案复杂,但更灵活。您为每个虚拟主机设置一个 Web 服务器实例。通常,它是使用容器(例如 docker)实现的,并设置一个 Linux 服务(systemd)来协调这一切;
  • fastcgi_pass:简单易用,但每种语言的实现方式不同,且并非所有语言都支持。有局限性,但对大多数基本情况来说效果很好;

PHP

对于 PHP 用户,您可以使用 PHP-FPM 轻松实现这一点。

如果您不确定是否使用 PHP-FPM,那么您可能正在使用,因为它是 Nginx 与 PHP 的默认设置。

这个想法是创建多个“spool”,每个主机一个。然后,我们为每个spool关联一个不同的用户。

1.为每个虚拟主机创建一个用户

假设我们有虚拟主机(又称“服务器块”)mywebsite1。其文件夹位于/var/www/mywebsite1

首先,我们为其创建一个新的用户和组:

adduser myuser1

此命令还创建一个同名的组(myuser1)并将用户分配给该组。

现在,该用户应该是唯一可以访问其网站文件夹和文件的用户:

chown -R myuser1:myuser1 /var/www/mywebsite1

我不建议将用户添加到“www-data”组。

如果您需要 Nginx 访问网站文件,请参阅“Nginx 文件访问”部分了解更多详细信息和解决方案。

2. 创建线轴

打开主假脱机配置文件(例如/etc/php/7.0/fpm/pool.d/www.conf)并为每个虚拟主机添加一个假脱机:

线轴编号 1 ( mywebsite1):

[mywebsite1]
user = myuser1
group = myuser1
...
listen = /run/php/mywebsite1.sock
...  
listen.owner = www-data
listen.group = www-data

线轴编号 2 ( mywebsite2):

[mywebsite2]
user = myuser2
group = myuser2
...
listen = /run/php/mywebsite2.sock
...  
listen.owner = www-data
listen.group = www-data

或者,您可以.conf为每个线轴创建一个新文件。这将使文件更有条理。

listen.ownerlisten.group必须是 Nginx 使用的同一个用户(通常是)www-data。这并不意味着用户www-data可以访问网站文件夹及其文件。这与套接字文件权限有关。这意味着www-data可以向套接字文件发送 HTTP 请求。

3. 更改服务器块

将每个服务器块分配到其缓冲池。

主持人1:

server {
    ...
    location / {
        fastcgi_pass unix:/run/php/mywebsite1.sock;
    }
    ...
}

主持人2:

server {
    ...
    location / {
        fastcgi_pass unix:/run/php/mywebsite2.sock;
    }
    ...
}

4.重启FPM和NGINX服务

sudo /etc/init.d/php7.0-fpm restart
sudo service nginx restart

PS:“php7.0-fpm”替换为你实际的PHP-FPM。

5. 测试

创建一个pinfo.php(或任何名称)文件来显示当前进程用户:

<?php 
echo str_replace("\n", '<br>', shell_exec('ps -u -p '.getmypid()));

pinfo.php或者通过终端创建文件:

echo "<?php echo str_replace(\"\\n\", '<br>', shell_exec('ps -u -p '.getmypid()));" > pinfo.php

然后http://.../pinfo.php在浏览器上打开。


Nginx 文件访问

不要将用户添加到该www-data组中。否则,这样做的目的可能落空。

控制网站的攻击者可以访问该www-data组织拥有的文件,包括 Nginx 文件。

此外,不要将文件和文件夹的所有权更改为www-data组。否则,获得另一台主机控制权的攻击者可以访问它们。保持它们的所有权为user:usergroup

Nginx 不需要直接访问网站的文件夹和文件。

允许 Nginx 直接访问文件的唯一原因是为了更优化地提供图像、视频等静态文件。

如果您想这样做,请参阅下一部分“通过 Nginx 提供静态内容”。

通过 Nginx 提供静态内容

假设出于性能原因,您允许 Nginx 访问公共静态文件。假设这些公共静态文件位于/var/www/mywebsite1/public

首先,为它们添加一个别名,并使“fastcgi_pass”不代理该文件夹:

server {
    ...
    location /public {
        alias /var/www/mywebsite1/public;
    }

    location ~ ^/public/ {
        fastcgi_pass unix:/run/php/mywebsite2.sock;
    }
    ...
}

之后,我们需要Nginx有访问文件的权限。

有以下几种选择:

www-data1. 为用户添加网站组

使 Nginx 用户 ( www-data) 加入网站组 ( myusergroup1):

usermod -aG myusergroup1 www-data

这使得 Nginx 可以访问网站的文件,但反过来不行。

2.允许所有用户读取公共资产文件夹

无论如何,这些文件在互联网上都是公开可见的。

# Only do this if you don't want the previous solution
chmod -R o+r /var/www/mywebsite1/public

为什么要使用多个用户(安全原因)

假设您在同一用户下运行所有​​网站(例如)。在这种情况下,对//的www-dataPHP 调用将可以访问所有网站!system()passthru()exec()

NGINX 不会保护您免受此影响。

PHP 就是一个例子,但任何流行的 Web 服务器语言都有类似的调用。作为黑客,您可以ls ..浏览所有网站。您可以cp//在任何文件(包括其他网站文件)中编写代码。echomv

即使同一个人拥有服务器上的所有网站(例如您),也建议使用不同的用户运行每个网站,因为这样可以防止最终的黑客和病毒访问您的其他网站。

答案3

回应 Ivan 的上述评论,这似乎适用于 OP。两件事:

  1. 应用程序文档根目录类似于/blah/peterWeb/html/blah/johnWeb/html。即使 NGINX 和 Apache2 都以组的形式运行 www-data,它们都不允许其中一个目录浏览或操作另一个目录。

  2. 将每个目录树置于其自己的用户权限之下将允许每个用户通过 ssh/login 进入 UNIX 系统,并将他们的目录保持为私有 - 只是不要将每个用户放入 www-data 组。如果您同意,那么您的句子:

    每个可以提供 PHP 脚本或 cgi-bin 进程的用户都可以访问 www-data 用户可访问的任何文件。

    可能更准确地写成:

    与 apache/nginx 服务器(www-data)属于同一组的每个用户都可以在其可访问的任何文件(本质上是 Web 服务器上的所有内容)中执行任何他们想做的事情(包括运行 php 脚本)。

编辑1: 为了解决一些服务器管理问题,我进一步研究了这个主题。我不知道 Ivan 的信息有多准确!如果您打算让用户能够在共享主机配置上上传和运行脚本,那么请注意。这里是一种方法. 感谢 Ivan 帮助我理解了这个漏洞。

答案4

我自己也在寻找解决方案,并发现了两种可能的解决方法:

Nginx 的几个实例

首先,可以运行多次Nginx,每个都在不同的用户下,这确实回答了提出的问题

当然,您需要一个主实例来监听外部接口上的 80/443 端口,并将相应的请求代理到监听不同端口(如 127.0.0.1:8001 等)的其他实例。只需为不同的用户创建不同的配置文件,然后运行多个实例即可nginx -c /path/to/config_xxx

设置正确的文件夹权限+不同的 php-fpm 用户

另一个解决方案是实际问题,“向其他用户隐藏用户文件的方法”将是丹尼尔的回答并使用户目录彼此无法访问,但允许 Nginx 进入它们。

为此,只需将用户目录保留在user:usergroup权限下,但将www-data用户添加到每个用户的组!通过类似 的命令usermod -a -G usergroup www-data。这个简单(不是说 - 愚蠢)的技巧将保持用户文件夹的权限不变,但将允许 nginx 进入它们并提供静态内容。

相关内容