如何在 Apache 2.4 上运行需要 PATH_INFO 的 CGI 脚本目录?

如何在 Apache 2.4 上运行需要 PATH_INFO 的 CGI 脚本目录?

使用 Apache 2.2,我在 VirtualHost 中运行 Mailman 的 CGI Web 界面,它具有:

    <Directory "/usr/lib/cgi-bin/mailman/">
               AssignUserId www-data www-data
               AllowOverride None
               Options ExecCGI
               AddHandler cgi-script .cgi
               Order allow,deny
               Allow from all

    </Directory>
    <Directory "/var/lib/mailman/archives/public/">
               AssignUserId www-data www-data
               Options FollowSymlinks
               AllowOverride None
               Order allow,deny
               Allow from all
    </Directory>
    <Directory "/usr/share/images/mailman/">
               AssignUserId www-data www-data
               AllowOverride None
               Order allow,deny
               Allow from all
    </Directory>

    ScriptAlias "/mailman/"  "/usr/lib/cgi-bin/mailman/"

这很有效。最近,也许是在 Jessie 中更新了 Apache 2.4(2.4.10-10+deb8u7)之后,我发现无法从 Apache 获取任何内容。经过一番思考和调试 mailman(1:2.1.18-2+deb8u1)之后,我发现有效的方法是用一堆 ScriptAliasMatch 语句替换 ScriptAlias,并修改 Mailman 以使用请求 URI而不是路径信息自从路径信息未定义。也许那是因为我是 ScriptAliasMatch,但如果 ScriptAliasMatch 吞掉尾随路径组件,这似乎会限制它的实用性。

具体来说,我破解了该网站,使其能够以相当不雅的方式工作:

    <Directory "/usr/lib/cgi-bin/mailman/">
               AssignUserId www-data www-data
               AllowOverride None
               Options ExecCGI
               AddHandler cgi-script .cgi
               Order allow,deny
               Allow from all

    </Directory>
    <Directory "/var/lib/mailman/archives/public/">
               AssignUserId www-data www-data
               Options FollowSymlinks
               AllowOverride None
               Order allow,deny
               Allow from all
    </Directory>
    <Directory "/usr/share/images/mailman/">
               AssignUserId www-data www-data
               AllowOverride None
               Order allow,deny
               Allow from all
    </Directory>

    Alias "/mailman/images/" "/usr/share/images/mailman/"
    #       ScriptAlias "/mailman/"  "/usr/lib/cgi-bin/mailman/"
    ScriptAliasMatch "/mailman/admin/(.*)"  "/usr/lib/cgi-bin/mailman/admin"
    ScriptAliasMatch "/mailman/admindb/(.*)"  "/usr/lib/cgi-bin/mailman/admindb"
    ScriptAliasMatch "/mailman/confirm/(.*)"  "/usr/lib/cgi-bin/mailman/confirm"
    ScriptAliasMatch "/mailman/create/(.*)"  "/usr/lib/cgi-bin/mailman/create"
    ScriptAliasMatch "/mailman/edithtml/(.*)"  "/usr/lib/cgi-bin/mailman/edithtml"
    ScriptAliasMatch "/mailman/listinfo/(.*)"  "/usr/lib/cgi-bin/mailman/listinfo"
    ScriptAliasMatch "/mailman/options/(.*)"  "/usr/lib/cgi-bin/mailman/options"
    ScriptAliasMatch "/mailman/private/(.*)"  "/usr/lib/cgi-bin/mailman/private"
    ScriptAliasMatch "/mailman/rmlist/(.*)"  "/usr/lib/cgi-bin/mailman/rmlist"
    ScriptAliasMatch "/mailman/roster/(.*)"  "/usr/lib/cgi-bin/mailman/roster"
    ScriptAliasMatch "/mailman/subscribe/(.*)"  "/usr/lib/cgi-bin/mailman/subscribe"

然后我修补了 Mailman 的使用 PATH_INFO 回退到 REQUEST_URI 的函数:

def GetPathPieces(envar='PATH_INFO'):
    path = os.environ.get(envar)
    if path is None:
        path = '/'.join(os.environ.get('REQUEST_URI').split('/')[3:]).split('?')[0]
    if path:
        if CRNLpat.search(path):
            path = CRNLpat.split(path)[0]
            syslog('error', 'Warning: Possible malformed path attack.')
        return [p for p in path.split('/') if p]
    return None

我已经阅读了有关 ScriptAlias 和 mod_cgi 的文档,并尝试通过添加到我的 VirtualHost 来确保:

    AcceptPathInfo on

这没有帮助。我还查看了此服务器的大量 Apache 配置,但没有找到任何相关内容。

同样看似不相关但很接近的是 VirtualHost 的 DocumentRoot 中的 wordpress .htaccess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

我的问题是:我如何在 Apache 2.4 上运行未修改的 Debian Jessie Mailman 副本。或者,我遇到了 Apache 中的错误?Mailman 的行为似乎合理。

答案1

对于我使用的 Perl CGI 脚本,以下配置适用于 SLES12 中的 Apache 2.4.51,但它AH01630在运行时会触发一些错误(“服务器配置拒绝客户端”):

...
<VirtualHost FQHN:443>
    DocumentRoot "/srv/www/HN"
    ...
    ScriptAlias /alias /srv/www/cgi-bin/CGI.pl
    <Location /alias>
        SetHandler perl-script
        PerlResponsehandler ModPerl::Registry
        ...
    </Location>
...
</VirtualHost>

也许这对 Python 也有帮助。

相关内容