在CentOS7

时间:2017-01-12 02:35:10

标签: php apache centos exec selinux

我无法在我的apache webserver目录中写入文件。我使用的是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使用的其他用户执行。所以我需要确保我的权限允许该用户具有写访问权。

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

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执行时看似有不同的权限。有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:5)

我看到的用户" apache"从PHP执行到执行SSH时,似乎有不同的权限,这是SELinux的结果。当SELinux正在执行"执行"模式(默认情况下在CentOS 7中)它基本上是"层"基于标准linux用户权限的访问保护方案。在简单的意义上,用户" apache"实际上,当它执行httpd进程时,确实有不同的权限。

要获得更详细的apache"服务的html目录"具有SELinux上下文类型" httpd_sys_content_t"。所以我的git repo继承了相同的上下文。但SELinux安全策略的工作方式是httpd只对上下文类型具有读访问权限#http; 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。

默认情况下,有一个SELinux布尔值,名为" httdp_can_network_connect"这是设置为关闭。这可以防止httpd进行自己的外部连接。如果你所做的只是服务于服务器上存在的内容,那么你想要的是什么。出于我的目的,我需要使用:

将该布尔值设置为on
sudo setsebool httpd_can_network_connect on

经过2天的拔毛。我可以fianlly做一个" git fetch"来自一个PHP文件。

我使用" 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