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

时间:2015-02-01 17:44:39

标签: linux apache cgi

我知道有关于这个主题的一些问题,但似乎没有一个问题可以解决我的问题。请参阅thisthisthis

我在Linux上,Fedora21,我正在尝试启用每个用户目录的CGI脚本。我按照these的说明进行了操作,但没有成功。

我收到错误:

[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:

shell确实存在:

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

8 个答案:

答案 0 :(得分:7)

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

在读完suEXEC documentation后,我明白问题必须在那里。所以,我看了一下配置:

# 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

答案 1 :(得分:3)

对我来说,当我将shebang行(#!/usr/bin/sh)更改为#!/usr/bin/env sh时,它起了作用。我发现来自What is the preferred Bash shebang?的所有shebang行似乎都有用(但请注意shbash不同,所以如果你想使用sh坚持使用它。

所以这段代码对我有用:

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

问题原来是Web服务器没有正确执行,即使它来自命令行。无论系统返回给服务器的任何错误消息,它肯定都没有通过CGI标题(例如,&#34; Content-Type:text / html \ r \ n \ r \ n&#34;)。因此,这个失败的消息。

对我而言,纠正它意味着更改shebang

#!/usr/bin/env python

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

#!/usr/local/bin/python

也许你会遇到类似的东西。

(FreeBSD 9.x。)

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

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

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

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

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

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

  1. 通过更改其默认shell,允许以www-data用户身份登录。编辑/ 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

答案 6 :(得分:0)

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

print 'your test'

它应该适用于Python的更高版本。

print ('your test')

答案 7 :(得分:0)

我在执行用户目录中的python cgi时遇到问题。

/ var / log / httpd / error_log显示:

  

[2019年4月26日星期五13:09:41.840285] [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,脚本开始正确执行。 我不确定是解决问题的是用户还是小组,但同时更改它们都可以解决。

注意:问题在于用户号小于1000。 因此,使userdir cgi executee的userID为> 999。

这是man suexec输出的摘录。

  

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

     

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