There are a few blogs out there that disucss this topic but none of them were as thorough as I needed and none quite fit exactly what I was looking for.  Here is a HOWTO with examples as well as scripts to manage everything.

First want to give credit I used the following 2 blog posts to get me pointed in the right direction. From there it was lots of man pages, and trial/error: and…

Note: you will want to run all commands as root/sudo

Note2: use this at your own risk. I am by no means a security expert.

Step 1: Configure OpenSSL

You first need to configure openssl such that it knows how to create and maintain your client certs.

Create a new configuration section in /usr/lib/ssl/openssl.cnf like the following:

Few things of note here:

dir: we are going to be namespacing everything into its own dir
crlnumber/crl: these are commented out. Using v1 style deny of certs in the field that you do not want to be vaild anymore
serial: this is a running version number that makes new client certs more unique


Step 2: Build a Certificate Authority

The following script will create the dirs and files needed for the CA. Run it like ./ testconfig

Things to note here:

This is a self signed cert . I’m only using this for internal tools, so this is OK for my use case. Also you’ll see the CA is valid for 3 yrs.  You’ll also notice that it creats the CRL.


Step 3: Create the server SSL certificate

This will be used by Nginx.

When prompted, make sure to put your website FQDN in the Common name. Ex: ‘Common Name (e.g. server FQDN or YOUR name) []’

things to note in this script:

Again 3 year expire time on the cert. Self signed.


Step 4: Create a client cert

This will create a .p12 file (contains pub and private key in one). This .p12 file is what you give your end user (aka client). They will import this file into their browser, to be used for your site.

Things to note:
When prompted for ‘Common Name’ enter the end users name. Ex: Ryan Pendergast. Also be sure to leverage email adress. You can use this info in your web apps (it is passed along by Nginx)

I did set a PW for the [user].key but I did NOT make an export password.  The export PW is one the client would have to type in before they import they p12 into their browser. 

Send this p12 to your user.

Step 5: Setup nginx

error_log: note ‘debug’ is on. This helps you look into problems in the handshake process. Once you get things working, remove the ‘debug’.
checkout for meanings of the directives

Make sure to restart nginx.

Step 6: Test it out

Open up chrome. Go to settings, search for setting ‘ssl’. Click manage certs and import the p12. If you didn’t provide an export PW in step 4 just leave PW blank.

When requests come in, users must present a client cert. If they present one, server makes sure that the CA was the one that created the cert.

Step 7: revoking client certs

If for example, someone leaves you company, you will want to revoke their cert. To do so, use the following script:

you must restart nginx after running this command


Thats it. Any comments on improving any of the above are welcome.