UniServer CA2: Client Certificates
UniServer CA2: Introduction | Client Certificates | Revocation | Batch File Details
|
|
Uniform Server 5.5-Nano CA Demo |
Portable CA - Client Certificates
The real power of running your own CA is the ability to sign certificates in particular personal (client) certificates this page covers client authentication to grant access to areas of your server.
Using certificates is more secure than using standard password solutions and offers more flexibility. Certificates are validated against a chain of CA's that have signed the certificates. Apache requires at least one CA to validate against the previous page explained how to create and where to install this certificate.
Apache needs configuring in order to use personal certificate authentication.
Enable Apache for CA operation
Uniform Server has been pre-configured for CA operation however a default installation has this function disabled. Before running the servers enable the appropriate sections as follows:
Edit ssl.conf
Apache needs to know where to find the CA certificate and certificate chain. This has been pre-configured in file ssl.conf it just requires enabling.
Edit file UniServer\usr\local\apache2\conf\ssl.conf locate lines:
#== CA plugin option. Server Certificate Chain: #SSLCertificateChainFile /usr/local/apache2/conf/ssl.crt/ca.crt #== CA plugin option. Certificate Authority (CA): #SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/ca.crt |
Remove the hash "#" as shown this enables the two command lines:.
#== CA plugin option. Server Certificate Chain: SSLCertificateChainFile /usr/local/apache2/conf/ssl.crt/ca.crt #== CA plugin option. Certificate Authority (CA): SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/ca.crt |
Enable client authentication
To enable the use of client certificates, we need to add the following directives to ssl.conf
SSLVerifyClient require SSLVerifyDepth 1 |
Adding the above two lines access to the whole ssl web server will be limited only to web browsers that present a valid certificate. The directive SSLVerifyClient require instructs Apache that a certificate is required for access, one which is signed by our local CA. The SSLVerifyDepth value specifies the maximum depth of the intermediate certificate issuers in the chain of certificates. There are no intermediate CAs hence a value of "1," is used meaning all client certificates must be signed by our local CA.
Uniform Server has been pre-configured to restrict access to a single folder UniServer\ssl\personalcert the above two lines are placed in a Location block to specifically target that folder.
<Location /personalcert> SSLVerifyClient require SSLVerifyDepth 1 </Location> |
The main SSL server is accessible to anyone while only valid certificate holders can access folder personalcert.
Add content
Folder personalcert contains some example content you can delete this and add your own pages that you wish limited access.
For testing the example index page index.php contains the following:
<? phpinfo(); ?> |
Quick test
Start the servers and type the following into a browser: https://localhost/
Both Firefox and IE will diplay the public secure demo page (contained in the root foder ssl).
Now type in https://localhost/personalcert/
Both Firefox and IE are refused access, not surprising since neither has a personal certificate installed.
Run Client.bat
Lets create a client certificate (some_name.p12) and key (some_name.key) by running Client.bat
You will be prompted for the following information:
CN Common Name. Your full name [Mr X] : O Organisation Name (eg, company) [Nano] : OU Organisation Unit (eg, section) [Demo] : |
You can enter anything you like ideally use your full name for CN. Defaults are shown in square brackets. Use the defaults for this test.
After entering the above:
- When prompted enter the pass phrase you used to create the CA (fred)
- Type "y" to sign certificate
- Type "y" to commit - Creates certificate and adds serial number.
- When prompted enter export password (e.g. mpg123) (This is required to import the certificate into a browser)
- Confirm password.
The client certificate can be found in folder UniServer\plugins\UniServer_CA\CA\clients Inside this are sub-folders these are named using the value entered for CN.
If you used default common name (CN) the folder will be named Mr X inside this you will find the certificate named Mr X.p12
The certificate produced combines both a users private key and signed certificate into PKCS#12 format (also referred as PFX) In the real world a user would send only a signing request to the CA. Once signed and returned a user would combine this with his private key. Remember this is your personal CA so you can do whatever you like hence the certificate is created all in a single step in addition certificate is valid for 10 years (normally limited to 1 year for commercial CAs).
Install Certificate and test
Firefox
Install:
|
Test:
Note 1: If you have only a single certificate for this site let Firefox automatically choose it. Set this option as follows: Tools > Options > Advanced > set Select one automatically radio button click OK Firefox will not now require an input from you when a certificate is requested. Note 2: Unlike IE you need to manually set a master password to protect your certificates.
|
IE
Install:
|
Test:
|
Create two more personal certificate
For testing lets create two more client certificates.
Certificate 2
|
|
Certificate 3
|
Install the above two certificates to your browser as explained above.
Customising access control 1
One of the real powers of using certificates is that both Apache and scripts can target elements within a certificate. This allows access to be refined such that groups can access a particular area or be further refined to allow a single user access.
Each of our certificates has three fields that can be targeted CN, OU and O.
CN Common Name. Your full name | Mr X | Mr Y | Mr Z |
O Organisation Name (eg, company) | Nano | Mona | Apollo |
OU Organisation Unit (eg, section) | Demo | Demo2 | Maths |
Environment variables
These are exposed as environment variables with the following names:
- SSL_CLIENT_S_DN_O
- SSL_CLIENT_S_DN_OU
- SSL_CLIENT_S_DN_CN
Edit ssl.conf
By default they are internal to SSL to make them available to CGI scripts such as PHP and Perl the following directive must be added to the SSL configuration file:
- SSLOptions +StdEnvVars
Edit file UniServer\usr\local\apache2\conf\ssl.conf add the above three lines to this section:
<Location /personalcert> SSLVerifyClient require SSLVerifyDepth 1 SSLOptions +StdEnvVars </Location> |
Restart the servers this allows Apache to pick-up the new configuration
Edit test script - PHP
Now modify our test script UniServer\ssl\personalcert\index.php to display certificate fields using environment variables the complete script as shown below:
<? echo "<DIV ALIGN=CENTER>"; echo "<H1> Welcome ".getenv("SSL_CLIENT_S_DN_CN")."<H1>"; echo "<H2> O = ".getenv("SSL_CLIENT_S_DN_O")."<H2>"; echo "<H2> OU = ".getenv("SSL_CLIENT_S_DN_OU")."<H2>"; echo "</DIV>"; phpinfo(); ?> |
Note the function that gets the environment variable is getenv() it returns a string which is concatenated to create the final echo string. Top
Firefox Set-up
When Apache requests a certificate we want to present one of our personal certificates Firefox when set for auto selection uses the newest for that site unlike IE it does not offer a choice. When testing this along with a master password becomes very irritating hence make the following modifications to Firefox.
- Tools > Options > Advanced tab > set Ask me every time radio button click OK
- Tools > Options > Security tab
Un-Check Use a master password
In the pop-up enter master password click remove button.
Run Test
Test this configuration as follows:
- Start the servers
- Type the following into a browser https://localhost/personalcert/
- When requested select one of the certificates
- Test page displayed
- Refresh page and select another certificate
First three lines of each test page displays certificate information. Having access to this information allows you to write your own customised validation scripts.
Customising access control 2
Apache has access to the above environment variables this allows you to customise access.
Suppose our company is named Mona and we wish to allow access only for individuals from that company to the personalcert folder.
Add the following line to the location block in ssl.conf :
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" |
The compete block looks like:
<Location /personalcert> SSLVerifyClient require SSLVerifyDepth 1 SSLOptions +StdEnvVars SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" </Location> |
Test:
- Restart the server allows Apache to pick-up the new configuration.
- Access page https://localhost/personalcert/
- Confirm that Only Mr X and Mr Y have access
- Confirm Mr Z is denied access.
Note: Once Mr Z has been denied access, refreshing the page will not produce a certificate selection pop-up close the page and open a new tab. Accessing the page will now produce a certificate selection pop-up.
Individual access
It is possible to target a user by name for example Mr X you would use this line:
SSLRequire %{SSL_CLIENT_S_DN_CN} eq "Mr X"
However there is a problem with this! Suppose the Apollo company also has a person named Mr X he will have access to company Mona's confidential information.
The solution is to target two certificate fields CN and O as follows:
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X"
Modify ssl.conf to look like this:
<Location /personalcert> SSLVerifyClient require SSLVerifyDepth 1 SSLOptions +StdEnvVars SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X" </Location>
Test:
- Restart the server allowing Apache to pick-up the new configuration.
- Access page (index.php) https://localhost/personalcert/
- Confirm that Only Mr X has access
- Confirm Mr Y and Mr Z are denied access.
Note: Once Mr Y or Mr Z is denied access Firefox got a little confused hence had to re-start Firefox several times during this test.
.htaccess
Instead of using a location block in ssl.conf the directives can be placed in an .htaccess file.
- Create a new folder named test in folder UniServer\udrive\ssl
- Copy index.php from folder personalcert to folder test
- Copy .htaccess from folder ssl to folder test
Open .htaccess delete its content and replace with the following:
# This file provides security to a folder # Limiting access to a single user Mr X SSLOptions +StrictRequire SSLRequireSSL SSLRequire %{HTTP_HOST} eq "localhost" ErrorDocument 403 https://localhost SSLVerifyClient require SSLVerifyDepth 1 SSLOptions +StdEnvVars SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X"
What these line perform
SSLOptions +StrictRequire | # Use strict |
SSLRequireSSL | # Must have an SSL connection |
SSLRequire %{HTTP_HOST} eq "localhost" | # Must be this host |
ErrorDocument 403 https://localhost | # Above not true redirect |
SSLVerifyClient require | # Must use a certificate |
SSLVerifyDepth 1 | # Check against server CA |
SSLOptions +StdEnvVars | # Generate CGI variables |
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X" |
# Restrict access to Mr X |
With .htaccess files there is no need to restart the servers Apache reads this every time the folder is accessed.
Test:
- Access page (index.php) https://localhost/test/
- Confirm that Only Mr X has access
- Confirm Mr Y and Mr Z are denied access.
Summary
I have show how easy it is to create and use personal certificate, provided some examples of their use although these only scratch the surface.
There may come a time when a certificate becomes compromised what do you do in this situation. I cover revocation of personal certificates on the next page.