Ssl
基於 SSL 的動態 DocumentRoot (Client Auth.)
我目前使用客戶端 SSL 身份驗證來保護敏感內容。使用者需要將我們使用 OpenSSL 生成的證書導入他們的瀏覽器。當使用者訪問該網站時,如果他們的瀏覽器或作業系統的鑰匙串中沒有證書,我們會將他們重定向到自定義 403 頁面。這是使用以下 Apache 配置實現的。
<VirtualHost *:443> ServerName host.tld ServerAlias www.host.tld ServerAdmin servers@host.tld DocumentRoot /var/www/path ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCertificateFile /etc/ssl/host/host.crt SSLCertificateKeyFile /etc/ssl/host.key SSLCACertificateFile /etc/ssl/cacert.pem SSLVerifyClient optional SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire SSLVerifyDepth 10 # SSLCARevocationPath /etc/ssl/crl SSLCARevocationFile /etc/ssl/ca.crl SSLCARevocationCheck chain RewriteEngine on RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS RewriteRule .? - [F] ErrorDocument 403 /403.html </VirtualHost>
我想更進一步,並引入一些條件來載入特定的 DocumentRoot(如果他們有證書),或者另一個 DocumentRoot(如果他們沒有客戶端證書)。
總結:website.com
- 使用者 A 使用客戶端 SSL 訪問,從 /var/www/has_ssl 服務 website.com
- 使用者 B 在沒有客戶端 SSL 的情況下訪問,從 /var/www/no_ssl 提供 website.com
如果為空,我可以使用
%{SSL:SSL_CLIENT_S_DN_CN} =""
重定向到路徑,但我不確定如何根據證書的存在重寫 DocumentRoot。這幾天我一直在為此苦苦掙扎。任何幫助或指示表示讚賞。
AFAIK 你不能有條件地設置
DocumentRoot
. 但是,您可以使用 mod_rewrite 在內部重寫請求,這與未設置客戶端 SSL 時返回 403 響應的方式大致相同。例如,如果您設置:
DocumentRoot /var/www
然後在內部將所有請求重寫為
/var/www/has_ssl
成功或/var/www/no_ssl
其他。RewriteEngine on RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS RewriteRule ^ /no_ssl%{REQUEST_URI} [L] RewriteCond %{SSL:SSL_CLIENT_VERIFY} =SUCCESS RewriteRule ^ /has_ssl%{REQUEST_URI} [L]
為了防止直接訪問
/no_ssl
或子目錄,您可以在上述重寫之前/has_ssl
實現外部重定向,從請求中刪除子目錄。例如:RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^/(no_ssl|has_ssl)(.*) /$1 [R=301,L]