Web Server Management: Securing Access to Web Servers | ||
---|---|---|
Prev | Chapter 4. Configuring Apache to support TLS | Next |
An optional feature of TLS is that the client can supply a certificate to the server and demonstrate its possession of the corresponding private key. This can be used for strong authentication of the user without having to transmit passwords to the server.
To obtain a client certificate, a special web form on a CA's web site causes a browser to generate a key pair and to transmit the public half in a CSR to the CA. The private half is stored in the web browser, protected by a pass phrase. In due course the CA returns the certificate which is also stored in the browser. When a server requests client authentication as part of an TLS session negotiation the browser retrieves the certificate and accesses the private key by requesting the pass phrase from the user. The browser can demonstrate that it has access to the private half of the key corresponding to the certificate by using it to encrypt random data supplied by the server. The server has access to all the information from the certificate and can make access control decisions based on that information.
Assuming we have access to a source of client certificates, we can include support for them by adding the following:
CustomLog /var/logs/apache2/www-ssl.log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b \"%{SSL_CLIENT_S_DN_CN}x\"" SSLCACertificateFile /etc/apache2/ssl.crt/personalCA.crt SSLVerifyClient require
The new custom log line allows us record the "Common Name" part of the "Subject" name in the client certificate. We also need to copy the CA's certificate into place so that Apache can use it to validate the personal certificate it is offered by the browser:
# cp personalCA.crt /etc/apache2/ssl.crt/
Having done this, we can apply access control in a number of ways.
It may be sufficient to restrict access, as we are doing at the moment, to people with personal certificates issued by this particular CA.
Alternatively the SSLRequire
directive can be used inside a directory block to apply
restrictions based on a number of parameters, including all
the fields from both the client and server
certificates.
<Directory /srv/www/WWW/protected> SSLRequireSSL SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \ and %{SSL_CLIENT_S_DN_O} eq "University of Cambridge" \ and %{SSL_CLIENT_S_DN_OU} in {"Computing Service", "MISD"} \ and %{SSL_CLIENT_I_DN_O} eq "**TEST Jon's Test CA company" ) </Directory>
A further alternative is to add
SSLUserName SSL_CLIENT_S_DN_CN
which will cause Apache to treat the "Common
Name" field from the user's certificate as if it had
been entered in a normal HTTP authentication dialogue. As a
result you can use standard Apache directives such as
Require
to control access on a person by
person basis. This option was new in Apache 2.0 - in mod_ssl
for Apache 1.3 the more limited 'SSLOptions +FakeBasicAuth'
can be used to similar effect.
Finally, adding
SSLOptions +StdEnvVars
will make environment variables containing details of the client and server certificates, TLS protocol in use, etc., available to CGI or other dynamic programs that handle requests.
In a real PKI, the CA would make available lists of
certificates that have been compromised or lost. The
SSLCARevocationfile
directive lets you supply
such a list to Apache so that it knows not to recognise such
certificates.