在用户目录中保护 PHP

在用户目录中保护 PHP

我是我们大学的一个小型服务器的系统管理员,学生们可以使用该服务器随意进行实验和运行长时间作业。

我在用户目录中启用了 PHP,以便他们可以轻松地试验网站。

最近,我发现用户目录中的所有 PHP 代码均由 Web 服务器用户 (www-data) 运行,该用户拥有一些我显然不想授予用户的权限。存在漏洞的网站或恶意用户可能会删除服务器的常规网站。

有没有办法用用户的权限运行用户的 PHP?

我想到了一个解决方法,即几乎不授予 Web 服务器任何权限,这样入侵就不会造成任何严重后果。这在我的处境下是可行的,因为网站非常简单(纯 HTML 索引)。

该服务器运行的是带有 Apache 2.4.10 的 Debian Jessie。

答案1

我已经使用 nginx、lighttpd 和 apache 多次完成此操作。它们的概念基本相同:以用户身份运行的 [快速]CGI 进程。

如果您想省去很多麻烦,请尝试像其他人建议的那样弄乱权限。特别是,如果您的用户网站由用户拥有,而您的主站点由 root 或类似人员拥有,那么您将处于良好的状态。但用户仍然不会被隔离,并且可以读取彼此的文件等(数据库密码?)。为每个用户/站点运行单独的虚拟服务器将为您提供最大的安全性,并且它肯定比尝试使用 apache 隔离用户更简单。

在 apache 中,隔离 PHP 用户的标准方法是通过 SuExec(还有 mpm-itk)。如果你在 Google 上搜索apache fastcgi suexec或类似内容,你应该会得到很多结果。我认为将满的此处提供了说明。它可能因各种设计决策和使用的发行版而异。相反,我将尝试提供一些我认为重要的要点以及我的配置的简要说明。我的设置非常复杂(除此之外,我还运行了一个自定义 SELinux 模块)。以下是 [希望] 简要概述:

  • 通过将 *.somedomain 指向服务器来实现基于名称的虚拟主机:user.somedomain 是虚拟主机的名称(我假设您可以对用户目录执行同样的事情?)。
  • /etc/httpd/vhosts.d/user.conf每个用户一个。
  • /var/www/vhosts_config每个用户 一个目录。
    • /var/www/vhosts_config/$USER/wrapper-bin包含执行 PHP 的包装器(稍后会详细介绍)
    • /var/www/vhosts_config/$USER/php/php.ini:我喜欢php.ini每个用户都有单独的帐户。
    • /var/www/vhosts_config/$USER/php/ext/*.ini:每个可用扩展一个 ini 文件
    • /var/www/vhosts_config/$USER/php/ext-active/*.ini:每个启用的扩展的符号链接../ext(所以我也可以为每个用户启用/禁用扩展)
  • /var/www/vhosts/user包含 vhost 的实际内容。我建议始终使用public_html子目录作为文档根目录,以便用户拥有文档根目录之外的目录来存储配置文件等。
  • 用户不应该能够彼此的文件。您需要允许+x用户访问 Web 服务器。有多种方法可以做到这一点。我使用 POSIX ACL。

每个用户的 httpd 配置看起来像这样(为简洁起见有所改变):

<VirtualHost *:80>
        ServerName someuser.somedomain
        DocumentRoot /var/www/vhosts/someuser/public_html

        SuexecUserGroup someuser someuser    

        FcgidWrapper /var/www/vhosts_config/someuser/wrapper-bin/php .php

        #max of 5 cgis per vhost
        FcgidMaxProcessesPerClass 5
        FcgidMinProcessesPerClass 0

        AddHandler php-fcgi .php
        Action php-fcgi /wrapper-bin/php

        Alias /wrapper-bin/ /var/www/vhosts_config/someuser/wrapper-bin/

        <Location /wrapper-bin/>
                Options +ExecCGI
                SetHandler fcgid-script
        </Location>
</VirtualHost>

suexecsetuidapache 调用以作为给定用户启动进程的根程序。它非常挑剔。它要求它执行的程序由用户拥有,并包含在用户/var/www拥有的目录的子目录中(这在不同的 Linux 发行版上有所不同,并在编译时设置)。这就是为什么每个用户都需要自己的 PHP 包装器脚本。

/var/www/vhosts_config/someuser/wrapper-bin/php看起来像:

export PHPRC=/var/www/vhosts_config/someuser/php
export PHP_INI_SCAN_DIR=$PHPRC/ext-active/
export PHP_FCGI_CHILDREN=0
umask 0077
exec /usr/bin/php-cgi
  • PHP_INI_SCAN_DIR设置一个目录来查找其他php.ini文件,我用它来加载特定于扩展的配置。
  • PHPRC列出在其中查找php.ini文件的目录。

你不为每个用户使用单独的 PHP 配置,这样做肯定会使事情变得复杂。我喜欢为用户提供精简的配置,只启用必要的配置(默认情况下启用一些常用扩展)。我还为每个用户加载了具有不同配置的 suhosion(不同的加密密钥)。

相关内容