繁体   English   中英

用户目录中的 Apache CGI“标题前的脚本输出结束”

[英]Apache CGI in user directory "End of script output before headers"

我知道关于这个话题有一些问题,但似乎没有一个能解决我的问题。 看到这个这个这个

我在 Linux、Fedora21 上,我正在尝试启用每个用户目录的 CGI 脚本。 我遵循了这些说明,但没有成功。

我收到错误:

[cgi:error] End of script output before headers: test.cgi

test.cgi是一个可执行的 sh 文件,包含一个非常简单的脚本:

#!/usr/bin/sh

echo "Content-type: text/plain"
echo ""
echo "Hello"

它具有可执行标志并且从 shell 运行没有问题。 我也尝试过使用 Python:结果相同。

我也很好地禁用了 selinux。

我还尝试将debug级别设置为 Apache 的 ErrorLog,但我得到的只是在上述错误之前“授予”权限。

我还配置了/etc/httpd/conf.d/userdir.conf文件

<Directory "/home/*/public_html">
    AllowOverride All
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require all granted
</Directory>

<Directory /home/*/public_html/cgi-bin/>
    Options ExecCGI FollowSymLinks
    SetHandler cgi-script
    AddHandler cgi-script .cgi .exe .pl .py .vbs
    Require all granted
    AllowOverride All
</Directory>

并重新启动了服务器。 没有成功。 对我来说一切都很好,我无法理解......怎么了??

编辑:

我忘了补充一点,这个问题只是针对每个用户的目录:如果我将相同的脚本移动到/var/www/cgi-bin目录,它会按预期工作。

编辑2:

外壳确实存在:

$ ls /usr/bin/sh
/usr/bin/sh

最后我解决了这个问题 感谢@JimB,因为在他的评论中他指出了我不知道的SUEXEC(或者直到现在才被忽略)。

在阅读了suEXEC文档后 ,我明白问题必须存在。 所以,我看了一下配置:

# suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=1000
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=1000
 -D AP_USERDIR_SUFFIX="public_html"

一切看起来都很好(我的用户好uid / gid,userdir_suffix很好,等等)。 所以我看了一下系统日志:

# journalctl -b | grep "suexec"
May 22 11:43:12 caladan suexec[5397]: uid: (1000/user) gid: (1000/user) cmd: test.cgi
May 22 11:43:12 caladan suexec[5397]: directory is writable by others: (/home/user/public_html/cgi-bin)

这就是问题:我的cgi-bin目录是其他人可写的

我通过简单地将权限更改为755来修复。

对我来说,当我将shebang线( #!/usr/bin/sh )更改为#!/usr/bin/env sh 我发现任何shebang线从什么是首选Bash shebang? 似乎工作(但请注意shbash不同,所以如果你想使用sh stick)。

所以这段代码对我有用:

#!/usr/bin/env sh
echo "Content-type: text/plain"
echo ""
echo "Hello"

另外,根据上面提到的帖子,似乎/usr/bin/env sh似乎优于/bin/sh 我不知道每个目录的东西。

当您尝试从cgi调用其他Python模块方法时,有时会出现这种情况,您可能会留下一些“print”语句(可能用于调试)。 因此,扫描您的代码以查找任何“print”语句,有时这可以轻松解决问题。

对于从命令行运行良好的Python 2.x CGI脚本,我看到了消息“标题:myscript.py之前的脚本输出结束”。

问题原来是Web服务器没有正确执行,即使它来自命令行。 无论系统返回给服务器的错误消息是什么,它肯定没有传递给CGI标题(例如,“Content-Type:text / html \\ r \\ n \\ r \\ n”)。 因此,这个失败的消息。

对我来说,纠正它意味着改变shebang

#!/usr/bin/env python

更具体系统性(但可验证):

#!/usr/local/bin/python

也许你遇到了类似的事情。

(FreeBSD 9.x.)

只允许文件所有者对cgi脚本具有写权限,而不是该 ,即-rwxr-xr-x而不是-rwxrwxr-x

在用户目录中,该组通常是一个个人用户组,只有用户才是其中的成员,但似乎Apache对于查看g + w位感到紧张,但却给出了一个有点虚假的错误消息。

尝试以apache用户身份运行脚本。

这可能会发生很多原因。 @JimB提到了shebang的问题。 @premganz提到在编写Content-Type字符串之前触发的调试print语句的问题。 在我的情况下,它是数据库连接失败。 这可能是任何其他问题。

我发现调试它的最佳方法是直接在命令行上以apache用户身份运行脚本,并查看它给出的错误。

如何以Apache用户身份运行脚本

假设您正在运行apache2,并且apache用户是www-data,并且您的cgi脚本是/myapp/myreport.py - 您可以执行以下操作。

  1. 允许以www-data用户身份登录,方法是更改​​其默认shell。 编辑/ etc / passwd(暂时)

     sudo su - cd /etc cp -p passwd passwd.2017-10-22 emacs passwd # edit file - use your favorite editor 

    更改:

     www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin 

    至:

     www-data:x:33:33:www-data:/var/www:/bin/bash 
  2. 以www-data用户身份登录

     sudo su - www-data 
  3. 设置任何环境变量。 将您的apache SetEnv语句转换为导出语句。 就我而言,我的apache配置目录设置已设置这些变量

     SetEnv PYTHONPATH /myapp/lib SetEnv VCONF /myapp/conf/prod.yaml 

    运行它们

     export PYTHONPATH=/myapp/lib export VCONF=/myapp/conf/prod.yaml 
  4. 然后尝试你的cgi脚本

     cd /myapp ./myreport.py 
  5. 你应该看到Apache正在经历的任何错误。 固定他们。

  6. 将www-data用户的默认shell设置回/ usr / sbin / nologin

当我们以旧方式使用打印时会发生此错误。

print 'your test'

它应该是更高版本的Python。

print ('your test')

我在userdir中执行python cgi时遇到问题。

/ var / log / httpd / error_log显示:

[Fri Apr 26 13:09:41.840285 2019] [cgi:error] [pid 25421] [client 98.234.206.134:60837]标题前的脚本输出结束:index.cgi

在URL中调用的用户是doug,用户42,组42

我隐约记得suexec在1000以下的团体或用户执行cgi脚本时遇到问题。

所以我创建了一个名为user1k的新组作为1000.然后我做了

adduser -g 1000 -u 1000 dwg
chmod 755 /home/dwg
mkdir /home/dwg/public_html

我把我的python cgi脚本放到这个目录中。

现在组和用户> = 1000,脚本开始正确执行。 我不确定是用户还是修复问题的组,但改变它们两者肯定解决了它。

注意:问题是用户ID低于1000。 因此,使userdir cgi执行者的userID> 999。

这是man suexec输出的摘录。

目标用户ID是否超过最小ID号? 配置期间指定最小用户ID号。 这允许您设置允许执行CGI / SSI程序的最低可能用户ID。 这对于阻止“系统”帐户很有用。

目标groupid是否超过最小ID号? 配置期间指定最小组ID号。 这允许您设置允许执行CGI / SSI程序的最低可能groupid。 这对于阻止“系统”组很有用。

我遇到过同样的问题。 需要这个:

sudo setsebool -P httpd_read_user_content 1

我是通过查看日志 (journalctl -b ) 发现的,它告诉我......

SELinux 阻止 /usr/bin/python2.7 对目录 public_html 进行搜索访问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM