Tag Archive: authentification


Au cours de mes différentes expérimentations, j’ai voulu renforcer l’authentification de certains de mes services en m’appuyant sur une infrastructure à clés publiques dont je disposais déjà. Étant donné que la configuration du VirtualHost sur Apache n’a pas forcément été simple à mettre en place, je vous propose par la suite un template de Virtualhost que j’ai conçu. Les aspects relatifs à la gestion d’une PKI ou de la génération de certificats ne sera pas traitée dans ce billet.

Prérequis

La présente configuration suppose que vous disposiez au préalable:

  • d’un serveur Apache fonctionnel avec un virtualhost qui vous permettra de accueillir les utilisateurs dont l’authentification a échoué
  • des modules apache suivants (liste non exhaustive): mod_ssl, mod_rewrite, mod_headers
  • de certificats SSL serveurs et clients valides.

Gestion des erreurs

Un des problèmes principaux de l’authentification SSL repose sur le fait que le client se retrouve sur une page d’erreur du navigateur et non sur une page d’erreur de votre site web. La configuration suivante vous permettra de rediriger le client vers une autre page lui proposant éventuellement d’autres modes d’authentification (forte de préférence). La redirection mise en place est de type HTTP/307 et est complètement standard.

Pour notre exemple, je vous fournis une mire d’échec très simpliste en PHP qui permettra au client de relancer la procédure d’authentification vers le bon site une fois les problèmes corrigés de son côté. Pour la suite de ce billet, on supposera cette page accessible via l’URL suivante: https://login.yourdomain.com/sslfail.php

<html>
    <head>
        <title>FAIL</title>
    </head>
    <body>
        <p>SSL authentication failed. <?php
            if(isset($_GET["from"]))
            {
                echo("<a href=\"https://". $_GET["from"] .".yourdomain.com/\">Try Again.</a>");
            }
        ?></p>
    </body>
</html>

Le fichier VirtualHost

Pour la suite, on va considérer que le service à protéger sera accessible aux clients sur secureservice.yourdomain.com.

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName secureservice.yourdomain.com
        DocumentRoot /var/secureservice-wwws

        # Configuration SSL côté serveur
        SSLEngine on
        SSLCertificateFile    /path/to/ca/certs/secureservice.pem
        SSLCertificateKeyFile /path/to/ca/private/secureservice.key
        SSLCertificateChainFile /path/to/ca/keystore/ca.crt

        # Configuration SSL côté client
        SSLCACertificateFile /path/to/ca/certs/ca.pem
        SSLCARevocationFile /path/to/ca/crl/ca-crl.crl
        SSLVerifyDepth  10

        <IfModule mod_rewrite.c>
            # If mod_rewrite is available, redirect clients on failure
            SSLVerifyClient optional

            <IfModule mod_headers.c>
                Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
                Header set Pragma "no-cache"
                Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
            </IfModule>
            RewriteEngine On
            RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
            RewriteRule .* https://login.yourdomain.com/sslfail.php?from=secureservice [r=307]
        </IfModule>
        <IfModule !mod_rewrite.c>
            # If mod_rewrite is not available, just deny clients on failure
            SSLVerifyClient require
        </IfModule>

        BrowserMatch "MSIE [2-6]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
        # MSIE 7 and newer should be able to use keepalive
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    </VirtualHost>
</IfModule>

Concernant les attributs côté client, je tiens à vous préciser quelque points: en plus de la configuration classique du certificat serveur, 3 lignes sont impératives pour mettre en place l’authentification SSL:

  • La ligne qui dit au serveur où chercher les certificats des CA qui ont signé les certificats client (SSLCACertificateFile). Le chemin doit impérativement pointer sur un fichier encodé au format PEM. Si vous avez plusieurs CA à prendre en compte, concaténez vos différents fichiers PEM et faites pointer cette ligne sur le fichier résultant.
  • La ligne qui indique combien de niveaux de validation sont supportés pour les certificats clients (SSLVerifyDepth).  Si la valeur associée vaut zéro, le certificat client doit être auto-signé. Si la valeur vaut 1, le certificat doit être validé par le certificat d’une autorité présente dans le fichier des autorité client. Si la valeur vaut 2 ou plus, le certificat peut avoir été signé par une autorité intermédiaire valide. Avec 2, le client peut avoir été signé par une CA signée par une CA présente dans le fichier des autorités.
  • La ligne qui va spécifier le comportement à tenir en cas d’échec. Lorsque SSLVerifyClient est positionné sur require, la négociation SSL/TLS sera annulée si le certificat de l’utilisateur n’est pas validé par le serveur. Le client sera informé par son navigateur que l’opération a échoué. Si par contre SSLVerifyClient est positionné sur optional, et que le certificat de l’utilisateur n’est toujours pas valide, la connexion s’établit quand même, mais il sera, dans notre cas, redirigé vers la page d’échec (http://login.tourdomain.com/sslfail.php?from=secureservice) par le biais d’une réponse HTTP/307. À ce sujet, il est très important d’ajouter le module headers à apache, car les navigateurs ont tendance à mettre en cache les redirections. Si une redirection est mise en cache, votre client pourrait croire que son authentification échoue en permanence, ce qui n’est pas souhaitable.

La spécification d’une liste de révocation de certificats n’est pas toujours nécessaire, mais il reste préférable de l’utiliser car elle vous permettra d’assurer une gestion des droits d’accès plus propre. La ligne avec SSLCARevocationFile doit pointer sur un fichier qui contient la concaténation de toutes les listes de révocation des autorités client encodées au format PEM.

Publicité

Introduction

Le pré-requis pour ce tutoriel est une connaissance basique d’Apache 2, et des virtualhosts.

J’ai récemment fait l’acquisition d’une caméra de surveillance IP, et je voulais pouvoir y accéder depuis l’extérieur sans que l’on ne puisse m’observer.

Mon réseau domestique est structuré en plusieurs VLAN. 3 de ces VLANs nous intéresseront pour la suite de cet article:

  • Le VLAN Interconnexion Internet:  zone où mon modem et mon firewall sont connectés.
  • Le VLAN DMZ: tous mes équipements devant être accessibles depuis l’Internet y sont connectés.
  • Le VLAN Serveurs internes: tous les équipements dont j’ai besoin, mais qui ne doivent pas être directement accessibles depuis l’Internet.

Ci-dessous, l’extrait de la politique de sécurité qui nous intéresse (valable autant en IPv4 qu’en IPv6).

  • Internet peut initier des connexions TCP et envoyer des paquets UDP dans la DMZ et vice-versa.
  • Internet ne peut pas joindre directement les serveurs internes. L’usage d’un reverse proxy dans la DMZ est obligatoire.
  • Le reverse proxy est l’unique machine de la DMZ autorisée à accéder aux serveurs internes.
  • Les connexions SSH du reverse proxy sont bloquées depuis internet et la DMZ.

Dans cette configuration, pour sécuriser correctement la webcam, j’ai installé cette dernière dans mon VLAN des serveurs internes, et j’ai configuré le reverse-proxy pour qu’il effectue une authentification.

Configuration d’Apache 2 en reverse-proxy

Tout d’abord, j’ai choisi d’utiliser l’authentification HTTP-Digest, qui est simple à mettre en place depuis apache, et qui est un tantinet plus sûre que l’authentification basique, où le mot de passe transite en clair sur le réseau.

Pour concrétiser l’exemple, la racine Web de la webcam est accessible en faisant http://192.168.3.8/ depuis le reverse-proxy. La webcam sera accessible depuis http://services.example.com/webcam/ depuis l’Internet (les noms ont été changés pour protéger les innocents).

Vous devez activer les modules apache suivant pour réussir votre configuration:

  • mod_auth_digest
  • mod_proxy
  • mod_proxy_http
  • mod_proxy_connect
  • mod_proxy_ftp

LoadModule ou a2enmod sont vos amis ;-þ

Séance gratte papier fichiers

Ensuite, il va falloir générer le fichier avec les mots de passes pour l’authentification HTTP Digest (souvent .htdigest). Pour cela, effectuez la commande suivante:

htdigest -c /chemin/vers/htdigest webcam toto

Le mot de passe de ‘toto‘ vous sera demandé interactivement.

L’argument ‘webcam‘ correspond à ce qu’on appelle un realm ou plus communément Domaine de connexion. Avec l’authentification HTTP-Digest, vous pouvez gérer un utilisateur sur plusieurs domaines (avec des mots de passes naturellement différents).

Une fois le fichier htdigest généré, posé au bon endroit, en veillant que www-data puisse y accéder en lecture, on s’attaque à la configuration des sites.

Rendez-vous dans /etc/apache2/sites-enabled et ajoutez les lignes suivantes, par précaution, si vous n’utilisez pas de forward proxy sur la machine:

ProxyRequests Off

Order deny,allow
        Allow from all

Ces lignes vont interdire l’utilisation des fonctions forward-proxy sur la machine, qui sont testées régulièrement par des petits malins qui s’amusent à scanner votre IPv4 ou votre subnet IPv6.

Dans le fichier contenant le(s) virtualhost(s) correspondant à services.example.com, ajoutez les lignes suivantes dans le bloc virtualhost adéquat:

    <Location /webcam/>
        AuthType Digest
        AuthName "webcam"
        AuthDigestDomain /webcam
        AuthUserFile /chemin/vers/htdigest
        Require valid-user
        ProxyPass http://192.168.3.8/
        ProxyPassReverse http://192.168.3.8/
    </Location>

La chaîne après le mot-clé AuthName doit être impérativement celle du Realm que vous avez choisi lors de la génération du fichier htdigest.

Stress du passage en production

Rechargez votre démon apache. Normalement, à cette étape, lorsque vous tapez http://services.example.com/webcam/ (ne pas oublier le ‘/’ à la fin), un prompt d’authentification devrait s’afficher. Après avoir entré les identifiants valides, vous devriez pouvoir accéder à l’interface de votre webcam.