如何在一个虚拟服务器上使用 ssl_verify_client=ON 而在另一个虚拟服务器上使用 ssl_verify_client=OFF?

如何在一个虚拟服务器上使用 ssl_verify_client=ON 而在另一个虚拟服务器上使用 ssl_verify_client=OFF?

我想强制对我的虚拟主机之一进行 SSL 客户端验证。但是尝试从中获取某些内容时出现“未发送所需 SSL 证书”错误。

这是我的测试配置:

# defaults                                                                                                                                                                    
ssl_certificate /etc/certs/server.cer;                                                                                                                                 
ssl_certificate_key /etc/certs/privkey-server.pem;                                                                                                                     
ssl_client_certificate /etc/certs/allcas.pem;                                                                                                                                 

server {                                                                                                                                                                      
    listen 1443 ssl;                                                                                                                                                          
    server_name server1.example.com;                                                                                                                                          
    root /tmp/root/server1;                                                                                                                                                   

    ssl_verify_client off;                                                                                                                                                    
}                                                                                                                                                                             

server {                                                                                                                                                                      
    listen 1443 ssl;                                                                                                                                                          
    server_name server2.example.com;                                                                                                                                          
    root /tmp/root/server2;                                                                                                                                                   

    ssl_verify_client on;                                                                                                                                                     
} 

第一个服务器回复 200 http 代码,但第二个服务器返回“400 错误请求,未发送所需的 SSL 证书,nginx/1.0.4”。

可能,在同一个 IP 上使用 ssl_verify_client 是不可能实现的?我应该将这些服务器绑定到不同的 IP,这样能解决我的问题吗?

答案1

我遇到了类似的问题,但希望区分ssl_verify_clients服务器块内的位置块,而不是服务器块之间的位置块。 您可以通过将默认的 SSL 配置内容移动到两个服务器中来解决问题(复制它,当然,或者将它们全部放在一个服务器块中,接受多个子域并使用位置)。

对于基于位置的解决方案,看起来如下所示。使用

ssl_verify_client optional;

在服务器块中,并在各个位置使用 if 语句,例如:

if ($ssl_client_verify != SUCCESS) { return 403; }

我需要这样做才能授予管理员对 webapp 的访问权限,但仍然允许来自 github 的 webhook,而无需向 github 提供客户端 ssl 证书。

答案2

ssl_verify_client如果您想在相同的 IP 地址和端口上拥有多个基于名称的虚拟主机(使用 SNI),但这些主机的设置不同,则需要至少升级到 nginx >= 1.0.9。

在较旧的 nginx 版本中,ssl_verify_client默认虚拟主机的设置用于同一 IP+端口组合上的所有其他基于名称的虚拟主机。其他一些 SSL 选项(ssl_verify_depthssl_prefer_server_ciphers)也以相同的方式处理。如果您确实无法升级,使用单独的 IP 或端口可能是一种解决方法。

来自 nginx 的注释变更日志对于 1.0.9:

*) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and
   "ssl_prefer_server_ciphers" directives might work incorrectly if SNI
   was used.

nginx源码相关改动: r4034在后备箱里,r4246在 1.0 分支中。

答案3

您是否已在浏览器中加载了由 CA“/etc/certs/allcas.pem”签名的客户端证书(PKCS12 格式)?在 Firefox 中,您可以通过进入“首选项”->“高级”->“加密”->“查看证书”->“您的证书”来检查您的客户端证书。

参数“ssl_verify_client”的默认值为“off”。如果 SSL 客户端证书不是强制性的,也可以使用值“optional”。

答案4

我遇到了同样的问题并找到了解决方案。

请尝试default_server为第二台服务器添加标志

listen 443 ssl default_server;

相关内容