[英]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
目录,它会按预期工作。
外壳确实存在:
$ 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? 似乎工作(但请注意sh
与bash
不同,所以如果你想使用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 - 您可以执行以下操作。
允许以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
以www-data用户身份登录
sudo su - www-data
设置任何环境变量。 将您的apache SetEnv语句转换为导出语句。 就我而言,我的apache配置目录设置已设置这些变量
SetEnv PYTHONPATH /myapp/lib SetEnv VCONF /myapp/conf/prod.yaml
运行它们
export PYTHONPATH=/myapp/lib export VCONF=/myapp/conf/prod.yaml
然后尝试你的cgi脚本
cd /myapp ./myreport.py
你应该看到Apache正在经历的任何错误。 固定他们。
将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.