Trouble with ssl_verify_client option

Maxim Dounin mdounin at mdounin.ru
Sat Nov 6 05:06:53 MSK 2010


Hello!

On Fri, Nov 05, 2010 at 11:28:33PM +0100, Luit van Drongelen wrote:

> On Fri, Nov 5, 2010 at 1:14 AM, Luit van Drongelen <me at luitvd.net> wrote:
> > Am I expecting the wrong things here, or is server-specific
> > ssl_verify_client setting broken here?
> 
> My case further simplified:
> http { server { listen: 443; ssl on; ssl_verify_client optional;
> certificate and key stuffs; }} # DOESN'T WORK
> vs.
> http { ssl_verify_client: optional; certificate and key stuffs;
> server{listen: 443; ssl: on; }} # WORKS FINE
> 
> This is the same for ssl_verify_client: on, where the "doesn't work"
> means it'll just stop any request.
> So are my expectations of ssl_verify_client wrong, or would this be a bug?

Directive ssl_verify_client works correctly only on 
per-ssl-connection basis (as well as ssl_certificate) as it 
requires client certificate request during ssl handshake.

This means that (unless you have SNI[1] enabled) if you have multiple 
ssl server{}'s listening on the same ip:port pair - you have to 
specify ssl_verify_client identical (or at least somewhat synced) 
for all servers on the ip:port pair in question.

[1] http://en.wikipedia.org/wiki/Server_Name_Indication

Your simplified cases should both work ok (and they works ok here, 
and I doubt you actually tested them).  Though this one will cause 
troubles without SNI:

http {
    server {
       listen 443;
       server_name  test1.example.com;
       ssl on;
       ...
   }

   server {
       listen 443;
       server_name  test2.example.com;
       ssl on;
       ssl_verify_client on;
       ...
   }
}

Default server for port 443 is first one, test1.example.com, and 
all ssl connections will be established without certificate 
request (and with server certificate specified in this server - 
though this is probably obvious).  As soon as request to 
test2.example.com comes in - nginx will select second server, try 
to check client's certificate and return 400 as there is no client 
certificate.

Obvious solutions are:

1. Use separate ip's for separate servers.

2. Keep ssl_verify_client at least "optional" in the default 
server for ip:port pair if you want client certificates to be 
available for servers on the ip:port pair in question.  Note that 
this may cause unnecessary "select certificate to submit" dialogs 
in browser.

3. Use SNI.  As long as you care about IE users under Windows XP - 
this probably isn't an option.

Maxim Dounin



More information about the nginx mailing list