9

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

Drifter104
  • 3,773
  • 2
  • 25
  • 39

3 Answers3

2

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.

dtoubelis
  • 4,677
  • 1
  • 29
  • 32
  • So I updated the `client_package.cer` with the CA root and intermediate certificates but I'm still getting the same issue. Well I say the same error, the message no longer mentions SPDY. To confirm the client_package.cer no longer contains the client certs – Drifter104 Aug 20 '15 at 16:40
  • I have configuration exactly like yours on one of my servers. Make sure that you read the link I provided and you may also want to add something like this https://gist.github.com/dtoubelis/2e0813103ec089d6d9f1 to your `/etc/nginx/sites-available/default` just to isolate the issue. – dtoubelis Aug 20 '15 at 17:01
  • Oh, one more thing. I had the same issue when I had ocsp stapling enabled but forgot to provide trusted certificates. Here is snipet from my current working configuration https://gist.github.com/dtoubelis/562108c860df32f9b8cc – dtoubelis Aug 20 '15 at 17:09
  • ... and this is how you can verify it using openssl `openssl s_client -servername example.com -connect example.com:443 -key client-cert.key -cert client-cert.crt` – dtoubelis Aug 20 '15 at 17:15
  • 1
    Finally resolved and the issue looks like it was the CA not being in the original chain. I did wonder about this when I posted the question but I couldn't find anything to clarify it. – Drifter104 Aug 21 '15 at 14:01
1

Use ssl_trusted_certificate directive indstead of ssl_client_certificate. See docs http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate .

But anyway, I would recomend signing all client certificates with ONE ROOT CA and verify, if the client certificate is signed with that CA.

If it solved your problem, please accept it as answer.

mvorisek
  • 515
  • 1
  • 9
  • 19
  • Maybe i miss understood something here. I changed the directive as suggested and used the same pem file. I had to remove `ssl_verify_client on` because it isn't valid with that directive. This just allows anyone access to the site. – Drifter104 Aug 17 '15 at 08:32
  • Do you use caching on that server? If no, you can use `if` with confidence (otherwise `if` statemens are evil) and check the client cert with agains some nginx variable ($ssl_client_fingerprint, $ssl_client_raw_cert, ...). See the end of docs http://nginx.org/en/docs/http/ngx_http_ssl_module.html . – mvorisek Aug 17 '15 at 09:34
  • This answer is not accurate, please see here http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate – dtoubelis Aug 19 '15 at 04:31
  • @dtoubelis see my comments, I use nginx a lot, if there is a problem and I can not figure it out, I always log all related variables and if I see, that the variable product correct result, I simply use `if` and the problem is solved. – mvorisek Aug 19 '15 at 16:41
  • 1
    @Mvorisek, the only difference between `ssl_trusted_certificate` and `ssl_client_sertificate` is that the latter causes nginx to send list of acceptable CAs to the client (to show the pop-up in the browser with certificate selection box) and the other does not. People choose one over the other for privacy reasons but this has nothing to do with the problem @Drifter104 is having. – dtoubelis Aug 19 '15 at 19:55
  • I created a log format with all the SSL variables but of course SSL session isn't established if the client cert isn't validated. So I'm guessing the if statements wouldn't work either? – Drifter104 Aug 20 '15 at 16:42
  • Just accept all ssl connections with and without client certs, with and without validation... – mvorisek Aug 20 '15 at 16:55
  • QUOTE: ,,, ssl_trusted_certificate ... In contrast to ...ssl_client_certificate, the listof these certificates will not be sent to clients. This note is not about certificate chain sent to the client, but about the _list_ of certificates sent to clients while requesting client certificates. See RFC5246, 7.4.4. Certificate Request, https://tools.ietf.org/html/rfc5246#section-7.4.4 - the list is sent in the certificate_authorities field of the Certificate Request message to let clients know which authorities are accepted by the server. Maxim Dounin http://nginx.org/ – Craig Hicks Apr 17 '18 at 01:17
-1

Ssl certificates are wildcard or single domain? Maybe developer ia tryng to access website url eg test.myapp.com but certificate is issued only for myapp.com or www.myapp.com

x86fantini
  • 302
  • 1
  • 3
  • 9