apache and ssl
overview
In this document I will attempt to describe briefly how an end user or server administrator can configure their systems to allow for authentication to any user who posses a signed certificate.
To keep things simple the following assumptions will be made:
certificate security
Whilst you may rightly or wrongly assume that you're the only user of your system you should always ensure that you protect your SSL key. You may be the only person logged into your system, but if a rogue process has the ability to read your keys and then the game is lost.
Mozilla Firefox allows you to set a master password, which encrypts user key data, quite handy and mitigates some problems.
basic apache setup
First, lets take a look at the bit which should be familiar to us all,
SSLEngine on
SSLCertificateKeyFile /root/ssl/site.key
SSLCertificateFile /root/ssl/site.crt
SSLCertificateChainFile /root/ssl/issuer.crt
This is quite straight forward to all who have seen before, it's the boilerplate "we'd like to encrypt the data on network please" directives. We won't introduce any changes here.
I place the following section in a file, which is then Included for the appropriate directory/location blocks:
SSLCACertificateFile /root/ssl/ca.pem
SSLRequireSSL
SSLVerifyDepth 3
SSLVerifyClient require
SSLUserName SSL_CLIENT_S_DN_Email
SSLOptions +StdEnvVars
By doing it this way, for any location on the server that I choose it is
possible to restrict access to those who have a certificate which is
signed by the given SSLCACertificateFile
CA file. This is controlled
by the SSLRequireSSL
directive.
If you have a directory where you wish to have SSL authentication as an
optional requirement you can set the SSLVerifyClient
to optional.
SSLUserName
sets the remote user name to the client certificate email address.
Setting SSLOptions
to +StdEnvVars
enables copious amounts of environment available to CGI applications.
user restriction
To restrict the access even further, so not just signed by the declared
pem, but has to be signed by that pem AND contain given requirements,
such as an email address, we can use SSLRequire
which takes logic operators, such as:
SSLRequire ( %{SSL_CLIENT_S_DN_Email} eq "user@s5h.net" )
cacti authentication
This is the simplest part, all we have to do here is to go to the console, select "User Management", select a user, go to the "copy" operation then click go. Enter the username which matches the remote user.
Modify the new user and set "Authentication Realm" to "Web Basic".
Now we must enable basic authentication, to do this go to "Settings", then the "Authentication" tab. Now select "Web basic authentication".
This should now use your certificate for login authentication. You will not be able to log out whilst the certificate is installed in your browser.
If you are new to certificates then you can have a quick go using ca-cert, who can issue you a certificate with relative ease.
certificate authorization errors with a helpful error
Sometimes it is desirable (almost all the time) to have error messages that are displayed when a user cannot access a resource without getting the standard (and somewhat unhelpful) SSL protocol error page.
To do this we need to set the SSL CA and verification parameters, expose the environment variables and use mod_rewrite to do the clever redirecting.
One helpful benefit of this is that you can setup a directory or location on the web server and then filter some parts of that directory for hard requirements, such as a DBA team who can view a server list (servers.txt), and a network team who can view the DNS list (dns.txt). The 'faq.html' file will be considered public, so no special requirements are needed in order to view it.
<Location /lists>
SSLRenegBufferSize 1073741824
SSLCACertificateFile /usr/local/etc/corp.cer
SSLVerifyClient optional
SSLVerifyDepth 10
SSLOptions +StdEnvVars +ExportCertData
Options FollowSymLinks Indexes MultiViews
RewriteEngine on
#
# pass bits through here that are to be served without any SSL verification
RewriteCond %{REQUEST_URI} ^/lists/faq.html$
RewriteRule ^ - [L]
#
# we consider a valid cert to be one that is signed by corp.cer ca
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
RewriteRule ^ /help_no_valid_cert.html [R=302,L]
#
# pass bits through here that are to be served with a valid corp CA
# signed cert
RewriteCond %{SSL:SSL_CLIENT_S_DN_CN} ^.*(dba1|dba2|dba3)
RewriteCond %{REQUEST_URI} ^/lists/servers.txt$
RewriteRule ^ - [L]
#
RewriteCond %{REQUEST_URI} ^/lists/servers.txt$
RewriteRule ^ /help_invalid_cn.html [L]
#
RewriteCond %{SSL:SSL_CLIENT_S_DN_CN} ^.*(tcp1|tcp2|tcp3)
RewriteCond %{REQUEST_URI} ^/lists/dns.txt$
RewriteRule ^ - [L]
#
RewriteCond %{REQUEST_URI} ^/lists/dns.txt$
RewriteRule ^ /help_invalid_cn.html [L]
#
# if you want to reject access to everything else
# RewriteRule ^ /help_no_valid_cert_cn.html [R=302,L]
# everything else must have a valid CN
</Location>