我想强制对我的虚拟主机之一进行 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_depth
、ssl_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.
答案3
您是否已在浏览器中加载了由 CA“/etc/certs/allcas.pem”签名的客户端证书(PKCS12 格式)?在 Firefox 中,您可以通过进入“首选项”->“高级”->“加密”->“查看证书”->“您的证书”来检查您的客户端证书。
参数“ssl_verify_client”的默认值为“off”。如果 SSL 客户端证书不是强制性的,也可以使用值“optional”。
答案4
我遇到了同样的问题并找到了解决方案。
请尝试default_server
为第二台服务器添加标志
listen 443 ssl default_server;