proxy_ssl_certificate not exchanging client certificates

lieut_data nginx-forum at nginx.us
Tue Apr 28 21:17:32 UTC 2015


I was excited to see proxy_ssl_certificate and friends land in Nginx 1.7.8,
and decided to revisit Nginx as a candidate for proxy caching an upstream
server requiring client authentication. I've included the debugging
configuration I've been playing around with at the end of this post.

This particular upstream server does not trigger client authentication for
all endpoints. For example, I can issue 

-----
http http://NGINX_PROXY_IP/test/path Host:UPSTREAM_SERVER
-----

and get back the proxied response without error. However, for endpoints that
require client authentication (triggered by the server after it examines the
request path), nginx never gets a response. I've verified that the upstream
server is working as expected using both wget:

-----
wget --verbose --debug --save-headers -O -
--ca-certificate=PATH_TO_SERVER_CERTFICATE
--certificate=PATH_TO_CLIENT_CERTIFICATE
--private-key=PATH_TO_CLIENT_PRIVATE_KEY
https://UPSTREAM_SERVER/path/requiring/client/authentication
-----

and openssl's s_client:
-----
echo -e "GET https://UPSTREAM_SERVER/path/requiring/client/authentication
HTTP/1.0\r\n\r\n" | openssl s_client -ign_eof -connect UPSTREAM_SERVER:443
-state -debug -cert PATH_TO_CLIENT_CERTIFICATE -key
PATH_TO_CLIENT_PRIVATE_KEY
-----

In the latter case, it's apparent that the server triggers renegotiation
after seeing the requested path, and openssl's s_client responds accordingly
by sending the client certificate, completing the exchange moments later.
However, when invoking the same via the Nginx proxy:

-----
http http://NGINX_PROXY_IP/
Host:UPSTREAM_SERVER/path/requiring/client/authentication
-----

the upstream connection eventually closes after sending no data -- the same
behaviour it exhibits when no client certificates are provided via wget or
openssl's s_client.

I'm using nginx.debug and have verified that the client certificate files
are read (throwing errors if the wrong path is specified). I've also used
ltrace and verified that Nginx appears to inject the client certificate via
SSL_CTX_use_certificate (taking a somewhat different path than wget's
SSL_CTX_use_certificate_file).

Have I failed to configure Nginx with the requisite client certificates? Is
there anyway to see the level of debugging from openssl's s_client but via
Nginx?

Here's the configuration in question:

-----
user nginx;
worker_processes  1;
daemon off;

error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    proxy_cache_methods GET HEAD;
    proxy_cache_min_uses 1;

    server {
        listen 80;

        proxy_http_version 1.1;
        proxy_ssl_protocols 'TLSv1.2';
        proxy_ssl_certificate PATH_TO_CLIENT_CERTIFICATE;
        proxy_ssl_certificate_key PATH_TO_CLIENT_PRIVATE_KEY;
        proxy_ssl_session_reuse off;
        proxy_ssl_trusted_certificate PATH_TO_SERVER_CERTFICATE;
        proxy_ssl_verify on;

        location / {
            resolver 8.8.8.8;
            proxy_pass https://$host$request_uri;
            proxy_cache rest-cache;

            add_header rt-Fastcgi-Cache $upstream_cache_status;
            proxy_set_header Host $host;
            proxy_ignore_headers Set-Cookie;
        }
    }
}
-----

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,258464,258464#msg-258464



More information about the nginx mailing list