Nginx 多服务器阻止 SSL 和非 SSL

Nginx 多服务器阻止 SSL 和非 SSL

我需要 nginx.conf 方面的帮助。我需要使用客户端证书身份验证来保护从 /devices 开始的资源。其他资源通过 https 传输,但不需要客户端证书。

我使用存储库在 ubuntu 16.04 上安装了 nginx。然后我在 /etc/nginx/conf.d/ 中创建了一个名为 dozee.conf 的文件,并粘贴了 serverfault Q&A 中的内容 (https://serverfault.com/a/721704/80340) 并按要求进行修改。

dozee.conf 中的配置如下

server {
  listen       *:443 ssl;
  server_name localhost;

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

  ssl_verify_client on;

  location /device {
    proxy_pass          http://localhost:8080/device;
    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/ca.crt;

  ssl_verify_client off;

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

我在这里面临的问题是 nginx 的行为受第二个服务器块控制。

如果我将ssl_verify_client off;第二个服务器块更改为ssl_verify_client on;两个路径//device开始询问客户端证书。

如果我保留ssl_verify_client它们,则off它们都不需要客户端证书。

我在这里做错了什么?

答案1

您的第一个server块仅匹配类似 的请求https://localhost/some/url。所有其他请求均由第二个server块处理。

但是,nginx 可能无法用于您想要的用例。初始化 TLS 连接时,nginx 没有关于上层 HTTP 请求的信息来决定是否需要来自客户端的客户端证书。它只能根据虚拟主机名信息来执行此操作,该信息在 TLS 连接设置时通过 SNI 传递。

在 Apache 中,可以根据 URL 路径强制进行 TLS 重新协商,然后 Apache 会请求客户端证书。我在 nginx 中没有找到类似的选项。

因此,您使用 nginx 的唯一选择可能是为您的设备使用另一个虚拟主机(例如 devices.example.com)。这是答案中您复制粘贴配置的实际解决方案。

相关内容