Dynamiczne DocumentRoot oparte na SSL (uwierzytelnianie klienta)
Obecnie używam uwierzytelniania SSL klienta do ochrony poufnych treści. Użytkownicy muszą zaimportować do swoich przeglądarek certyfikat, który wygenerowaliśmy przy użyciu OpenSSL. Gdy użytkownik odwiedza witrynę, przekierowujemy go na niestandardową stronę 403, jeśli nie ma certyfikatu w swojej przeglądarce lub pęku kluczy systemu operacyjnego. Osiąga się to za pomocą następującej konfiguracji 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>
Chciałbym pójść o krok dalej i wprowadzić pewne warunki, aby załadować określony DocumentRoot, jeśli mają obecny certyfikat, lub inny DocumentRoot, jeśli nie mają certyfikatu klienta.
Podsumowując: website.com
- Odwiedziny użytkownika A z klientem SSL, obsługuj witrynę website.com z / var / www / has_ssl
- Odwiedziny użytkownika B bez klienta SSL, obsługuj witrynę internetową.com z / var / www / no_ssl
Mogę użyć %{SSL:SSL_CLIENT_S_DN_CN} =""do przekierowania do ścieżki, jeśli jest pusta, ale nie jestem pewien, jak przepisać DocumentRoot na podstawie obecności certyfikatu.
Walczę z tym od kilku dni. Każda pomoc lub wskazówki są mile widziane.
Odpowiedzi
AFAIK, nie możesz warunkowo ustawić pliku DocumentRoot. Możesz jednak wewnętrznie przepisać żądanie za pomocą mod_rewrite, w podobny sposób, w jaki zwracasz odpowiedź 403, gdy klient SSL nie jest ustawiony.
Na przykład, jeśli ustawisz:
DocumentRoot /var/www
Następnie wewnętrznie przepisz wszystkie żądania /var/www/has_sslna sukces lub w /var/www/no_sslinny sposób.
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]
Aby zapobiec bezpośredniemu dostępowi do podkatalogów /no_ssllub /has_ssl, można zaimplementować przekierowanie zewnętrzne przed powyższym przepisaniem, które usuwa podkatalog z żądania. Na przykład:
RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^/(no_ssl|has_ssl)(.*) /$1 [R=301,L]