Nginx weryfikuje certyfikaty klienta tylko w określonej lokalizacji

14

Używamy Nginx jako odwrotnego proxy do naszego serwera aplikacji WWW. Nginx obsługuje nasz protokół SSL, ale w przeciwnym razie działa tylko jako odwrotny serwer proxy.

Chcemy wymagać ważnego certyfikatu klienta dla żądań, /jsonrpcale nie wymagamy ich nigdzie indziej. Najlepszym sposobem, jaki znaleźliśmy, jest

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

Działa to dobrze w przypadku większości przeglądarek, ale niektóre przeglądarki, takie jak Safari i Chrome na Androida, ostatecznie wyświetlają monit o podanie certyfikatu klienta bez względu na to, w której witrynie się znajdują.

Jak sprawić, by Nginx akceptował certyfikat klienta, ale nie dbał o to wszędzie, z wyjątkiem naszej /jsonrpclokalizacji?

Eli Courtwright
źródło

Odpowiedzi:

8

Dlaczego nie spróbować zamiast tego drugiego bloku serwera ? Duplikacja kodu jest zła, ale czasem nieunikniona. Zakładam, że / jsonrpc reprezentuje API, więc może używać własnej subdomeny, jeśli jeszcze go nie używa:

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/;
  }
}
Anatolij
źródło
To prawdopodobnie zrobimy, jeśli nie będziemy w stanie znaleźć sposobu na umieszczenie właściwej konfiguracji w jednym serverbloku. Nie mieliśmy tego samego problemu podczas używania Apache, więc miałem nadzieję, że będzie jakieś ustawienie, które będzie działać tutaj.
Eli Courtwright,
1
@EliCourtwright Wiem, że to pytanie było dawno temu, ale czy kiedykolwiek znalazłeś rozwiązanie lepsze niż dwa bloki serwerów?
N Jones
2
@NJones: niestety nie, z tym musieliśmy iść.
Eli Courtwright
Co jeśli wszystko musi odpowiadać dla tej samej domeny www.example.com? Czy takie podejście może nadal działać?
Freedom_Ben