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

ogg*_*ron 8 perl cgi apache-2.4

所以,我是 CGI/Perl 的新手,我正在尝试将基于 perl 的 Web 应用程序移动到新服务器。

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

我正在尝试通过 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
Run Code Online (Sandbox Code Playgroud)

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

它看起来像这样:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

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

[root@localhost cgi-test]# ls -al /usr/bin/perl
-rwxr-xr-x. 2 root root 11400 Mar  6 05:07 /usr/bin/perl
Run Code Online (Sandbox Code Playgroud)

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

<Directory "/var/www/html/cgi-test">
    Options +ExecCGI
    AddHandler cgi-script .cgi .pl
</Directory>
Run Code Online (Sandbox Code Playgroud)

为了消除 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
Run Code Online (Sandbox Code Playgroud)

我尝试将脚本作为 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$
Run Code Online (Sandbox Code Playgroud)

据推测,我正在采取 Apache 的一些安全预防措施。关于这可能是什么,有很多相互矛盾的建议。非常感谢任何帮助。

And*_*des 5

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

解决权限问题同时保持 SELinux 处于“强制”模式,从而提高服务器安全性的正确方法是将适当的上下文应用到自定义 CGI 脚本目录中的文件。如果它是一个永久目录,您应该更改 selinux 策略以自动创建具有适当权限的新文件。

您可以使用以下命令检查 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
 (...)
Run Code Online (Sandbox Code Playgroud)

这意味着在 apache 的标准 cgi-bin 目录中创建的每个文件都将被自动赋予 SELinux 类型httpd_sys_script_exec_t并且可由 httpd 执行,因此这也是目录中的cgi-test文件应该具有的内容。

注意:下面显示的示例基于 CentOS/RHEL6,它应该在 RHEL7 上工作,最终调整。

临时解决方案

您可以简单地更改您的 perl 脚本的 SELinux 上下文:

$ chcon -t httpd_sys_script_exec_t /var/www/html/cgi-test/first.pl
Run Code Online (Sandbox Code Playgroud)

使用以下命令检查文件的 SELinux 属性ls -laZ

$ 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
Run Code Online (Sandbox Code Playgroud)

但是,如果在此文件系统上进行 SELinux 重新标记操作,则属性将恢复为默认值,并且将再次停止工作。每次添加新的 CGI 脚本时也必须这样做。

确定的解决方案

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

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

$ semanage fcontext -a -t httpd_sys_script_exec_t "/var/www/html/cgi-test(/.*)?"
Run Code Online (Sandbox Code Playgroud)

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

$ restorecon -R -v /var/www/html/cgi-test
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式检查新添加的规则:

$ semanage fcontext --list | grep cgi-test
Run Code Online (Sandbox Code Playgroud)


ser*_*com -2

确保您已在 apache 配置中添加了 ScriptAlias,如下所示

ScriptAlias /cgi-test/ /var/www/html/cgi-test/
Run Code Online (Sandbox Code Playgroud)

还可以尝试将 FollowSymLinks 添加到 Options 指令中。

  • 这些都没有必要。我不需要 ScriptAlias,因为我告诉 Apache 某个目录中已经有脚本了。FollowSymLinks 不是必需的,因为这里不涉及符号链接。 (2认同)