Tag Archive: tls


Standard TLS sessions have a big issue: they are vulnerable to the « wiretap then crack » attack scheme: any intercepted communication can be stored and deciphered when you’ll have/find/factorize the server private key. Network traffic analysers often provide an option to perform such an operation for debug/protocol validation purposes. « Perfect » forward secrecy has been designed to fight against this issue: when two peers want to establish a TLS tunnel with PFS, after performing the server (or the mutual) authentication, they agree on an ephemeral session key.

TLS perfect forward secrecy can be supported in all recent browsers with Apache 2.3+. Version 2.4 has recently been migrated to Debian Jessie. The configuration you will find below has been made with the Qualys SSL Server Test. This test suite is quite useful to review the configuration of your TLS server: it checks the validity of your certificates, the strength of the cipher suite your server offers and gives you information on how common browsers will behave on your website.

Though the grade I get is not perfect, the configuration that I posted below seems to be, at this i’m writing this post, both the most interoperable and the most robust configuration you can create with Apache.

Replace (or add if applicable) the following configuration directives in your SSL module configuration file (most likely to be found in /etc/apache2/mods-enabled/ssl.conf).

SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1
SSLCompression off
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:AES256-GCM-SHA384:AES256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA

then restart your apache server.

Please refer to the configuration at the bottom of this post


UPDATE: Qualys has updated its browser test suite, integrating Opera 12.15 and Firefox 21 on fedora 19, which are both known for not supporting TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xC011).

Fedora community is well known for building FIPS 140-2 compliant cryptographic modules, and FIPS 140-2 happens not to support TLS_ECDHE_RSA_WITH_RC4_128_SHA.

This federal standard is known to only whitelist some cipher suites. In fact FIPS 140-2 doesn’t allow the use of « next » generation algorhithms (such as ECDHE for ephemeral key exchange, or as Galois/Counter Mode for block ciphers) despite the fact they bring significant improvements in terms of bandwidth and computing overhead.

Considering nowadays cryptographic ecosystem, this standard is to be considered as obsolete, except if you plan to sell any cryptographic product to the US goverment.

Ignoring that fact, today’s main security issue is caused by Apple Safari that still has not mitigated the BEAST vulnerability using the (1/n-1) split record trick.

So here is quite embarassing tradeoff you have to deal with: 1. Let your apple clients be vulnerable to BEAST while supporting PFS for any other browser by recommending CBC modes block ciphers and refusing use of RC4 (this will enhance the security for every browser except Safari), 2. Protect everyone against BEAST by using a crippled stream cipher and support PFS with a best-effort policy.

Bonus reminder: even if 3DES-EDE cipher suites use a 168 bit key, real key strength is 112 bits because of its vulnerability to the meet-in-the-middle attack. You may advertise for legacy support purposes, but if you do so, put these suites at the bottom of your server cipherlist, but do not add export or ADH suites are they are respectively weak and vulnerable.


UPDATE 2: After some browser behaviour analysis, I have achieved to get full PFS support for modern browsers, as shown on the pictures below. To do so, you need to properly enable some Diffie-Hellman ciphers. Doing so doesn’t trip the BEAST vulnerability flag and enables PFS for FIPS-compliant browsers that were not supported. The « Key exchange » subgrade in the Qualys SSL Server Test will decrease because DH parameters length are not great, even if they give a sufficient level of security for now.

This grade deterioration is an apache-specific issue: Apache developpers currently assumes that (EC)DH parameter choice is to be build-specific. According to me, this is not an acceptable solution as it makes long term support more difficult. You should consider bumping (voting for) this bugtracker feature request to get a more flexible way to control DH/ECDH parameters in the future.

Replace (or add if applicable) the following configuration directives in your SSL module configuration file (most likely to be found in /etc/apache2/mods-enabled/ssl.conf).

SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1
SSLCompression off
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RC4-SHA:AES256-GCM-SHA384:AES256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA

then restart your apache server.

Here is the grade I’ve got with the last configuration:

Below, you can see which cipher suites are selected by your clients.

Expert tip: The (1/n-1) split record trick is implemented in Firefox since a while. Thus, you can safely disable RC4 on Firefox in the advanced configuration menu. To do so, enter ‘about:config’ in your address bar, then search for ‘rc4’ and toggle all the found values to ‘false’. If you experience connections issues, toggle back those parameters to true.


An updated version of these cipher suites has been posted in the post 2015, an overview of TLS

Publicité

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.