We have an application that is not client-certificate aware and must consume a client-certificate authenticated web-service. To fix this, we're trying to use Nginx to reverse proxy a local (http) url which our application will hit to the remote HTTPS and client certificate authenticated service. The config is below:

location /secure/api/ {
    proxy_pass https://secure.webservice.com/secure/api/;
    proxy_ssl_certificate     /etc/ssl/api-client.crt;
    proxy_ssl_certificate_key /etc/ssl/api-client.crt.key;
    proxy_ssl_verify off;

When trying to connect to the reverse-proxy url (http://our.proxy.com/secure/api/) it just sits there and spins. If we test the connection from the proxy with wget or openssl, we can connect successfully.

Here's a snippit from nginx/error.log:

2015/08/25 15:33:56 [info] 29810#0: *57 client closed connection while waiting for request, client: x.x.x.x, server:
2015/08/25 15:34:05 [info] 29810#0: *53 epoll_wait() reported that client prematurely closed connection, so upstream connection is closed too while reading response header from upstream, client: x.x.x.x, server: our.proxy.com, request: "GET /secure/api/ HTTP/1.1", upstream: "https://y.y.y.y:443/secure/api/", host: "our.proxy.com"

The 'client closed connection' lines are concerning and I'm not sure which side of the connection is closing the connection; client->proxy or proxy->upstream.

Also, it's worth noting that tcpdump does show that nginx is initiating a connection to secure.webservice.com over 443.

I feel like the first step in figuring this out is deciphering which side of the connection is closing and why...thoughts?

Thanks in advance.

Note: x.x.x.x is a local (private) ip, y.y.y.y is an internet (public) ip.


There are a few articles regarding this configuration here and here. We also use client SSL certificates with Nginx and have the following working config with http/https redirect :

#config for upstream app servers (not aware of SSL)
upstream appcluster {
    server X.X.X.1:8000;
    server X.X.X.2:8000;
# http-to-https redirect 
server {
       listen         80;
       server_name    localhost;
       return         301 https://$server_name$request_uri;
# resolves SSL & client SSL here
server {
    listen      443;
    server_name localhost;
    ssl on;
    ssl_certificate    <path to cert.pem>;
    ssl_certificate_key <path to cert.key>;
    ssl_client_certificate <path to CA authority to resolve client ssl - this is ca.crt>;
    ssl_verify_client on;
    # after ssl resolution forward to upstream cluster
    location /restService {
        proxy_pass http://appcluster/restService;
  • Thanks for your answer Dmitry, but this only configures SSL on the front end proxy and then talks HTTP to the backend/upstream application servers. We're essentially trying to do the opposite while also including a client certificate for authentication. – MrBlargityBlarg Aug 26 '15 at 13:54
  • Actually, we do handle client SSL with ssl_client_certificate and ssl_verify_client options. Just to make it clear - each of our client has client certificate which has to be validated with CA authority certificate (in Nginx) in order to process request. – Dmitry Savinkov Aug 26 '15 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.