PHP脚本/目录需要哪些权限?

30

我试图帮助朋友将一个网站从一个网络酒店转移到另一个。旧地方已经关闭,我只有一个打包的tar文件。

该网站包含HTML文档,并且可以下载一个小型Java应用程序(要加载到手机上),以向该网站发送数据。

移动Java应用程序将字符串发送到URL=<HOST>/php/register.php。此PHP脚本包括另一个PHP脚本(../inc/db_login.php),该脚本使用$link=mysql_connect()连接到SQL数据库。另一个文件register.php执行SQL插入操作,将新发送的数据放入数据库中。

我的问题基本上是,在新网站上应该把这两个PHP文件放在哪里,目录和文件应该具有什么权限?

旧的Web服务器显然有一个/php/inc目录。新服务器没有这些目录。我应该创建它们吗?它们应该具有什么权限?我猜密码存在单独的PHP文件中是为了安全考虑。 /php/inc目录可能具有不同的权限。

新服务器有目录:

  • /httpdos
  • /httpsdos
  • /cgi-bin
  • /conf(以及一些可能无关紧要的目录)

我的问题:

  1. 文件扩展名(.php)对服务器有意义吗:由于PHP脚本被包含在HTML代码中(在<?...?>之间),服务器是否需要查看文件后缀或者是无关紧要的?(当然,我知道服务器会响应<?...?>

  • 应该将公共文件(在我的情况下是register.php)放置在httpdocs/目录中,还是服务器(我想是apache)会有反应并从另一个目录获取它?

  • 从操作系统的角度来看,PHP脚本是否应具有权限R-X(读取和执行),--X(执行)或R--(读取)?我猜apache只是读取这些文件,这意味着它们应该是R--,但这意味着如果PHP服务“停止”,客户端将在浏览器中获取所有PHP代码吗?我更喜欢它是--X,但由于这既不是二进制文件也没有#!,我猜它必须是--R

  • 如果可以将公共PHP脚本放置在另一个目录中(例如/php而不是/httpdocs),那么/php(和脚本)需要什么权限?我猜服务器必须知道这个/php目录(还是有通常的默认值?)

  • 包括的PHP脚本(../inc/db_login.php,包含SQL密码)不应该在/httpdocs下。这意味着我的register.php正在包含一个不在/httpdocs子树下的文件。这是否有效?服务器需要知道吗?

  • 7个回答

    58

    为了能够使用,目录必须具有可执行权限,通常是0755。通过mod_php运行的PHP脚本不会被执行,而是被读取;0644足以满足此需求。必须写入的目录需要由Web服务器正在运行的用户拥有所有权。可能还存在有关权限的其他问题,例如SELinux,但上述内容将帮助您完成基础操作。

    必须对其他用户或外部客户端不可访问的文档进行保护,可以将其设置为0600,所有权归Web服务器用户所有,并且位于DocumentRoot之外。请注意,使用Safe Mode运行mod_php将防止脚本包含DocumentRoot之外的任何内容;这是一个令人遗憾的缺陷。


    谢谢您的回答。我会把register.php放在httpdocs/php中。 现在我尝试创建/inc并包含../../inc/db_login.php,但/inc的创建被拒绝了... db_login.php应该放在cgi-bin中吗?如果apache处于安全模式,那么db_login必须放在httpdocs树中...这不是一个安全风险吗? - christophe milard
    但是,如果register.php和db_login.php都在html文档根目录下,并且它们的权限相同,将它们放在2个不同的文件中有什么好处(从安全角度来看)?我认为这样做的想法是围绕包含在db_login中的密码提供“更多安全性”... 如果PHP失败,代码是否会传递给客户端存在风险?再次感谢您的时间。/C - christophe milard
    @IgnacioVazquez-Abrams,为什么不把它改成604而不是644呢? - Pacerier
    @Pacerier:因为下一个看到它的人会说“什么鬼?”并且无论如何都会把它改回去。 - Ignacio Vazquez-Abrams
    @IgnacioVazquez-Abrams,将其放置在004处以防止意外编辑是个好主意。 - Pacerier
    显示剩余2条评论

    17

    将php文件设置为640

    为了最大限度地提高安全性,您应该设置最低权限,即640

    • 所有者6是上传文件的人。
    • 组4是提供文件的组。将apache设置为组成员。
    • nobody 0意味着没有其他用户可以读取此文件。这很重要,因为PHP脚本有时会包含密码和其他敏感数据。

    永远不要允许所有人读取PHP脚本。

    有用的命令:

    chmod 640 file.php
    chown user:group file.php
    usermod -a -G group apache
    

    这些命令的作用:

    1. 更改 file.php 文件的所有者,以便用户可以读写,组可读。
    2. 更改 file.php 文件所有者为指定的用户名和组名。
    3. 将 Apache 添加到组中,以便 Apache 可以提供文件服务。否则,640 将无法正常工作。

    1
    这是PHP脚本的最佳答案。除非有充分的理由,否则对于PHP脚本,请使用“go-to”权限级别为640。这个问题只回答了一半的问题,但它是那半个问题的最佳答案。我很想知道人们为什么会使用其他东西。 - garydavenport73
    1
    好观点。解释清晰明了。它表明出于安全目的,不允许比所需权限更多的权限是更好的选择。 - Marcellin Wabo

    1

    1) 以 .php 结尾的文件将被 Apache 交给 PHP 编译器处理。如果没有正确设置,PHP 文件将由服务器作为文本文件提供。在 httpd.conf 文件中的 Apache 配置行 "AddHandler php5-script php" 是设置 PHP5 的方法。

    2) register.php 需要在 http://www.example.com/php/register.php 上可访问,因为 Java 应用正在寻找它,所以在 Apache htdocs 文件夹中,需要有一个名为 "php" 的文件夹,并且其中包含 register.php 文件。

    3) 运行 Apache 服务的用户需要对 PHP 文件具有读取权限。使用 PHP 作为 Apache 模块时,没有单独的“服务”可供 PHP 使用。相反,当 Apache 服务收到对 PHP 文件的请求时,它会调用 shell 来解析文件并将结果交给 Apache 服务,然后由其提供给客户端。只有在使用命令行(CLI 设置)时,脚本才需要执行权限,并以 #!/path/to/php-bin 开头。

    4) 请求的文件(register.php)需要在htdocs目录下才能被Apache服务器提供。如果PHP运行时禁用了"安全模式",register.php可能会包含一个位于htdocs文件夹之外的文件。

    5) 路径"../inc/db_login.php"是相对于最初获取的PHP脚本(register.php)的,因此,由于register.php位于htdocs/php/register.php,所以db_login.php将位于htdocs/inc/db_login.php


    第三点:CLI和CGI设置都需要执行权限。 - Ignacio Vazquez-Abrams

    0

    将文件权限设置为0644,文件夹权限设置为0755。

    我已经编写了一个库来实现这个功能。

    使用示例:

    <?php
    
    use MathiasReker\FilePerm;
    
    require __DIR__ . '/vendor/autoload.php';
    
    (new FilePerm([__DIR__])) // <-- root directory
        ->setDefaultModeFile(0644) // <-- file permission
        ->setDefaultModeFolder(0755) // <-- folder permission
        ->scan()
        ->fix();
    

    完整文档:https://github.com/MathiasReker/php-file-permissions

    0

    我编写了一个函数来解决PHP / SuPHP和类似环境中的权限问题:

    function realChmod($path, $chmod = null)
    {
        if (file_exists($path) === true)
        {
            if (is_null($chmod) === true)
            {
                $chmod = (is_file($path) === true) ? 644 : 755;
    
                if (in_array(get_current_user(), array('apache', 'httpd', 'nobody', 'system', 'webdaemon', 'www', 'www-data')) === true)
                {
                    $chmod += 22;
                }
            }
    
            return chmod($path, octdec(intval($chmod)));
        }
    
        return false;
    }
    

    也许对你有用。


    你应该考虑使用八进制字面量来代替处理那些 octdec() 的麻烦,并且使用 |= 代替 += - Ignacio Vazquez-Abrams
    2
    你正在使用一个PHP脚本来修复另一个PHP脚本的权限?如果服务器的权限出了问题,不允许运行PHP脚本,那么这个脚本也无法运行。但是,如果你手动修复了这个脚本的权限,那么你就可以使用它来批量恢复其他脚本。不过,从命令行使用chmod -R可能会更快。 - MidnightLightning
    @MidnightLightning:即使在Web服务器上无法正常工作,只要您有shell访问权限,仍然可以通过CLI运行PHP脚本。此外,“chmod -R”可能会很危险,最好使用经过适当设计的“find”命令。 - Ignacio Vazquez-Abrams
    但是,如果register.php和db_login.php都在html文档根目录下,并且它们的权限相同,将它们放在两个不同的文件中有什么好处(从安全角度来看)?我认为这样做的想法是在db_login中包含的密码周围有“更多的安全性”...?如果PHP失败,代码会传递给客户端,这不是一个风险吗? 再次感谢您的时间。 /C. - christophe milard
    将它们拆分并不一定是为了安全,而是为了模块化。如果另一个脚本需要访问与register.php相同的数据库,由于数据库功能是独立的,新文件只需包含db_login.php即可,而无需在所有需要它的脚本中重新编写该代码。此外,如果您的数据库密码发生更改,如果合并它,则必须在使用该数据库连接的所有文件中进行更改,而在当前设置中,您只需更改一个位置即可。 - MidnightLightning

    0
    假设您的SFTP / FTP用户是johndoe,Web服务器组是www-datajohndoe只读取、写入文件,但不执行文件(在我的情况下从未执行)。 Web服务器软件通常来自组www-data的Apache / Nginx可以读取/写入/执行文件。 其他用户? 他们在这里做什么? 因此,我过去设置了0670rw-rwx---),并且始终适用于我 :)

    0

    所有直接通过URL访问的PHP文件可以放置在与静态内容相同的目录中(这是通常的做法)。

    最好有至少一个目录位于Web服务器不可见的位置,用于保存包含文件,但PHP包含路径仍应包括'.'。

    我建议不要在根文件系统中放置大量非标准目录 - 默认的Web根目录因发行版而异,但我通常使用以下内容:

    /var/www/htdocs - 作为文档根目录 /usr/local/php - 用于包含文件

    显然,如果您打算运行您的Web服务器chrrot,则应相应地进行映射。

    所有文件都必须由Web服务器运行的uid可读取,但是如果您尽可能限制此uid可写入的内容,则可以关闭潜在的攻击向量。

    我通常将我的目录设置为drwxrwSr-x,由Web开发小组的成员拥有,组所有权为Web开发团队,(httpd uid不在Web开发组中),因此文件为-rw-rw-r--。因此,Webdex组中的任何人都可以更改文件,而httpd uid只能读取文件。

    1)文件扩展名(.php)对服务器有意义吗:

    是的 - 去阅读PHP安装指南。

    C。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接