Nginx проверяет клиентские сертификаты только в определенном месте

14

Мы используем Nginx в качестве обратного прокси-сервера для нашего сервера веб-приложений. Nginx обрабатывает наш SSL и тому подобное, но в остальном он действует как обратный прокси.

Мы хотим требовать действительный сертификат клиента для запросов, /jsonrpcно не требовать их где-либо еще. Лучший способ, который мы нашли, это

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

Это прекрасно работает для большинства браузеров, но некоторые браузеры, такие как Safari и Chrome-на-Android, в конечном итоге предлагают пользователю предоставить сертификат клиента независимо от того, где он находится на веб-сайте.

Как заставить Nginx принимать, но не заботиться о сертификате клиента везде, кроме нашего /jsonrpcместоположения?

Эли Кортрайт
источник

Ответы:

8

Почему бы не попробовать второй блок сервера вместо этого? Дублирование кода это плохо, но иногда неизбежно. Я предполагаю, что / jsonrpc представляет API, поэтому он может использовать свой собственный поддомен, если он еще не используется:

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/;
  }
}
Анатолий
источник
Это то, что мы, вероятно, в конечном итоге сделаем, если не сможем найти способ поместить правильную конфигурацию в один serverблок. У нас не было такой же проблемы при использовании Apache, поэтому я надеялся, что есть некоторые настройки, которые будут работать здесь.
Эли Кортрайт,
1
@EliCourtwright Я знаю, что этот вопрос был давно, но вы когда-нибудь находили решение лучше, чем два серверных блока?
Н Джонс
2
@NJones: к сожалению нет, это то, что мы должны были сделать.
Эли Кортрайт
Что если все должно отвечать за один и тот же домен www.example.com? Может ли такой подход все еще работать?
Freedom_Ben