【发布时间】:2017-03-25 23:17:46
【问题描述】:
在将网站从运行 Apache 2.2 的旧网络服务器迁移到运行 Apache 2.4 的新网络服务器时,我遇到了一个奇怪的 CGI 问题。基本上没有 CGI 脚本在新的网络服务器上工作。他们返回 500 个错误。但是在 ScriptLog 中没有“%error”部分并且“%response”是空的。脚本似乎正在运行,但绝对没有返回任何内容!由于没有任何内容意味着没有标题,因此结果是 500 错误。
mod_cgi 模块已加载(通过运行“apachectl -M”确认)。我们使用的是 prefork MPM,所以这是正确的模块。
大多数 CGI 脚本都是 Perl,但我们也有一个用 C 编译的脚本,它显示完全相同的行为模式。即使是这样的基本测试脚本也不起作用:
#!/usr/bin/perl
print STDOUT "Content-type: text/html\n\n";
print STDOUT "Hello, World.";
我临时为“apache”用户分配了一个 shell,切换到该用户,并且能够运行其中的几个脚本。以这种方式运行时,并非所有产品都会产生有意义的输出,但它们确实会运行。是的,/usr/bin/perl 确实存在,是系统上唯一的 Perl 副本,并且安装了 perl-CGI。
所有这些脚本都在一个 NFS 共享上,供新旧网络服务器使用。旧的网络服务器仍然可以毫无问题地将这些脚本作为 CGI 提供。因此,如果尚不清楚这里的问题不在于 CGI 脚本本身。这是新网络服务器的配置问题。
NFS 共享安装在 /mnt/cgi/ 中,每个用户都有子目录。我们的 Apache 配置文件中包含的部分如下所示:
Alias /cgi-bin/usera /mnt/cgi/usera
<Directory /mnt/cgi/usera>
Options +ExecCGI
AddHandler cgi-script .cgi .pl
Require all granted
</Directory>
可以通过http://server.example.com/cgi-bin/usera/first.pl 访问此目录中的脚本。当我连接到此页面时,它会附加到 ServerLog 中指定的日志文件(使用正确的 IP 地址...我 xxx-ed 出来):
%% [Fri Nov 11 12:00:00 2016] GET /cgi-bin/usera/first.pl HTTP/1.1
%% 500 /mnt/cgi/usera/first.pl
%request
Host: xxx.xxx.xxx.xxx
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Via: 1.1 xxx.xxx.xxx.xxx:80
X-Forwarded-For: xxx.xxx.xxx.xxx
X-Forwarded-For-Port: 51380
%response
这些脚本的权限都是 755,所以这不是问题。如果我从脚本目录的 Directory 定义中删除 AddHandler 行,那么我可以下载脚本,因此 Apache 肯定能够访问它们。
新服务器是 RHEL7。 SELinux 处于 Permissive 模式,而不是 Enforcing。无论如何,布尔值 httpd_enable_cgi 和 httpd_use_nfs 都是“开启”的。
我尝试过但无济于事的事情包括:
- 设置“ScriptAlias /cgi-bin/usera /mnt/cgi/usera”,而不仅仅是“Alias”。
- 设置“ScriptAlias /cgi-bin/ /mnt/cgi”。一般来说,我们无论如何都不想使用 ScriptAlias,因为其中一些目录中还有文本数据文件。
- 使脚本成为所有者:组 apache:apache。
- 将“AllowOverride None”添加到目录块。
- 添加“使用 CGI::Carp 'fatalsToBrowser';”到一个脚本。这不返回任何内容。同样,我认为脚本运行良好,但 Apache 没有以某种方式接收到输出。
我还应该补充一点,一般来说,新的网络服务器工作正常。基于 PHP 的 webapp 在它们上运行得很好,当然静态内容也没有问题。
所以这是很多细节,但最终问题是这样的:Apache 怎么会执行 CGI 脚本但根本没有从它们那里得到任何输出?有什么想法吗?
【问题讨论】: