Apache:权限被拒绝:'/var/www/html/cgi-test/first.pl'的exec失败

所以,我是新来的CGI / Perl,我试图将一个基于Perl的Web应用程序移动到一个新的服务器。

我的新服务器是运行Apache HTTPD 2.4.6的CentOS 7。

我试图从一个HTTP请求获得一个基本的Perl CGI工作。

Web请求返回“500内部服务器错误”

错误日志显示“权限被拒绝”:

[Tue May 12 16:56:44.604660 2015] [cgi:error] [pid 12302] [client 10.0.2.2:56693] AH01215: (13)Permission denied: exec of '/var/www/html/cgi-test/first.pl' failed [Tue May 12 16:56:44.604708 2015] [cgi:error] [pid 12302] [client 10.0.2.2:56693] End of script output before headers: first.pl 

我的CGI脚本位于/var/www/html/cgi-test/first.pl

它看起来像这样:

 #!/usr/bin/perl print "Content-type: text/html\n\n"; print "Hello, World."; 

在cgi-test目录中,权限如下所示:

 drwxr-xr-x. 2 root root 21 May 12 16:48 . drwxr-xr-x. 4 root root 32 May 12 16:48 .. -r-xr-xr-x. 1 root root 76 May 12 16:48 first.pl 

Perl是在正常的地方,我认为正常的权限

 [root@localhost cgi-test]# ls -al /usr/bin/perl -rwxr-xr-x. 2 root root 11400 Mar 6 05:07 /usr/bin/perl 

我的httpd.conf是默认的。 我刚刚添加了以下部分,以便允许我的cgi-test目录中的cgi:

 <Directory "/var/www/html/cgi-test"> Options +ExecCGI AddHandler cgi-script .cgi .pl </Directory> 

为了消除suexec成为这个问题的原因,我把它从/ usr / sbin / suexec移到另一个文件名。

Httpd以“apache”组中的用户“apache”运行,

 [root@localhost cgi-test]# ps -Af | grep httpd root 12298 1 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 12299 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 12300 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 12301 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 12302 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 12303 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND root 12342 12260 0 17:20 pts/0 00:00:00 grep --color=auto httpd [root@localhost cgi-test]# groups apache apache : apache 

我试图运行脚本为Apache,它没有任何问题的作品。

 [root@localhost cgi-test]# su -s /bin/bash apache bash-4.2$ perl /var/www/html/cgi-test/first.pl Content-type: text/html Hello, World.bash-4.2$ 

据推测,我正在对Apa​​che进行一些安全预防。 关于这可能是什么有很多相互矛盾的build议。 任何帮助非常感谢。

答案是SELinux阻止访问脚本。

感谢alphamikevictor提出这个答案。

默认情况下,在CentOS 7上启用SELinux并阻止perl / CGI。 我确认它是使用/ usr / bin / sestatus启用的

在旧的服务器上,SELinux被完全禁用。

我从你自己的答案看到,这是一个SELinux的权限问题,因为试图在非标准目录中的Apache内运行CGI脚本。

在“执行”模式下维护SELinux并解决权限问题,从而提高服务器安全性的正确方法是将适当的上下文应用于自定义CGI脚本目录中的文件。 如果要成为永久目录,则应将selinux策略更改为使用适当的权限自动创build新文件。

您可以使用以下命令检查cgi-bin目录的selinux策略:

 $ semanage fcontext --list | grep cgi-bin (...) /var/www/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0 /var/www/html/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0 (...) 

这意味着在apache的标准cgi-bin目录下创build的每个文件都将自动被赋予SELinuxtypeshttpd_sys_script_exec_t并且可以被httpd执行,所以这就是你的cgi-test目录下的文件应该包含的内容。

注意:下面的例子是基于CentOS / RHEL6的,对于RHEL7来说,它应该和最终的调整一样。

临时解决scheme

你可以简单的改变你的perl脚本的SELinux上下文:

 $ chcon -t httpd_sys_script_exec_t /var/www/html/cgi-test/first.pl 

ls -laZ检查文件的SELinux属性:

 $ ls -laZ /var/www/html/cgi-test/first.pl -rwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 /var/www/html/cgi-test/first.pl 

但是,如果在这个文件系统上有SELinux relabel操作,属性将被恢复为默认值,并且它将会再次停止工作。 每次添加一个新的CGI脚本时,它也必须被完成。

确定的解决scheme

您可以通过为自定义CGI目录和所有包含的子目录和文件添加规则来更改SELinux策略。

这是通过semanage命令完成的(在policycoreutils-python RPM包中可用):

 $ semanage fcontext -a -t httpd_sys_script_exec_t "/var/www/html/cgi-test(/.*)?" 

这将需要一段时间才能运行。 更改策略后,在自定义目录中创build的任何新文件都将具有新的上下文。 对于已经存在的那些,您可以手动应用策略:

 $ restorecon -R -v /var/www/html/cgi-test 

你可以检查你新增的规则:

 $ semanage fcontext --list | grep cgi-test 

确保你已经在下面的apacheconfiguration中添加了ScriptAlias

 ScriptAlias /cgi-test/ /var/www/html/cgi-test/ 

另外尝试添加到Options指令的FollowSymLinks。