DocumentRoot dynamique basé sur SSL (authentification du client)

Sep 12 2020

J'utilise actuellement l'authentification SSL du client pour protéger le contenu sensible. Les utilisateurs doivent importer un certificat dans leur navigateur que nous avons généré à l'aide d'OpenSSL. Lorsqu'un utilisateur visite le site Web, nous le redirigeons vers une page 403 personnalisée s'il n'a pas le certificat dans son navigateur ou dans le trousseau de son système d'exploitation. Ceci est réalisé en utilisant la configuration Apache suivante.

<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>

Je voudrais aller plus loin et introduire des conditions pour charger un DocumentRoot spécifique s'ils ont le certificat présent, ou un autre DocumentRoot s'ils n'ont pas le certificat client.

En résumé: website.com

  • L'utilisateur A visite avec le client SSL, sert website.com à partir de / var / www / has_ssl
  • L'utilisateur B visite sans SSL client, sert website.com à partir de / var / www / no_ssl

Je peux utiliser %{SSL:SSL_CLIENT_S_DN_CN} =""pour rediriger vers un chemin s'il est vide, mais je ne sais pas comment réécrire le DocumentRoot en fonction de la présence du certificat.

J'ai du mal avec ça depuis quelques jours. Toute aide ou pointeurs est apprécié.

Réponses

2 MrWhite Sep 12 2020 at 06:17

AFAIK, vous ne pouvez pas définir de manière conditionnelle le DocumentRoot. Cependant, vous pouvez réécrire en interne la requête en utilisant mod_rewrite, de la même manière que vous renvoyez une réponse 403 lorsque le SSL client n'est pas défini.

Par exemple, si vous définissez:

DocumentRoot /var/www

Réécrivez ensuite en interne toutes les demandes en cas /var/www/has_sslde succès ou /var/www/no_sslautrement.

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]

Pour empêcher l'accès direct aux sous /no_ssl- /has_sslrépertoires ou, vous pouvez implémenter une redirection externe avant les réécritures ci-dessus qui suppriment le sous-répertoire de la demande. Par example:

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