Ssl

基於 SSL 的動態 DocumentRoot (Client Auth.)

  • September 11, 2020

我目前使用客戶端 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]

引用自:https://serverfault.com/questions/1033551