Nginx Client SSL Authentication – Step-by-Step Guide

nginxssl-certificate

I have Nginx running purely as a proxy to a various number of web servers. One of our clients has asked us to use client certificates and has provided us 3 certificates for the 3 different machines that will connect to a webservice running on one of the proxied servers.

Having never done this before I found the relevant nginx settings and created a site config (relevant part below)

      server {
        listen                  443 ssl; 
        server_name             service.domain.com;
        ssl_certificate         /etc/nginx/ssl/wildcard/server.crt; 
        ssl_certificate_key     /etc/nginx/ssl/wildcard/server.key; 
        ssl_client_certificate  /etc/nginx/ssl/client.certificates/client_package.cer;
        ssl_verify_client on;

I concatenated the 3 client certificates plus a certificate created by a developer (this one was self signed) who needed to access the site during development into the single file mentioned above.

The client has now tried to access the site but is unable to do so. As a test of the config I removed the developer cert from the concatenated certificate file and confirmed he was unable to access the site. Once I added his cert back in to the concatenated file he (developer) was able to access the site correctly again.

I turned on debug level access on the error log and when the client tried to connect I got the following error.

2015/08/13 11:57:41 [info] 27601#0: *1963 client sent no required SSL certificate while processing SPDY, client: 1x.xx.xx.xx, server: service.domain.com, request: "GET /test.cfm
HTTP/1.1", host: "service.domain.com"

As you can see from the configuration above I don't have SPDY enabled (but I do on other sites), and the client ensures me they are sending the client certificates. As this is the first time I've done this I want to make sure that before I go back and say my logs say you aren't sending a client certificate, I've got everything correct this end.

With regards to the certificates that were sent to me: All 3 are signed by the same public certificate authority. I don't however have the whole chain in concatenated file. What guides I've found on-line mention having the root ca as well, but they all talking about self-signed which none of these are. So I'm not sure that applies.

To clarify as well I'm not trying to pass the client certificate to the proxied server either.

nginx version: nginx/1.8.0
openssl version: OpenSSL 1.0.1k 8 Jan 2015

If there is any more information needed please let me know

Best Answer

Your configuration is actually correct. However, please make sure that you DO NOT put actual client certificates into client_package.cer file. This file should only contain trusted CA certificates, actually it should contain the complete chain(s). You should request all root and intermediate certificates from your client if they haven't provided them.

There are also few gotchas related to the default server setup. Please read this and make sure it does not affect you.