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, http://wiki.nginx.org/HttpSslModule and trial/error:
http://blog.nategood.com/client-side-certificate-authentication-in-ngi and http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-clie…
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:
https://gist.github.com/4148611
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 ./new_ca.sh testconfig
https://gist.github.com/4148663
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.
https://gist.github.com/4148834
When prompted, make sure to put your website FQDN in the Common name. Ex: ‘Common Name (e.g. server FQDN or YOUR name) []:your.domain.com’
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.
https://gist.github.com/4148845
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
https://gist.github.com/4149088
Notes:
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 http://wiki.nginx.org/HttpSslModule#ssl_crl 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:
https://gist.github.com/4149421
Notes:
you must restart nginx after running this command
Thats it. Any comments on improving any of the above are welcome.