PHP 脚本/目录的权限是啥?

Posted

技术标签:

【中文标题】PHP 脚本/目录的权限是啥?【英文标题】:What permissions for PHP scripts/directories?PHP 脚本/目录的权限是什么? 【发布时间】:2011-01-06 23:08:28 【问题描述】:

我正在尝试帮助一位朋友将网站从一个网络酒店转移到另一个。 老地方已经关门了,我只有一个扁平的 tar 文件。

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

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

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

旧的网络服务器显然有一个/php/inc 目录。这些都不存在于新的网络服务器上。我应该创建它们吗?他们应该有什么权限?我猜想将密码放在单独的 PHP 文件中的原因是安全性。 /php/inc 目录可能有不同的权限。

新服务器有目录:

/httpdos /httpsdos /cgi-bin /conf(还有一些可能无关紧要)

我的问题

    文件扩展名 (.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 子树下的文件。这行得通吗?服务器需要知道吗?

我了解您可能需要了解服务器配置。只需假设您的答案中的默认值(如果是,您可以告诉它在哪里更改)。

【问题讨论】:

【参考方案1】:

目录必须具有执行权限才能使用。通常这是0755。通过mod_php 运行的PHP 脚本不会被执行而是被读取; 0644 就足够了。必须写入的目录需要由运行 Web 服务器的用户拥有。可能还有其他关于权限的问题,例如SELinux,但以上内容将帮助您了解基础知识。

其他用户或外部客户端不得访问的文档应为0600,归网络服务器用户所有,并且位于 DocumentRoot 之外。请注意,在安全模式下运行 mod_php 将阻止脚本包含 DocumentRoot 之外的任何内容;一个可悲的缺陷。

【讨论】:

感谢您的回答。我会将 register.php 放在 httpdocs/php 中。现在我尝试创建 /inc 并包含 ../../inc/db_login.php,但是 /inc 的创建被拒绝了...应该将 db_login.php 放在 cgi-bin 中吗?而且如果apache处于安全模式,那么db_login必须在httpdocs树中……这不是有安全风险吗? cgi-bin 中不应包含 CGI 脚本以外的任何内容。是的,在 DocumentRoot 下拥有配置文件是一个潜在的安全风险; PHP 可以通过一个配置选项来解决这个问题,该选项指定一个可以显式包含的附加目录。但事实并非如此。 但是如果 register.php 和 db_login.php 都在 html doc 根目录下并且它们的权限相同,那么将它们放在 2 个不同的文件中会有什么好处(安全性)。我认为这个想法是围绕 db_login 中包含的密码“更安全”......?如果 PHP 失败,代码到达客户端不是有风险吗?再次感谢您的宝贵时间。 /C 在这种情况下,您可以做的一件事是依赖 httpd 关于点文件的行为; httpd 将不允许外部访问名称以单点开头的文件,例如.db_login.php。问题在于该文件现在默认对ls 和类似工具是不可见的,并且很容易忘记它的存在。 @IgnacioVazquez-Abrams,为什么不改成604 而不是644【参考方案2】:

我编写了一个函数来解决 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() 杂乱无章的东西,并使用 |= 而不是 += 您正在使用 PHP 脚本来修复 PHP 脚本的权限?如果服务器的权限不正常并且不允许 PHP 脚本运行,那么这个脚本也不会运行。虽然如果您手动修复此脚本的权限,那么您可以使用它来批量恢复其他脚本。不过,从命令行使用 chmod -R 可能会更快。 @MidnightLightning:即使 PHP 脚本在 Web 服务器中无法正常工作,仍然可以通过 CLI 运行 PHP 脚本,当然前提是您具有 shell 访问权限。此外,chmod -R 可能很危险,最好使用精心设计的find 但是如果 register.php 和 db_login.php 都在 html doc 根目录下并且它们的权限相同,那么将它们放在 2 个不同的文件中会有什么好处(安全性)。我认为这个想法是围绕 db_login 中包含的密码“更安全”......?如果 PHP 失败,代码到达客户端不是有风险吗?再次感谢您的宝贵时间。 /C. 拆分它们不一定是为了安全,而是为了模块化。如果另一个脚本需要访问与 register.php 相同的数据库,由于数据库功能是独立的,那么该新文件可以只包含 db_login.php 并继续,而不是在所有需要它的脚本中重写该代码。另外,如果您的数据库密码曾经更改过,如果您合并它,则必须在使用该数据库连接的所有文件中更改它,而在当前设置中,您只需在一个地方更改它。【参考方案3】:

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) PHP 文件需要运行 Apache 服务的用户的读取权限。使用 PHP 作为 Apache 模块没有“服务”,这对于 PHP 来说是独立的。相反,当 Apache 服务收到对 PHP 文件的请求时,它会对 PHP 二进制文件进行 shell 调用以解析文件并将结果交给 Apache 服务,然后将结果提供给客户端。仅当您从命令行(CLI 设置)使用 PHP 时,脚本才需要执行权限,并以 #!/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 .

【讨论】:

第 3 点:CLI 和 CGI​​ 设置都需要执行权限。【参考方案4】:

所有打算通过 URL 直接寻址的 PHP 文件都可以愉快地驻留在与静态内容相同的目录中(这是通常的做法)。

最好在网络服务器可见的目录之外至少有一个目录来保存包含文件,但 PHP 包含路径仍应包含“.”。

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

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

显然,如果您打算运行您的网络服务器 chrrot,则应相应地映射它们。

所有文件都必须可由运行网络服务器的 uid 读取,但是,如果您可以尽可能限制此 uid 可写入的内容,那么您就可以关闭潜在的攻击媒介。

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

1) 文件扩展名 (.php) 对服务器意味着什么:

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

C.

【讨论】:

【参考方案5】:

设置php文件为640

为了最大安全性,您应该设置最低权限,即 是 640

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

永远不要让每个人都阅读 php 脚本。

有用的命令:

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

这些命令在做什么:

    更改 file.php 的所有权,以便用户可以读写、组读。 将 file.php 的所有权更改为选定的用户名和组名。 将 apache 添加到组中,以便 apache 可以为文件提供服务。否则 640 将不起作用。

【讨论】:

这是 PHP 脚本的最佳答案。对 PHP 脚本使用 640 的“首选”权限级别,除非有令人信服的理由不这样做。这个问题只回答了一半的问题,但却是那一半的最佳答案。我很想知道为什么人们会使用其他东西。 好点。解释很清楚。它说明了为什么最好不要允许超出安全目的所需的权限。【参考方案6】:

假设您的 SFTP/FTP 用户是 johndoe 并且 Web 服务器组是 www-datajohndoe 仅读取、写入文件但不执行文件(在我的情况下从不执行)。 Web 服务器软件通常来自www-data 组的 Apache/nginx 可以读取/写入/执行文件。其他用户?他们在这里做什么??? 所以,我曾经设置0670 (rw-rwx---) 并且总是为我工作:)

【讨论】:

以上是关于PHP 脚本/目录的权限是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Nginx/Apache下如何禁止指定目录运行PHP脚本

***和低级 PHP 脚本的含义是啥?

python脚本在Windows中运行的用户是啥? [复制]

以下PHP脚本的执行流程是啥? [复制]

通过表单按钮在 laravel 中触发 php 脚本的最佳方法是啥?

预加载 PHP 脚本时“未知类型依赖项”是啥意思?