我們希望限制那些擁有有效 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
根據目前的阿帕奇文檔這可能是一個問題:
在每個伺服器上下文中,它適用於建立連線時標準 SSL 握手中使用的客戶端身份驗證過程。在每個目錄上下文中,它會在讀取 HTTP 請求之後、發送 HTTP 回應之前強制使用重新配置的客戶端驗證等級進行 SSL 重新協商。
使用 <Directory> 上下文而不是 <Location> 怎麼樣?一個條目用於根級別,另一個條目用於腳本別名路徑:/path/to/gitolite-shell/
更新:
我找到了一些對此案的建議 ->Stackoverflow 上的問題/解答