Nginx 仅在特定位置验证客户端证书

Nginx 仅在特定位置验证客户端证书

我们使用 Nginx 作为 Web 应用服务器的反向代理。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 和 Android 上的 Chrome)最终都会提示用户提供客户端证书,无论用户访问网站的哪个页面。

我们如何让 Nginx 接受但并不真正关心除了我们所在/jsonrpc位置之外的任何地方的客户端证书?

答案1

为什么不尝试第二次服务器块?代码重复很糟糕,但有时不可避免。我假设 /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/;
  }
}

答案2

在寻找其他东西时偶然发现了这个问题。

也许我误解了这个问题:

但不应该跟随工作。

这有两个位置设置,但只有一个服务器设置。

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

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

相关内容