Nginx – Why did the format of nginx $ssl_client_i_dn suddenly change

nginxsslssl-certificate

We are using client side certificates for authenticating one of our customers.

Our setup is this: We have nginx in front of a Django application. In our nginx config, we have the required parameters to get the actual client-side-certificate verification to work (ssl_client_certificate, ssl_verify_client etc) and

uwsgi_param X-Client-Verify $ssl_client_verify;
uwsgi_param X-Client-DN $ssl_client_s_dn;
uwsgi_param X-SSL-Issuer $ssl_client_i_dn;

which means that we get the values of those variables into our Django app. The Django app then uses this information to identify which user is connecting and authorize them.

We have successfully been using this for several months without any issue when suddenly we started getting reports about people not being able to log in using the certificates. It turned out that the format of the $ssl_client_s_dn and $ssl_client_i_dn values had changed, from a slash-separated format:

 /C=SE/O=Some organziation/CN=Some CA

to a comma-separated format:

CN=Some CA,O=Some organization,C=SE

Solving this was easy, but I don't understand why. So my questions is really:

  1. From where does the value of $ssl_client_s_dn come? Is it set by nginx? The client?
  2. Is there any documentation/specification of the format this value can have and does it have a name?

Best Answer

They changed because nginx changed them in release 1.11.6. As shown in the changelog:

    *) Change: format of the $ssl_client_s_dn and $ssl_client_i_dn variables
       has been changed to follow RFC 2253 (RFC 4514); values in the old
       format are available in the $ssl_client_s_dn_legacy and
       $ssl_client_i_dn_legacy variables.

If you want to avoid this sort of thing, you should stick to stable releases, rather than unstable mainline releases. Either way, you should test first before blindly upgrading production.