Nginx vérifiant les certificats clients uniquement sur un emplacement particulier

14

Nous utilisons Nginx comme proxy inverse de notre serveur d'applications Web. Nginx gère notre SSL et autres mais agit simplement comme un proxy inverse.

Nous voulons exiger un certificat client valide pour les demandes, /jsonrpcmais pas les exiger ailleurs. La meilleure façon que nous avons trouvée est de

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/;
  }
}

Cela fonctionne très bien pour la plupart des navigateurs, mais certains navigateurs tels que Safari et Chrome sur Android finissent par inviter l'utilisateur à fournir un certificat client, peu importe où sur le site Web ils vont.

Comment pouvons-nous amener Nginx à accepter mais sans vraiment se soucier d'un certificat client partout sauf à notre /jsonrpcemplacement?

Eli Courtwright
la source

Réponses:

8

Pourquoi ne pas essayer le deuxième bloc serveur à la place? La duplication de code est mauvaise mais parfois inévitable. Je suppose que / jsonrpc représente une API afin qu'il puisse utiliser son propre sous-domaine s'il ne l'utilise pas déjà:

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
la source
C'est ce que nous finirons probablement par faire si nous ne pouvons pas trouver un moyen de mettre la bonne configuration dans le même serverbloc. Nous n'avons pas eu ce même problème lors de l'utilisation d'Apache, alors j'espérais qu'il y aurait un paramètre qui fonctionnerait ici.
Eli Courtwright
1
@EliCourtwright Je sais que cette question remonte à longtemps, mais avez-vous déjà trouvé une solution meilleure que deux blocs serveur?
N Jones
2
@NJones: malheureusement non, c'est ce que nous devions faire.
Eli Courtwright
Et si tout devait répondre pour le même domaine www.example.com? Une telle approche peut-elle encore fonctionner?
Freedom_Ben