我需要 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)。这是答案中您复制粘贴配置的实际解决方案。