В настоящее время я использую 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
Я могу использовать % {SSL: SSL_CLIENT_S_DN_CN} = ""
для перенаправления на путь, если он пуст, но я не уверен, как переписать DocumentRoot на основе наличие сертификата.
Бился с этим несколько дней. Любая помощь или указатели приветствуются.
Насколько я знаю, вы не можете условно установить DocumentRoot
. Однако вы можете внутренне переписать запрос, используя mod_rewrite, почти так же, как вы возвращаете ответ 403, когда клиентский SSL не установлен.
Например, если вы установите:
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]