我无法在我的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安装通过在我的php文件中打印输出来作为名为"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执行时看似具有不同的权限.有人可以帮我解决这个问题吗?
我看到的用户"apache"似乎在从PHP执行到执行SSH时具有不同权限的行为是SELinux的结果.当SELinux处于"强制"模式(默认情况下在CentOS 7中)时,它基本上在标准linux用户权限之上"分层"访问保护方案.从简单的意义上说,用户"apache"实际上在执行httpd进程时确实具有不同的权限.
要获得更详细的apache"serve"的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布尔值设置为off.这可以防止httpd进行自己的外部连接.如果您所做的只是提供服务器上存在的内容,那么您想要的是什么.为了我的目的,我需要将该布尔值设置为on使用:
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