DocumentRoot dinámico basado en SSL (autenticación de cliente)

Sep 12 2020

Actualmente utilizo la autenticación SSL de cliente para proteger el contenido confidencial. Los usuarios deben importar un certificado en sus navegadores que generamos con OpenSSL. Cuando un usuario visita el sitio web, lo redireccionamos a una página 403 personalizada si no tiene el certificado en su navegador o en el llavero del sistema operativo. Esto se logra utilizando la siguiente configuración de 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>

Me gustaría llevar esto un paso más allá e introducir algunos condicionales para cargar un DocumentRoot específico si tienen el certificado presente, u otro DocumentRoot si no tienen el certificado de cliente.

En resumen: website.com

  • El usuario A visita con el cliente SSL, sirve el sitio web.com desde / var / www / has_ssl
  • Visitas del usuario B sin SSL de cliente, sirva sitio web.com desde / var / www / no_ssl

Puedo usar %{SSL:SSL_CLIENT_S_DN_CN} =""para redirigir a una ruta si está vacía, pero no estoy seguro de cómo reescribir el DocumentRoot en función de la presencia del certificado.

He estado luchando con esto durante unos días. Se agradece cualquier ayuda o sugerencias.

Respuestas

2 MrWhite Sep 12 2020 at 06:17

AFAIK, no puede establecer condicionalmente el DocumentRoot. Sin embargo, podría reescribir internamente la solicitud usando mod_rewrite, de la misma manera que está devolviendo una respuesta 403 cuando el SSL del cliente no está configurado.

Por ejemplo, si configura:

DocumentRoot /var/www

Luego, reescriba internamente todas las solicitudes /var/www/has_sslen caso de éxito o /var/www/no_sslno.

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]

Para evitar el acceso directo a los subdirectorios /no_sslo /has_ssl, puede implementar una redirección externa antes de la reescritura anterior que elimine el subdirectorio de la solicitud. Por ejemplo:

RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^/(no_ssl|has_ssl)(.*) /$1 [R=301,L]