ScriptAlias 使请求匹配过多的 Location 块。发生了什么?

ScriptAlias 使请求匹配过多的 Location 块。发生了什么?

我们希望将开发服务器的访问权限限制为拥有有效 SSL 客户端证书的用户。我们在 Debian 6 上运行 Apache 2.2.16。

然而,对于某些部分(主要是 git-http,使用 gitolite 进行设置https://my.server/git/)我们需要一个例外,因为许多 git 客户端不支持 SSL 客户端证书。

我已成功要求服务器进行客户端证书身份验证,并为某些位置添加例外。然而,这似乎对 git 不起作用。

当前设置如下:

SSLCACertificateFile ssl-certs/client-ca-certs.crt
<Location />
  SSLVerifyClient require
  SSLVerifyDepth 2
</Location>
# this works
<Location /foo>
  SSLVerifyClient none
</Location>
# this does not
<Location /git>
  SSLVerifyClient none
</Location>

我也尝试了另一种解决方案,结果相同:

# require authentication everywhere except /git and /foo
<LocationMatch "^/(?!git|foo)">
  SSLVerifyClient require
  SSLVerifyDepth 2
</LocationMatch>

在这两种情况下,没有客户端证书的用户可以完美访问 my.server/foo/,但不能访问 my.server/git/(访问被拒绝,因为没有提供有效的客户端证书)。如果我完全禁用 SSL 客户端证书身份验证,my.server/git/ 就可以正常工作。

ScriptAlias 问题

Gitolite 是使用 ScriptAlias 指令设置的。我发现任何类似的 ScriptAlias 都会出现此问题:

# Gitolite
ScriptAlias /git/ /path/to/gitolite-shell/
ScriptAlias /gitmob/ /path/to/gitolite-shell/
# My test
ScriptAlias /test/ /path/to/test/script/

请注意,/path/to/test/script 是一个文件,而不是目录,/path/to/gitolite-shell/ 也是如此。

我的测试脚本只是打印出环境,非常简单:

#!/usr/bin/perl

print "Content-type:text/plain\n\n";
print "TEST\n";
@keys = sort(keys %ENV);
foreach (@keys) {
    print "$_ => $ENV{$_}\n";
}

似乎如果我去https://my.server/test/someLocation,所有与 /test/someLocation 匹配的 Location 块中的 SSLVerifyClient 指令均被应用或者只是/someLocation

如果我有以下配置:

<LocationMatch "^/f">
        SSLVerifyClient require
        SSLVerifyDepth 2
</LocationMatch>

然后,以下 URL 需要客户端证书:https://my.server/test/foo。但是,以下 URL 却没有:https://my.server/test/somethingElse/foo

请注意,这似乎仅适用于 SSL 配置。以下内容对https://my.server/test/foo

<LocationMatch "^/f">
        Order allow,deny
        Deny from all
</LocationMatch>

然而,它确实阻止访问https://my.server/foo

这对于我同时运行一些项目的情况来说是一个很大的问题https://my.server/project(需要 SSL 客户端证书授权)该项目的 git 存储库位于https://my.server/git/project无法要求 SSL 客户端证书。由于 /git/project URL 也与 /projectLocation块匹配,因此根据我目前的发现,这种配置似乎是不可能的。

问题:为什么会发生这种情况?我该如何解决我的问题?

最后,我希望要求除 /git 和 /someLocation 之外的整个服务器进行 SSL 客户端证书授权,并尽可能减少配置(这样我就不必在每次部署新内容或添加新的 git 存储库时修改配置)。

更新更多信息:请注意,在某些情况下,https://my.server/project实际上是反向代理,因此<Directory /path/to/project>无法执行指令。如果我想使用 SSL 客户端证书保护该应用程序,则必须使用<Location /project>(或更通用的<Location />)块。

更新 2我刚刚在 apache 2.4.3 中测试了这个问题,结果是一样的。如果这是由于某个错误造成的,那么至少有两个版本都存在这个问题。


注意:我重写了我的问题(而不是仅仅在底部添加更多更新)以考虑到我的新发现并希望使这一点更加清楚。

答案1

根据目前Apache 文档这可能是一个问题:

在每个服务器上下文中,它适用于建立连接时标准 SSL 握手中使用的客户端身份验证过程。在每个目录上下文中,它会在读取 HTTP 请求之后但在发送 HTTP 响应之前强制使用重新配置的客户端验证级别进行 SSL 重新协商。

那么使用 <Directory> 上下文而不是 <Location> 怎么样?一个条目用于根级别,另一个用于 Script-Alias 路径:/path/to/gitolite-shell/

更新:

我找到了一些针对此案例的建议 ->Stackoverflow 上的问答

相关内容