Problem with proxy_set_header $ssl_client_cert

Hello,

I am having an issue while verifying client SSL certificates. Everything
works fine until I attempt to forward the cert onto the upstream.

Once I add a line similar to the following in my location block, all
requests become an error 400 Bad Request.

proxy_set_header X-SSL-Client_Cert $ssl_client_cert;
(I’ve also tried $ssl_client_raw_cert, but the docs say
“[$ssl_client_cert]
is intended for the use in the proxy_set_header directive;”

Here is my entire location block:
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}

Originally I was using add_header X-SSL-Client-Cert in the server block,
which did not throw a 400, but my upstream app was not seeing the
header.

Once I remove the proxy_set_header line, the server works as expected:
requests with a valid cert get passed through while unauthenticated
requests
get a 403. (This is done by checking $ssl_client_verify).

Am I missing something obvious? Any help would be very appreciated.
Thank
you.

Posted at Nginx Forum:

Hello!

On Sun, Feb 24, 2013 at 09:41:38AM -0500, jstrybis wrote:

Originally I was using add_header X-SSL-Client-Cert in the server block,
which did not throw a 400, but my upstream app was not seeing the header.

Once I remove the proxy_set_header line, the server works as expected:
requests with a valid cert get passed through while unauthenticated requests
get a 403. (This is done by checking $ssl_client_verify).

Am I missing something obvious? Any help would be very appreciated. Thank
you.

The $ssl_client_cert variable abuses header continuation, and this
doesn’t work with many http servers (including nginx itself).
There should be more portable way to pass client certificate to an
upstream server.


Maxim D.

The $ssl_client_cert variable abuses header continuation, and this
doesn’t work with many http servers (including nginx itself).

Noticed that with spray-can.

There should be more portable way to pass client certificate to an
upstream server.

Is there already, or is there one in plans? Any known workarounds?
Encoding
and decoding the $ssl_client_cert somehow? (I’m really new to nginx.)


Lynoure Braakman

Posted at Nginx Forum:

On 25 Feb2013, at 18:37 , Lynoure [email protected] wrote:

The $ssl_client_cert variable abuses header continuation, and this
doesn’t work with many http servers (including nginx itself).

Noticed that with spray-can.

There should be more portable way to pass client certificate to an
upstream server.

Is there already, or is there one in plans? Any known workarounds? Encoding
and decoding the $ssl_client_cert somehow? (I’m really new to nginx.)

You could hack ngx_ssl_get_certificate() function to get certificate in
one line,
or there is an ugly, but possible way to remove limited number of
newline
characters from variable with map directive:

map $ssl_client_raw_cert $a {
“~^(-.-\n)(?<1st>[^\n]+)\n((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?

[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?((?[^\n]+)\n)?(-.-)$”
$1st;
}

server {
location / {
proxy_set_header X-cert
$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$t$v$u$w$x$y$z;
proxy_pass http://localhost:8000;
}
}

Example works for up to 26 line certificate, you could extend it to
reasonable number of lines.

Thank you Sergey, this workaround suffices for us for now.

Posted at Nginx Forum:

Thanks for your reply. My application does not require the entire
certificate, so I am just forwarding $ssl_client_s_dn in a custom header
without any problems.

Posted at Nginx Forum: