Nginx verifica los certificados del cliente solo en una ubicación particular

14

Usamos Nginx como proxy inverso de nuestro servidor de aplicaciones web. Nginx maneja nuestro SSL y tal, pero por lo demás solo actúa como un proxy inverso.

Queremos exigir un certificado de cliente válido para solicitudes, /jsonrpcpero no exigirlas en ningún otro lugar. La mejor manera que hemos encontrado es

server {
  listen       *:443 ssl;

  ssl on;
  ssl_certificate         /etc/nginx/server.crt;
  ssl_certificate_key     /etc/nginx/server.key;
  ssl_client_certificate  /etc/nginx/client-ca.crt;

  ssl_verify_client optional;

  location /jsonrpc {
    if ($ssl_client_verify != "SUCCESS") { return 403; }

    proxy_pass          http://localhost:8282/jsonrpc-api;
    proxy_read_timeout  90;
    proxy_redirect      http://localhost/ $scheme://$host:$server_port/;
  }
}

Esto funciona bien para la mayoría de los navegadores, pero algunos navegadores como Safari y Chrome-on-Android terminan incitando al usuario a proporcionar un certificado de cliente sin importar en qué lugar del sitio web vayan.

¿Cómo hacemos para que Nginx acepte pero no realmente se preocupe por un certificado de cliente en todas partes excepto en nuestra /jsonrpcubicación?

Eli Courtwright
fuente

Respuestas:

8

¿Por qué no probar el segundo bloqueo del servidor ? La duplicación de código es mala pero a veces inevitable. Supongo que / jsonrpc representa una API para que pueda usar su propio subdominio si aún no lo usa:

server {
  listen       *:443 ssl;
  server_name api.example.com;

  ssl on;
  ssl_certificate         /etc/nginx/server.crt;
  ssl_certificate_key     /etc/nginx/server.key;
  ssl_client_certificate  /etc/nginx/client-ca.crt;

  ssl_verify_client on;

  location =/jsonrpc {
    proxy_pass          http://localhost:8282/jsonrpc-api;
    proxy_read_timeout  90;
    proxy_redirect      http://localhost/ $scheme://$host:$server_port/;
  }
}

server {
  listen       *:443 ssl;

  ssl on;
  ssl_certificate         /etc/nginx/server.crt;
  ssl_certificate_key     /etc/nginx/server.key;
  ssl_client_certificate  /etc/nginx/client-ca.crt;

  ssl_verify_client off;

  location / {
    proxy_pass          http://localhost:8282/;
    proxy_read_timeout  90;
    proxy_redirect      http://localhost/ $scheme://$host:$server_port/;
  }
}
Anatoly
fuente
Esto es lo que probablemente terminaremos haciendo si no podemos encontrar una manera de poner la configuración correcta en el mismo serverbloque. No hemos tenido este mismo problema al usar Apache, por lo que esperaba que hubiera alguna configuración que funcionara aquí.
Eli Courtwright
1
@EliCourtwright Sé que esta pregunta fue hace mucho tiempo, pero ¿alguna vez encontraste una solución mejor que dos bloques de servidores?
N Jones
2
@NJones: desafortunadamente no, eso es con lo que tuvimos que ir.
Eli Courtwright
¿Qué pasa si todo debe responder para el mismo dominio www.example.com? ¿Puede un enfoque como este seguir funcionando?
Freedom_Ben