WSGI 在我的 Ubuntu 服务器上显示“权限被拒绝”,WSGISocketPrefix 设置不起作用

WSGI 在我的 Ubuntu 服务器上显示“权限被拒绝”,WSGISocketPrefix 设置不起作用

我正在尝试在 Ubuntu 10.04.3 LTS(lucid)上运行带有 mod_wsgi 支持守护进程的 Apache2。

问题是,我无法找到 WSGISocketPrefix 指令的有效配置。我的设置是:

<VirtualHost *:80>
    ...

    WSGIDaemonProcess myapp threads=5
    WSGIScriptAlias / /var/www/myapp/myapp.wsgi
    <Directory /var/www/myapp>
        WSGIProcessGroup myapp
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

Apache 以 root 身份运行。我正在使用 Flask Python 框架,因此我遵循了本教程:http://flask.pocoo.org/docs/deploying/mod_wsgi/#configuring-apache。没有任何其他设置,我得到了503服务暂时不可用HTTP 错误。在 Apache 错误日志中我收到以下消息:

[Mon Oct 17 15:24:24 2011] [error] [client 90.181.85.69] (13)Permission denied: mod_wsgi (pid=21805): Unable to connect to WSGI daemon process 'kvinono' on '/var/run/apache2/wsgi.16282.4.1.sock' after multiple attempts.

然后我发现了这个:https://code.google.com/p/modwsgi/wiki/ConfigurationIssues#Location_Of_UNIX_Sockets,所以我尝试设置WSGISocket前缀设置为我想到的任何值,并始终尝试重新启动/重新加载 Apache 并查看它是否有效。从来没有奏效,总是权限错误,只是在不同的位置。我尝试将用户/组设置为 WSGI 进程:

WSGIDaemonProcess myapp user=www-data group=www-data threads=5

...同时在 /var/run/wsgi 等文件夹上设置正确的权限,但这没有帮助。无法以 root/root 身份运行 WSGI 守护进程,Apache 不允许我这样做。实际上,WSGI 能够写入,并且当所有权限设置正确时,它确实将套接字文件写入文件夹,但这并没有解决错误。即使使用现有的套接字文件,它也会产生完全相同的结果没有权限错误。经过多次尝试和组合后,我尝试将 WSGISocketPrefix 设置为 /tmp。WSGI 再次能够创建套接字文件,但仍然因上述错误而“崩溃”。

我现在完全绝望了 :-( 如果您建议我围着火跳舞并唱一些萨满咒语,我愿意这样做,只要它有助于解决问题。

答案1

您正在使用 ITK MPM for Apache。您需要使用 mod_wsgi 3.3 或更高版本,其中包含修复:

当针对 ITK MPM for Apache 进行编译时,如果使用守护进程模式,守护进程的侦听器套接字将被标记为由守护进程运行的同一用户拥有。这至少允许在 ITK MPM 下处理的请求定向到与脚本相同的用户拥有的守护进程。请参阅问题:

http://code.google.com/p/modwsgi/issues/detail?id=187

但是您不能只使用操作系统提供的二进制文件,因为可用的二进制文件可能只适用于 worker 和 prefork MPM。对于 ITK MPM,您需要从源代码编译 mod_wsgi,并且必须安装适用于 ITK MPM 的头文件,而不是适用于 worker 或 prefork MPM 的头文件。这是因为 mod_wsgi 源代码具有:

    if (!geteuid()) {
#if defined(MPM_ITK)
        if (chown(process->socket, process->uid, -1) < 0) {
#else
        if (chown(process->socket, ap_unixd_config.user_id, -1) < 0) {
#endif
            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
                         "mod_wsgi (pid=%d): Couldn't change owner of unix "
                         "domain socket '%s'.", getpid(),
                         process->socket);
            return -1;
        }
    }

换句话说,这是一个编译时选择,至于如何设置权限,只有当 ITK MPM 标头安装正确且找到 MPM_ITK #define 时,才能为 ITK MPM 正确设置权限。

总而言之,您需要执行以下操作:

(1)确保安装了 ITK MPM 头文件。如果使用 Apache 的二进制包,请查看 Apache dev 包是否有 ITK 变体。

(2)从可公开下载的 mod_wsgi 3.3 源码包中获取源代码,编译并安装 mod_wsgi

mod_wsgi 源代码包和安装说明可从以下位置获取:

http://www.modwsgi.org

答案2

Graham Dumpleton 的答案可能有效,我还没有尝试过。我正在使用 mod_wsgi 3.2,遇到了同样的问题。

问题似乎是 WSGISocketPrefix 从 /etc/httpd(或 /etc/apache2)开始,并使用简单的连接。因此,当您将以下内容添加到配置中时

WSGISocketPrefix /var/run/wsgi

它最终尝试将文件放入 /etc/httpd//var/run/wsgi。由于某种原因,它没有记录此错误。

解决方法?我是这样操作的

WSGISocketPrefix ../../var/run/wsgi

我通过使用“var/run/wsgi”(不带前导/)作为前缀发现了这一点,并在日志中看到:

[Thu Feb 14 14:50:28 2013] [alert] (2)No such file or directory: mod_wsgi (pid=18702): Couldn't bind unix domain socket '/etc/httpd/var/run/wsgi.18702.0.1.sock'.

希望最新版本能修复这个问题,但至少我们可以坚持使用我们的 OS 分布式包。

答案3

尝试这个:

<VirtualHost *:80>
    ...

    WSGIDaemonProcess myapp threads=5
    WSGIScriptAlias / /var/www/myapp/myapp.wsgi/
    <Directory /var/www/myapp/>
        WSGIProcessGroup myapp
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

因此,您尝试在最后的 wsgi 路径和目录中添加“/”字符。

相关内容