Apache SSL client certificate, configuring Apache to allow access only SSL certificate installed on client

Let’s configure Apache (on an Ubuntu 12) to allow access to clients with an installed SSL certificate personnel, first we have to create some structures to later work with revocation lists.

The first is to have openssl installed:

ubuntu@ip-10-112-31-82:~$ sudo aptitude install openssl

We will create a directory structure that conforms to the expected paths for the configuration file openssl.cnf:

Source   
ubuntu@ip-10-112-31-82:~$ mkdir -p /vol/apache2_certs
ubuntu@ip-10-112-31-82:~$ cd /vol/apache2_certs/
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo cp /etc/ssl/openssl.cnf .

The openssl.cnf file defines a directory structure to work among other things with lists of denial of certificates, will edit and modify the line:

Source   
dir = ./demoCA

With:

Source   
dir = /vol/apache2_certs

And to avoid surprises with the expiration of the CRL certificate:

Source   
default_crl_days= 30

With:

Source   
default_crl_days= 3650

In this file there are many references to the variable $dir, we can see:

Source   
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ cat openssl.cnf | grep '$dir'
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
serial = $dir/tsaserial # The current serial number (mandatory)
signer_cert = $dir/tsacert.pem # The TSA signing certificate
certs = $dir/cacert.pem # Certificate chain to include in reply
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)

Some of the references are to create directories that should exist for all destinations:

Source   
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo mkdir -p newcerts private
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ ls -l
total 20
drwxr-xr-x 2 root root 4096 Apr 10 09:53 newcerts
-rw-r--r-- 1 root root 10845 Apr 10 09:51 openssl.cnf
drwxr-xr-x 2 root root 4096 Apr 10 09:53 private

Now we will generate the necessary certificates keeping the name he expects to find the configuration file openssl.cnf.

Creating certificate signing request and signature of certification authority:

Source   
#key creation
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl genrsa -out /vol/apache2_certs/private/cakey.pem 1024
Generating RSA private key, 1024 bit long modulus
..++++++
................++++++
e is 65537 (0x10001)
#Signing Request
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl req -new -key /vol/apache2_certs/private/cakey.pem -out /vol/apache2_certs/private/cacsr.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:ANDALUCIA
Locality Name (eg, city) []:SEVILLA
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ACME
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
#signing
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl x509 -req -days 3650 -in /vol/apache2_certs/private/cacsr.csr -signkey /vol/apache2_certs/private/cakey.pem -out /vol/apache2_certs/cacert.pem
Signature ok
subject=/C=ES/ST=ANDALUCIA/L=SEVILLA/O=ACME
Getting Private key

Now we will create a certificate for the Apache Web server, url ssl.acme.es, will sign the certificate authority created earlier:

Source   
#key creation
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl genrsa -out /vol/apache2_certs/private/ssl.acme.es.key.pem 1024
Generating RSA private key, 1024 bit long modulus
.................................................++++++
....++++++
e is 65537 (0x10001)
#Signing Request
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl req -new -key /vol/apache2_certs/private/ssl.acme.es.key.pem -out /vol/apache2_certs/private/ssl.acme.es.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:ANDALUCIA
Locality Name (eg, city) []:SEVILLA
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ACME
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:ssl.acme.es
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
#signing by the certifying authority
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl x509 -req -days 3650 -CA /vol/apache2_certs/cacert.pem -CAkey /vol/apache2_certs/private/cakey.pem -CAcreateserial -CAserial /vol/apache_cert/serial -in /vol/apache2_certs/private/ssl.acme.es.csr -out /vol/apache2_certs/ssl.acme.es.crt.pem
Signature ok
subject=/C=ES/ST=ANDALUCIA/L=SEVILLA/O=ACME/CN=ssl.acme.es
Getting CA Private Key

Now we will create a personal certificate and browser version to install on the client, and later set up apache. First we create a directory for personal certificates have located perfectly:

Source   
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo mkdir /vol/apache2_certs/certs_people
#key creation
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl genrsa -out /vol/apache2_certs/certs_people/55555555X.pem 1024
Generating RSA private key, 1024 bit long modulus
...................................++++++
...................................++++++
e is 65537 (0x10001)
#Signing Request
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl req -new -key /vol/apache2_certs/certs_people/55555555X.pem -out /vol/apache2_certs/certs_people/55555555X.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:ANDALUCIA
Locality Name (eg, city) []:SEVILLA
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ACME
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:Jonh Doe
Email Address []:jdoe@acme.es
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
#signing by the certifying authority
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl x509 -req -days 3650 -CA /vol/apache2_certs/cacert.pem -CAkey /vol/apache2_certs/private/cakey.pem -CAcreateserial -CAserial /vol/apache_cert/serial -in /vol/apache2_certs/certs_people/55555555X.csr -out /vol/apache2_certs/certs_people/55555555X.crt.pem
Signature ok
subject=/C=ES/ST=ANDALUCIA/L=SEVILLA/O=ACME/OU=IT/CN=Jonh Doe/emailAddress=jdoe@acme.es
Getting CA Private Key
Now we convert to the personal certificate it can be imported into a browser (ask us a password "test" that will be demanded for imports):
[codesyntax lang="bash"]
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo sudo openssl pkcs12 -export -clcerts -in /vol/apache2_certs/certs_people/55555555X.crt.pem -inkey /vol/apache2_certs/certs_people/55555555X.pem -out /vol/apache2_certs/certs_people/55555555X.p12
Enter Export Password:
Verifying - Enter Export Password:

Now we have to create a certificate revocation file (crl.pem), an index file (index.txt) and the file numbering (crlnumber):

Source   
#Creating index file
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo touch /vol/apache2_certs/index.txt
#tengo que crear el fichero crlnumber con 01 (un número en hexa):
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo vi /vol/apache2_certs/crlnumber
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ cat /vol/apache2_certs/crlnumber
01
#file creation crl.pem
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl ca -config /vol/apache2_certs/openssl.cnf -gencrl -out /vol/apache2_certs/crl.pem
Using configuration from /vol/apache2_certs/openssl.cnf

Summing a little now have a tree of directories and files:

Source   
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ tree
.
├── cacert.pem
├── certs_people
│   ├── 55555555X.crt.pem
│   ├── 55555555X.csr
│   ├── 55555555X.p12
│   └── 55555555X.pem
├── crlnumber
├── crlnumber.old
├── crl.pem
├── index.txt
├── newcerts
├── openssl.cnf
├── private
│   ├── cacsr.csr
│   ├── cakey.pem
│   ├── ssl.acme.es.csr
│   └── ssl.acme.es.key.pem
└── ssl.acme.es.crt.pem
3 directories, 15 files

That is, we have:

  • A Certificate Authority (cakey.pem files, cacsr.csr and cacert.pem
  • A web certificate for ssl.acme.es (files ssl.acme.es.key.pem, ssl.acme.es.csr and ssl.acme.es.crt.pem) signed by the certifying authority.
  • A Personal certificate for Jonh Doe (55555555X files. *), Signed by the certifying authority.
  • Files Necessary for certificate revocation (crlnumber files, crlnumber.old, crl.pem and index.txt

Now we configure Apache to only allow SSL access to browsers with an installed personal certificate (the Jonh Doe).

We go to the apache configuration directory create a virtual host from the default-ssl:

Source   
ubuntu@ip-10-112-31-82:/etc/apache2/sites-enabled$ ls
000-default
#If there is a default-ssl virtual host must be disabled
ubuntu@ip-10-112-31-82:/etc/apache2/sites-enabled$ sudo a2dissite default-ssl
#copy base configuration
ubuntu@ip-10-112-31-82:/etc/apache2/sites-enabled$ cd ../sites-available/
ubuntu@ip-10-112-31-82:/etc/apache2/sites-available$ sudo cp default-ssl ssl.acme.es

Edit the file ssl.acme.es and we have to find and modify the entries:

Source   
SSLCertificateFile /vol/apache2_certs/ssl.acme.es.crt.pem
SSLCertificateKeyFile /vol/apache2_certs/private/ssl.acme.es.key.pem
SSLCACertificateFile /vol/apache2_certs/cacert.pem
SSLCARevocationFile /vol/apache2_certs/crl.pem
SSLVerifyClient require
SSLVerifyDepth 10

Activate the virtualhost and restart Apache:

Source   
ubuntu@ip-10-112-31-82:/etc/apache2/sites-available$ sudo a2ensite ssl.acme.es
Enabling site ssl.acme.es.
To activate the new configuration, you need to run:
service apache2 reload
ubuntu@ip-10-112-31-82:/etc/apache2/sites-available$ sudo /etc/init.d/apache2 restart
* Restarting web server apache2 ... waiting [ OK ]

Once the certificate is installed 55555555X.p12 we can try to access the https://ssl.acme.es. During access will confirm certifies to use.

You might see a message indicating that the browser is not a trusted site (and stuff so little reassuring), as this show is designed for an environment where personal certificates are distributed is no problem importing the certifying authority the Navigator. You just have to import the file cacert.pem.

Now we will revoke the certificate of staff John Doe, recreate the file crl.pem revocation and reload Apache:

Source   
#revoked certificate
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl ca -config /vol/apache2_certs/openssl.cnf -revoke /vol/apache2_certs/certs_people/55555555X.crt.pem
Using configuration from /vol/apache2_certs/openssl.cnf
Adding Entry with serial number 8BE88F0198C75DDE to DB for /C=ES/ST=ANDALUCIA/L=SEVILLA/O=ACME/OU=IT/CN=Jonh Doe/emailAddress=jdoe@acme.es
Revoking Certificate 8BE88F0198C75DDE.
Data Base Updated
#file regeneration crl.pem
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl ca -config /vol/apache2_certs/openssl.cnf -gencrl -out /vol/apache2_certs/crl.pem
Using configuration from /vol/apache2_certs/openssl.cnf
#reload apache
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo /etc/init.d/apache2 reload
* Reloading web server config apache2 [ OK ]

We can see with revoked certificates:

Source   
ubuntu@ip-10-112-31-82:/vol/apache2_certs$ sudo openssl crl -text -noout -in /vol/apache2_certs/crl.pem
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: /C=ES/ST=ANDALUCIA/L=SEVILLA/O=ACME
Last Update: Apr 10 12:26:52 2013 GMT
Next Update: May 10 12:26:52 2013 GMT
CRL extensions:
X509v3 CRL Number:
2
Revoked Certificates:
Serial Number: 8BE88F0198C75DDE
Revocation Date: Apr 10 12:24:33 2013 GMT
Signature Algorithm: sha1WithRSAEncryption
0d:6b:f6:db:52:52:fa:1e:dc:19:73:73:fc:41:71:43:8e:4e:
...
3d:5d

Where the serial number 8BE88F0198C75DDE matches the certificate information Jonh Doe:

Source   
ubuntu@ip-10-112-31-82:/vol/apache2_certs/certs_people$ sudo openssl x509 -text -noout -in /vol/apache2_certs/certs_people/55555555X.crt.pem
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 10081465002889797086 (0x8be88f0198c75dde)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=ES, ST=ANDALUCIA, L=SEVILLA, O=ACME
Validity
Not Before: Apr 10 11:09:19 2013 GMT
Not After : Apr 8 11:09:19 2023 GMT
Subject: C=ES, ST=ANDALUCIA, L=SEVILLA, O=ACME, OU=IT, CN=Jonh Doe/emailAddress=jdoe@acme.es
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:c1:59:9b:97:33:c8:61:51:b8:22:bd:4a:37:64:
...
1a:30:6b:84:72:6e:25:07:83
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
29:35:98:08:02:fb:fd:86:f9:1b:15:26:26:bb:31:7d:f6:1f:
...
8c:84

If you want to reactivate the use of a personal certificate, simply:

  • Remove entry certificate file index.txt
  • Regenerar the file crl.pem
  • Make reload Apache

And with this you can set up a system very, very safe and revoking access to web services.

Leave a Reply