https://wiki.uniformserver.com/index.php?title=UniServer_CA2:_Client_Certificates&feed=atom&action=historyUniServer CA2: Client Certificates - Revision history2024-03-28T22:27:19ZRevision history for this page on the wikiMediaWiki 1.41.0https://wiki.uniformserver.com/index.php?title=UniServer_CA2:_Client_Certificates&diff=3977&oldid=prevRic: New page: {{Uc nav UniServer CA2}} '''Portable CA - Client Certificates''' The real power of running your own CA is the ability to sign certificates in particular '''personal''' (client) certificat...2009-12-11T19:15:46Z<p>New page: {{Uc nav UniServer CA2}} '''Portable CA - Client Certificates''' The real power of running your own CA is the ability to sign certificates in particular '''personal''' (client) certificat...</p>
<p><b>New page</b></p><div>{{Uc nav UniServer CA2}}<br />
'''Portable CA - Client Certificates'''<br />
<br />
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.<br />
<br />
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.<br />
<br />
Apache needs configuring in order to use personal certificate authentication.<br />
<br />
== Enable Apache for CA operation ==<br />
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:<br />
<br />
'''''[[#top | Top]]'''''<br />
==== Edit ssl.conf ====<br />
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.<br />
<br />
Edit file UniServer\usr\local\apache2\conf\'''ssl.conf''' locate lines: <br />
{|<br />
|-<br />
|<br />
<pre><br />
#== CA plugin option. Server Certificate Chain:<br />
#SSLCertificateChainFile /usr/local/apache2/conf/ssl.crt/ca.crt<br />
<br />
#== CA plugin option. Certificate Authority (CA):<br />
#SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/ca.crt<br />
</pre><br />
|}<br />
Remove the hash "#" as shown this enables the two command lines:.<br />
{|<br />
|-<br />
|<br />
<pre><br />
#== CA plugin option. Server Certificate Chain:<br />
SSLCertificateChainFile /usr/local/apache2/conf/ssl.crt/ca.crt<br />
<br />
#== CA plugin option. Certificate Authority (CA):<br />
SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/ca.crt<br />
</pre><br />
|}<br />
<br />
'''''[[#top | Top]]'''''<br />
<br />
==== Enable client authentication ====<br />
To enable the use of client certificates, we need to add the following directives to ssl.conf<br />
{|<br />
|-<br />
|<br />
<pre><br />
SSLVerifyClient require<br />
SSLVerifyDepth 1<br />
</pre><br />
|}<br />
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.<br />
<br />
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. <br />
{|<br />
|-<br />
|<br />
<pre><br />
<Location /personalcert><br />
SSLVerifyClient require<br />
SSLVerifyDepth 1<br />
</Location><br />
</pre><br />
|}<br />
The main SSL server is accessible to anyone while only valid certificate holders can access folder '''personalcert'''.<br />
<br />
==== Add content ====<br />
Folder '''personalcert''' contains some example content you can delete this and add your own pages that you wish limited access.<br />
<br />
For testing the example index page '''index.php''' contains the following:<br />
{|<br />
|-<br />
|<br />
<pre><br />
<?<br />
phpinfo();<br />
?><br />
</pre> <br />
|}<br />
'''''[[#top | Top]]'''''<br />
<br />
==== Quick test ====<br />
Start the servers and type the following into a browser: '''<nowiki>https://localhost/</nowiki>'''<br />
<br />
Both Firefox and IE will diplay the public secure demo page (contained in the root foder ssl). <br />
<br />
Now type in '''<nowiki>https://localhost/personalcert/</nowiki>'''<br />
<br />
Both Firefox and IE are refused access, not surprising since neither has a personal certificate installed.<br />
<br />
'''''[[#top | Top]]'''''<br />
==== Run Client.bat ====<br />
Lets create a client certificate (some_name'''.p12''') and key (some_name'''.key''') by running '''Client.bat'''<br />
<br />
You will be prompted for the following information:<br />
{|<br />
|-<br />
|<br />
<pre><br />
CN Common Name. Your full name [Mr X] :<br />
O Organisation Name (eg, company) [Nano] :<br />
OU Organisation Unit (eg, section) [Demo] :<br />
</pre><br />
|}<br />
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.<br />
<br />
After entering the above:<br />
* When prompted enter the pass phrase you used to create the CA ('''fred''')<br />
* Type "'''y'''" to sign certificate<br />
* Type "'''y'''" to commit - Creates certificate and adds serial number.<br />
* When prompted enter export password (e.g. '''mpg123''') (This is required to import the certificate into a browser)<br />
* Confirm password.<br />
<br />
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.<br />
<br />
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''' <br />
<br />
The certificate produced combines both a users private key and signed certificate into PKCS#12 format (also referred as PFX)<br />
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).<br />
<br />
'''''[[#top | Top]]'''''<br />
<br />
== Install Certificate and test ==<br />
=== Firefox ===<br />
{|<br />
|-<br />
|valign="top" width="50%"|<br />
'''''Install'':'''<br />
# Start browser<br />
# Select '''Tools > Options'''<br />
# Select '''Advanced''' (top right)<br />
# Select '''Encryption Tab'''<br />
# Click '''View Certificates''' button<br />
# Select '''Your Certificates TAB''' click '''Import''' button<br />
# Navigate to folder <br>UniServer\plugins\UniServer_CA\CA\clients\'''Mr X''' and select '''Mr X.p12'''<br />
# A pop-up is displayed '''enter import password''' (mpg123)<br />
# Click '''OK'''<br />
# Successfully restored click '''OK'''<br />
# '''Click OK''' to close window<br />
|<br />
'''''Test'':'''<br />
# Start Servers<br />
# Type into browser address bar '''<nowiki>https://localhost/personalcert/</nowiki>'''<br />
# In the ''site has requested that you identify yourself with a certificate'' pop-up select certificate for '''Mr X'''<br />
# Click '''OK'''<br />
# Click '''OK'''<br />
# Firefox request this several times just click OK (A real pain)<br />
# PHP Info page displayed.<br />
'''''Note 1'':''' If you have only a single certificate for this site let Firefox automatically choose it. Set this option as follows:<br />
<br />
'''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. <br />
<br />
'''''Note 2'':''' Unlike IE you need to manually set a master password to protect your certificates.<br />
* Tools > Options<br />
* Select '''Security tab'''<br />
* Select '''use a master password'''<br />
* Enter a master password and click '''OK'''<br />
|}<br />
'''''[[#top | Top]]'''''<br />
<br />
=== IE ===<br />
{|<br />
|-<br />
|width="50%"|<br />
'''''Install'':'''<br />
# Navigate to fole UniServer\plugins\UniServer_CA\CA\clients\'''Mr X'''<br />
# Double click on '''Mr X.p12'''<br />
# Certificate import '''Wizard starts'''<br />
# Click '''Next'''<br />
# File to import is listed click '''Next'''<br />
# Type in '''export password''' (mpg123)<br />
# Check '''Enable strong private key protection''' box<br />
# '''Un-Check''' Mark this key as exportable box<br />
# Click '''Next'''<br />
# Check Automatically select radio button is set click '''Next'''<br />
# Click '''Finish'''<br />
# Click '''Set Security Level''' button<br />
# '''Set High''' radio button click''' Next'''<br />
# '''Enter apassword''' (fred123)(required to use the certificate)<br />
# '''Confirm''' password <br />
# Click '''Finish'''<br />
# Click '''OK'''<br />
# The import was successful click '''OK'''<br />
|valign="top"|<br />
'''''Test'':'''<br />
* Start Servers<br />
* Typeinto browser address bar '''<nowiki>https://localhost/personalcert/</nowiki>'''<br />
* In the digital certificate pop-up select '''Mr X'''<br />
* Click '''OK'''<br />
* '''Enter password''' set in step 14 (fred123)<br />
* Click '''OK'''<br />
* PHP info '''page displayed'''.<br />
|}<br />
'''''[[#top | Top]]'''''<br />
<br />
== Create two more personal certificate ==<br />
For testing lets create two more client certificates.<br />
{|<br />
|-<br />
|<br />
'''''Certificate 2'''''<br>Run '''Client.bat''' when prompted enter the following<br />
{|<br />
|-<br />
|CN Common Name. Your full name [Mr X]:||'''Mr Y'''<br />
|-<br />
|O Organisation Name (eg, company) [Mona:]||'''Mona'''<br />
|-<br />
|OU Organisation Unit (eg, section) [Demo]:||'''Demo2'''<br />
|}<br />
|<br />
&nbsp;<br />
|<br />
'''''Certificate 3'''''<br>Run '''Client.bat''' when prompted enter the following<br />
{|<br />
|-<br />
|CN Common Name. Your full name [Mr X]:||'''Mr Z'''<br />
|-<br />
|O Organisation Name (eg, company) [Mona:]||'''Apollo'''<br />
|-<br />
|OU Organisation Unit (eg, section) [Demo]:||'''Maths'''<br />
|}<br />
|}<br />
Install the above two certificates to your browser as explained above.<br />
<br />
'''''[[#top | Top]]'''''<br />
<br />
== Customising access control 1 ==<br />
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.<br />
<br />
Each of our certificates has three fields that can be targeted '''CN''', '''OU''' and '''O'''.<br />
<br />
{|cellspacing="4"|<br />
|-style="background:#f5f5f5;"<br />
|'''CN''' Common Name. Your full name||'''Mr X'''||'''Mr Y'''||'''Mr Z'''<br />
|-style="background:#f5f5f5;"<br />
|'''O''' Organisation Name (eg, company)||'''Nano'''||'''Mona'''||'''Apollo'''<br />
|-style="background:#f5f5f5;"<br />
|'''OU''' Organisation Unit (eg, section)||'''Demo'''||'''Demo2'''||'''Maths'''<br />
|}<br />
<br />
=== Environment variables ===<br />
These are exposed as environment variables with the following names:<br />
<br />
* SSL_CLIENT_S_DN_O<br />
* SSL_CLIENT_S_DN_OU<br />
* SSL_CLIENT_S_DN_CN<br />
<br />
=== Edit ssl.conf ===<br />
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:<br />
<br />
* '''SSLOptions +StdEnvVars'''<br />
<br />
Edit file UniServer\usr\local\apache2\conf\'''ssl.conf''' add the above three lines to this section:<br />
{|<br />
|-<br />
|<br />
<pre><br />
<Location /personalcert><br />
SSLVerifyClient require<br />
SSLVerifyDepth 1<br />
SSLOptions +StdEnvVars<br />
</Location> <br />
</pre><br />
|}<br />
Restart the servers this allows Apache to pick-up the new configuration<br />
<br />
=== Edit test script - PHP ===<br />
Now modify our test script UniServer\ssl\personalcert\'''index.php''' to display certificate fields using environment variables the complete script as shown below:<br />
{|<br />
|-<br />
|<br />
<pre><br />
<?<br />
echo "<DIV ALIGN=CENTER>";<br />
echo "<H1> Welcome ".getenv("SSL_CLIENT_S_DN_CN")."<H1>";<br />
echo "<H2> O = ".getenv("SSL_CLIENT_S_DN_O")."<H2>";<br />
echo "<H2> OU = ".getenv("SSL_CLIENT_S_DN_OU")."<H2>";<br />
echo "</DIV>";<br />
phpinfo();<br />
?><br />
</pre><br />
|}<br />
Note the function that gets the environment variable is '''getenv()''' it returns a string which is concatenated to create the final echo string.<br />
'''''[[#top | Top]]'''''<br />
<br />
=== Firefox Set-up ===<br />
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.<br />
<br />
# '''Tools > Options > Advanced tab >''' '''set''' ''Ask me every time'' radio button click '''OK''' <br />
# '''Tools > Options > Security tab'''<br> '''Un-Check''' ''Use a master password''<br> In the pop-up '''enter master password''' click '''remove button'''.<br />
<br />
'''''[[#top | Top]]'''''<br />
=== Run Test ===<br />
Test this configuration as follows:<br />
<br />
# Start the servers<br />
# Type the following into a browser '''<nowiki>https://localhost/personalcert/</nowiki>'''<br />
# When requested select one of the certificates<br />
# Test page displayed<br />
# Refresh page and select another certificate<br />
<br />
First three lines of each test page displays certificate information. Having access to this information allows you to write your own customised validation scripts.<br />
<br />
'''''[[#top | Top]]'''''<br />
<br />
== Customising access control 2 ==<br />
Apache has access to the above environment variables this allows you to customise access.<br />
<br />
Suppose our company is named '''Mona''' and we wish to allow access only for individuals from that company to the '''personalcert''' folder.<br />
<br />
Add the following line to the location block in ssl.conf :<br />
{|<br />
|-<br />
|<br />
<pre><br />
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona"<br />
</pre><br />
|}<br />
The compete block looks like:<br />
{|<br />
|-<br />
|<br />
<pre><br />
<Location /personalcert><br />
SSLVerifyClient require<br />
SSLVerifyDepth 1<br />
SSLOptions +StdEnvVars<br />
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona"<br />
</Location><br />
</pre><br />
|}<br />
'''''Test'':'''<br />
* Restart the server allows Apache to pick-up the new configuration. <br />
* Access page '''<nowiki>https://localhost/personalcert/</nowiki>'''<br />
* Confirm that Only Mr X and Mr Y have access<br />
* Confirm Mr Z is denied access.<br />
'''''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. <br />
<br />
'''''[[#top | Top]]'''''<br />
=== Individual access ===<br />
It is possible to target a user by name for example Mr X you would use this line:<br />
<pre><br />
SSLRequire %{SSL_CLIENT_S_DN_CN} eq "Mr X"<br />
</pre><br />
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.<br />
<br />
The solution is to target two certificate fields '''CN''' and '''O''' as follows:<br />
<pre><br />
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X"<br />
</pre> <br />
Modify ssl.conf to look like this:<br />
<pre><br />
<Location /personalcert><br />
SSLVerifyClient require<br />
SSLVerifyDepth 1<br />
SSLOptions +StdEnvVars<br />
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X"<br />
</Location><br />
</pre><br />
'''''Test'':'''<br />
* Restart the server allowing Apache to pick-up the new configuration. <br />
* Access page (index.php) '''<nowiki>https://localhost/personalcert/</nowiki>'''<br />
* Confirm that Only Mr X has access<br />
* Confirm Mr Y and Mr Z are denied access.<br />
'''''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.<br />
<br />
'''''[[#top | Top]]'''''<br />
<br />
== .htaccess ==<br />
Instead of using a location block in '''ssl.conf''' the directives can be placed in an '''.htaccess''' file.<br />
<br />
* Create a new folder named '''test''' in folder UniServer\udrive\'''ssl'''<br />
* Copy '''index.php''' from folder '''personalcert''' to folder '''test'''<br />
* Copy '''.htaccess''' from folder '''ssl''' to folder '''test'''<br />
Open .htaccess delete its content and replace with the following:<br />
<pre><br />
# This file provides security to a folder<br />
# Limiting access to a single user Mr X <br />
<br />
SSLOptions +StrictRequire <br />
SSLRequireSSL <br />
SSLRequire %{HTTP_HOST} eq "localhost" <br />
ErrorDocument 403 https://localhost <br />
<br />
SSLVerifyClient require <br />
SSLVerifyDepth 1 <br />
SSLOptions +StdEnvVars<br />
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona" and %{SSL_CLIENT_S_DN_CN } eq "Mr X" <br />
</pre> <br />
What these line perform<br />
{|style="color:green; background-color:#ffffcc;" cellpadding="0" cellspacing="4" border="1"|<br />
|-<br />
|style="background:#f5f5f5;"|SSLOptions +StrictRequire || # Use strict<br />
|-<br />
|style="background:#f5f5f5;"|SSLRequireSSL || # Must have an SSL connection<br />
|-<br />
|style="background:#f5f5f5;"|SSLRequire %{HTTP_HOST} eq "localhost" || # Must be this host<br />
|-<br />
|style="background:#f5f5f5;"|ErrorDocument 403 <nowiki>https://localhost</nowiki>|| # Above not true redirect <br />
|-<br />
|&nbsp;||&nbsp;<br />
|-<br />
|style="background:#f5f5f5;"|SSLVerifyClient require || # Must use a certificate<br />
|-<br />
|style="background:#f5f5f5;"|SSLVerifyDepth 1 || # Check against server CA<br />
|-<br />
|style="background:#f5f5f5;"|SSLOptions +StdEnvVars || # Generate CGI variables<br />
|-<br />
|style="background:#f5f5f5;"|SSLRequire %{SSL_CLIENT_S_DN_O} eq "Mona"<br> and %{SSL_CLIENT_S_DN_CN } eq "Mr X" ||# Restrict access to Mr X<br />
|}<br />
With .htaccess files there is no need to restart the servers Apache reads this every time the folder is accessed.<br />
<br />
'''''Test'':'''<br />
* Access page (index.php) '''<nowiki>https://localhost/test/</nowiki>'''<br />
* Confirm that Only Mr X has access<br />
* Confirm Mr Y and Mr Z are denied access.<br />
<br />
'''''[[#top | Top]]'''''<br />
== Summary ==<br />
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.<br />
<br />
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 [[UniServer CA2: Client Certificates Revocation | next page]].<br />
<br />
'''''[[#top | Top]]'''''<br />
----<br />
<br />
[[Category: Uniform Server 5.0-Nano]]</div>Ric