Table of Contents

SSL

Authentication Users Password

Presentation

LL::NG uses Apache SSL module, like any other Apache authentication module, with extra features:

Configuration

With Apache

Enable SSL in Apache

You have to install mod_ssl for Apache.

For CentOS/RHEL:

yum install mod_ssl
In Debian/Ubuntu mod_ssl is already shipped in apache*-common package.
For CentOS/RHEL, We advice to disable the default SSL virtual host configured in /etc/httpd/conf.d/ssl.conf.

Apache SSL global configuration

You can then use this default SSL configuration, for example in the head of /etc/lemonldap-ng/portal-apache2.conf:

SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM
SSLCertificateFile /etc/httpd/certs/ow2.cert
SSLCertificateKeyFile /etc/httpd/certs/ow2.key
SSLCACertificateFile /etc/httpd/certs/ow2-ca.cert
Put your own files instead of ow2.cert, ow2.key, ow2-ca.cert:
  • SSLCertificateFile: Server certificate
  • SSLCertificateKeyFile: Server private key
  • SSLCACertificateFile: CA certificate to validate client certificates

If you specify port in virtual host, then declare SSL port:

NameVirtualHost *:80
NameVirtualHost *:443

Apache portal SSL configuration

Edit the portal virtual host to enable SSL double authentication:

SSLEngine On
SSLVerifyClient optional
SSLVerifyDepth 10
SSLOptions +StdEnvVars
SSLUserName SSL_CLIENT_S_DN_CN

All SSL options are documented in Apache mod_ssl page.

Here are the main options used by LL::NG:

With Nginx

Enable SSL:

ssl on;
ssl_verify_client optional;
ssl_certificate /etc/letsencrypt/live/my/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my/privkey.pem;
ssl_verify_depth 3;
ssl_client_certificate /etc/nginx/ssl/ca.pem;
ssl_crl /etc/nginx/ssl/crl/my.crl;

You must also export SSL_CLIENT_S_DN_CN in FastCGI params:

map $ssl_client_s_dn  $ssl_client_s_dn_cn {
           default           "";
           ~/CN=(?<CN>[^/]+) $CN;
      }
fastcgi_param  SSL_CLIENT_S_DN_CN $ssl_client_s_dn_cn;

Configuration of LemonLDAP::NG

In Manager, go in General Parameters > Authentication modules and choose SSL for authentication.

You can then choose any other module for users and password.

Then, go in SSL parameters:

Auto reloading SSL Certificates

A known problematic is that many browser (Firefox, Chrome) remembers the fact that the certificate is not available at a certain time. It is particularly important for smart cards: when the card is not inserted before the browser starts, the user must restart his browser, or at least refresh (F5) the page.

It is possible with AJAX code and 3 Apache locations to bypass this limitation.

1. Modify the portal virtual host to match this example:

    SSLEngine On
    SSLCACertificateFile /etc/apache2/ssl/ca.crt
    SSLCertificateKeyFile /etc/apache2/ssl/lemonldap.key
    SSLCertificateFile /etc/apache2/ssl/lemonldap.crt
 
    SSLVerifyDepth 10
    SSLOptions +StdEnvVars
    SSLUserName SSL_CLIENT_S_DN_CN
 
    # DocumentRoot
    DocumentRoot /var/lib/lemonldap-ng/portal/
    <Directory /var/lib/lemonldap-ng/portal/>
        Order Deny,Allow
        Allow from all
        Options +ExecCGI +FollowSymLinks
        SSLVerifyClient none
    </Directory>
 
    <Location /index>
        Order Deny,Allow
        Allow from all
        SSLVerifyClient none
    </Location>
 
    <Location /testssl>
        Order Deny,Allow
        Allow from all
        SSLVerifyClient require
    </Location>
 
    Alias /sslok /var/lib/lemonldap-ng/portal
    <Location /sslok>
        Order Deny,Allow
        Allow from all
        SSLVerifyClient require
    </Location>

2. Then you need to construct the Ajax page, for example in /index/bouton.html. It looks like this:

<body>
<script src="./jquery-2.1.4.min.js"             type="text/javascript"> </script>
<!--<script src="./jquery-ui-1.8-rass.js"   type="text/javascript">  </script>-->
 
 
<a href="http://www.google.fr" class="enteteBouton" id="continuerButton"><img src=authent.png></a>
<script>
$('.enteteBouton').click( function (e) {
  var b=navigator.userAgent.toLowerCase();
  if(b.indexOf("msie")!==-1){
    document.execCommand("ClearAuthenticationCache")
  }
  e.preventDefault();
  $.ajax({
        url:"https://auth.example.com/testssl",
        beforeSend:function(){},
        type:"GET",
        dataType:"html",
        success:function(c,a){ 
          if (c !== "") {
                alert("Carte OK");
                window.location.href = "https://auth.example.com/sslok/";
          }
          else {
              alert('Carte KO');
          }
        },
        error:function (xhr, ajaxOptions, thrownError){
          if(xhr.status==404) {
                alert("Carte OK");
                window.location.href = "https://auth.example.com/sslok/";
          }
          else {
              alert('Carte KO');
          }
        },
        complete:function(c,a){}
  });
});
</script>
</body>
It is incompatible with authentication chaining (see Stack Multiple backends), because of Apache parameter "SSLVerifyClient", which must have the value "require"