On our setup we want to promt a user for a client ssl certificate. All certificates are issued by StartSSL.

The problem is that even though ssl_verify_client on; is set 'on', the website / browser does not prompt for the certificate.

How can I get NGINX to prompt for the client certificate?

This is related to this unanswered question.

nginx version: nginx/1.9.11

Our config for the server:

server {
  listen 80;
  server_name example.com;
  # enforce https
  return 301 https://$server_name$request_uri;
  }

server {
  listen 443 ssl http2;
  server_name example.com;

  # strenghen ssl security
  ssl_certificate SOMECERT;
  ssl_certificate_key SOMEKEY;
  ssl_client_certificate SOMECERT;
  ssl_verify_client on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;
  ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
  ssl_dhparam SOMEPARAM;

  # allow longer uri
  client_header_buffer_size 256k;
  large_client_header_buffers 8 1024k;

  # Add headers to serve security related headers
  add_header Strict-Transport-Security "max-age=15768000; preload;";
  add_header X-Content-Type-Options nosniff;
  add_header X-Frame-Options "SAMEORIGIN";
  add_header X-XSS-Protection "1; mode=block";
  add_header X-Robots-Tag none;

  root /var/www/SOMEFOLDER;
  index index.php;

  client_max_body_size 1G;
  client_body_timeout 600s;

  # only allow clients with valid client ssl certificate
  if ($ssl_client_verify != SUCCESS) {
   return 403;
}

  location ~* \.php$ {
    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_read_timeout 600;
  }
 }

I was struggling with the same issue a couple days ago, and finally fixed my issue today. My problem was that I installed the client certificate improperly in the Chrome.

I followed these steps to setup mutual TLS auth and got cURL to work without any issues initially: http://nategood.com/client-side-certificate-authentication-in-ngi

Then I proceeded install the client.crt in my browser for client authentication. This was where I went wrong. The signed X.509 certificate itself does not contain the private key of the client, and hence the browser does not recognize it as a valid means of client authentication. The client must know the private key to prove that it owns the X.509 certificate that it is providing to the server.

So I generated the PKCS12 file that combined the X.509 client certificate and the private key and installed it in the browser. I then restarted the browser and the nginx server. This time, Chrome prompted me to select the configured PKCS12 profile, and IE picked it up automagically.

Here is an example of how to create a PKCS12 profile: https://www.tbs-certificates.co.uk/FAQ/en/288.html

Firefox seems to be in it's own weird world because it couldn't import the same PKCS12 profile that worked with IE and Chrome.

Hope this helps.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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