【问题标题】:Writing files (by executing git commands) from PHP on CentOS7在 CentOS7 上从 PHP 写入文件(通过执行 git 命令)
【发布时间】:2017-01-13 09:20:38
【问题描述】:

我无法在我的 apache 网络服务器目录中写入文件。我正在使用 CentOS 7。我正在尝试使用 exec 从 PHP 文件执行 git 命令:

exec("/usr/local/bin/git -C ../myRepo fetch 2>&1", $output, $exec_return_value);

通过打印输出,我看到错误表现为:

error: cannot open .git/FETCH_HEAD: Permission denied

我发现(在此博客的帮助下:http://jondavidjohn.com/git-pull-from-a-php-script-not-so-simple/)这是“预期的”,因为 Apache 将使用与我通过 ssh 使用的用户不同的用户执行。所以我需要确保我的权限允许该用户具有写入权限。

我通过在我的 php 文件中打印它的输出来确定我的 Apache 安装以名为“apache”的用户身份执行:

exec("whoami", $debugOutput, $debugRetVal);

我还按照同一链接中的建议设置了 SSH。但不幸的是,我仍然在 PHP 文件中遇到同样的错误:

error: cannot open .git/FETCH_HEAD: Permission denied

真正让我震惊的是,当我使用 ssh 会话作为 apache 运行时,我没有任何权限问题:

sudo -u apache /usr/local/bin/git -C ../myRepo fetch

用户“apache”在从 PHP 执行时似乎具有不同的权限。有人可以帮我解决这个问题吗?

【问题讨论】:

  • 您正在使用相对路径 (`../)。您确定您的 PHP 命令与您尝试的命令行 sudo 在同一目录中运行吗?在运行 git 之前尝试使用绝对路径和/或显示 pwd 以查看是否是问题所在。
  • 当我根据完全相同的相对路径打印出“ls -la”时,我看到了所有文件,以及“apache”拥有这些文件的事实。所以它是从我期望的位置执行的。

标签: php apache centos exec selinux


【解决方案1】:

我看到用户“apache”在从 PHP 执行与从我的 SSH 执行时似乎具有不同权限的行为是 SELinux 的结果。当 SELinux 处于其“强制”模式(在 CentOS 7 中默认为该模式)时,它本质上是在标准 linux 用户权限之上“分层”了一个访问保护方案。简单来说,用户“apache”实际上在 httpd 进程外执行时确实拥有不同的权限。

为了更详细地了解 apache“服务”的 html 目录,其 SELinux 上下文类型为“httpd_sys_content_t”。所以我的 git repo 继承了相同的上下文。但是 SELinux 安全策略的工作方式是 httpd 只能读取上下文类型“httpd_sys_content_t”。为了让 httpd 对文件有写访问权限,我需要将上下文更改为“httpd_sys_rw_content_t”。我是这样做的:

sudo chcon -R -t httpd_sys_rw_content_t ../myRepo

这终于解决了我原来的错误!不幸的是,问题中的链接也提到了一个新错误:

array(5) { [0]=> string(68) "ssh: connect to host PRIVATEGITHOST: Permission denied" [1]=> string(45) "fatal: Could not read from remote repository." [2]=> string(0) "" [3]=> string(51) "Please make sure you have the correct access rights" [4]=> string(26) "and the repository exists." } 

但正如我在问题中提到的,我已经按照博客的建议为“apache”用户设置了一个 ssh 密钥。所以这实际上是一个不同的错误。再次源自 SELinux 的错误。

默认情况下,有一个名为“httdp_can_network_connect”的 SELinux 布尔值设置为关闭。这可以防止 httpd 建立自己的外部连接。如果您所做的只是为服务器上存在的内容提供服务,那么这就是您想要的。出于我的目的,我需要将该布尔值设置为 on using:

sudo setsebool httpd_can_network_connect on

在拔掉我的头发 2 天后。我可以从 php 文件中执行“git fetch”。

我使用“audit2allow”工具​​调试了带有布尔值的最终错误,该工具查看了一些 SELinux 日志并用或多或少简单的英语告诉您如何解决问题。

sudo audit2allow -a

OUTPUT:
#============= httpd_t ==============
#!!!! This avc can be allowed using one of the these booleans:
#     nis_enabled, httpd_can_network_connect
allow httpd_t unreserved_port_t:tcp_socket name_connect;

如果有人遇到与 apache/httpd 相关的 SELinux 问题,我强烈建议您查看该工具。

为了完整起见,我想指出,像上面所做的那样更改存储库的文件上下文是“临时更改”,不会在系统重置后持续存在。为了永久更改我使用的上下文类型:

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/myRepo(/.*)?"

同样,我用它来永久更改布尔值:

sudo setsebool -P httpd_can_network_connect on

【讨论】:

  • 我想知道这样的事情会带来什么安全隐患。以及,您将如何缓解它们?
  • 您在想知道安全隐患时具体指的是什么?允许 httpd 发起外部连接?
猜你喜欢
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2016-03-25
  • 2016-04-30
  • 1970-01-01
  • 2012-06-28
相关资源
最近更新 更多