Dynamic DocumentRoot на основе SSL (аутентификация клиента)
В настоящее время я использую клиентскую SSL-аутентификацию для защиты конфиденциального контента. Пользователи должны импортировать в свои браузеры сертификат, который мы создали с помощью OpenSSL. Когда пользователь посещает веб-сайт, мы перенаправляем его на настраиваемую страницу 403, если у него нет сертификата в браузере или связке ключей операционной системы. Это достигается с помощью следующей конфигурации Apache.
<VirtualHost *:443>
ServerName host.tld
ServerAlias www.host.tld
ServerAdmin [email protected]
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, обслуживает website.com из / var / www / has_ssl
- Пользователь B посещает без клиентского SSL, обслуживает website.com из / var / www / no_ssl
I can use %{SSL:SSL_CLIENT_S_DN_CN} ="" to redirect to a path if empty, but I'm not sure how to rewrite the DocumentRoot based on the presence of the certificate.
I've been struggling with this for a few days. Any assistance or pointers is appreciated.
Ответы
AFAIK you can't conditionally set the DocumentRoot. However, you could internally rewrite the request using mod_rewrite, in much the same way you are returning a 403 response when the client SSL is not set.
For example, if you set:
DocumentRoot /var/www
Then internally rewrite all requests to /var/www/has_ssl on success or /var/www/no_ssl otherwise.
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]
To prevent direct access to either the /no_ssl or /has_ssl subdirectories you could implement an external redirect before the above rewrites that removes the subdirectory from the request. For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^/(no_ssl|has_ssl)(.*) /$1 [R=301,L]