Setting up HTTP client certificates

sslhappy-ca | dovecot-clientcert | thunderbird | apache-clientcert | firefox

tested with Apache 2.4

Your own CA

We are assuming you’ve created your own Certification Authority on e.g. dc1.example.local.

Submit certificate requests (CSRs) to that CA for:

Note. we truly need to enable HTTPS on the server itself, as it seems to be a requirement for the PKI client authentication to pass through.

Server-side setup

Send those to the server and workatation(s) e.g. for the server

scp /etc/ssl/ubuntu63.example.local.crt ubuntu63:/etc/ssl/
scp /etc/ssl/private/ubuntu63.example.local.key ubuntu63:/etc/ssl/private/

Enable HTTPS

a2enmod ssl
a2enmod headers
vi /etc/apache2/apache2.conf

<VirtualHost *:443>
        Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
        SSLEngine on
        SSLProtocol all -TLSv1 -SSLv2 -SSLv3
        SSLHonorCipherOrder off
        SSLCipherSuite "ECDHE:DHE:kGOST:!aNULL:!eNULL:!RC4:!MD5:!3DES:!AES128"
        SSLCertificateFile /etc/ssl/ubuntu63.example.local.crt
        SSLCertificateKeyFile /etc/ssl/private/ubuntu63.example.local.key
        #SSLCertificateChainFile /etc/httpd/ssl/issuer-concat-cert.crt

        ServerAdmin pbraun@nethence.com
        ServerName ubuntu63.example.local

        LogLevel warn

        DocumentRoot /var/www/html
</VirtualHost>

systemctl restart apache2

Note. the apache daemon now needs the passphrase for restarting, as it needs to unlock the private key for ubuntu63.example.local.

We can now reach the page normally and through TLS, as the client-side certificate verification is not enabled yet: http://ubuntu63.example.local/.

Now enabling client-side certificate check on the Apache service

on the CA host

scp /etc/ssl/cacert.pem ubuntu63:/etc/ssl/

on ubuntu63

vi /etc/apache2/apache2.conf #in the vhost

    SSLCACertificateFile /etc/ssl/cacert.pem
    <Location /protected>
      SSLOptions +StdEnvVars
      SSLVerifyClient require
    </Location>

systemctl restart apache2

As a result, when trying to load the /protected folder without any client specific certificate, the http client e.g. Firefox shows

Error code: SSL_ERROR_HANDSHAKE_FAILURE_ALERT

And the logs on the server shows

[Tue Mar 13 22:21:05.573195 2018] [ssl:error] [pid 17401:tid 139778410333952]
[client x.x.x.x:45252] AH02261: Re-negotiation handshake failed
[Tue Mar 13 22:21:05.573258 2018] [ssl:error] [pid 17401:tid 139778410333952]
SSL Library Error: error:140890C7:SSL routines:ssl3_get_client_certificate:
peer did not return a certificate -- No CAs known to server for verification?

Warning: one must take good care to disable the service on port 80. Enabling client certificate check on port 443 and keeping port 80 open would not serve any purpose in our goal. Instead of closing the port 80 on the firewalls and web daemon, I rather prefer to setup redirects. Therefore, users that do like to type urls manually into their browser will be able to reach the TLS-enabled service with no hassle nor pain.

Ready to go

Now proceed with a web client setup e.g. with Firefox.

Resources

Configuring Apache for SSL Client Certificate Authentication https://stuff-things.net/2015/09/28/configuring-apache-for-ssl-client-certificate-authentication/