通过命令验证挂载在 Nginx Ingress 上的证书
在使用 Nginx Ingress 并挂载证书的情况下,当通过 curl
携带 Host
请求头访问 Ingress Controller 时,返回的证书为 Kubernetes Ingress Controller Fake Certificate
,而不是实际挂载的证书:
直接请求域名的时候,就可以获取到正确的证书:
从用户的角度来看,似乎这是 Ingress Controller 存在问题。其实不然,通过 SNI 可以很好理解这一点。
社区 issue:https://github.com/kubernetes/ingress-nginx/issues/6398
SNI
参考:https://www.cloudflare.com/zh-cn/learning/ssl/what-is-sni/
通常情况下,一台服务器可能托管多个网站,而不同网站使用的证书也可能不同。如果没有额外机制,服务器在 TLS/SSL 握手时无法确定客户端要访问的具体网站,从而可能返回错误的证书。
SNI(服务器名称指示)正是为了解决这一问题。作为 TLS 协议的扩展,SNI 允许客户端在握手阶段就指定目标域名,使服务器能够返回对应的正确证书。例如,即使多个网站共用同一 IP,SNI 也能确保用户访问时获得匹配的证书。
通过命令验证证书是否正确
上述通过 curl
携带 Host
请求头直接访问 IP 的方式,可以视为一种不符合规范的请求。原因是:
curl https://x.x.x.x
时,SNI 会被设置为x.x.x.x
;curl
并不会将Host
与 SNI 绑定,且Host
在 HTTP 层时才会被使用,当流量到达 HTTP 层时,已经完成了 TLS 握手。因此流量到达 Ingress Controller 时,它无法根据 SNI 判断应返回哪一个证书;- 结果就是返回默认证书;若未配置默认证书,则会返回
Kubernetes Ingress Controller Fake Certificate
。
所以,上述的 curl
命令不能够很好的验证挂载了证书的 Ingress(直接请求域名除外),而是需要显式指定域名而不是 IP:
1 | curl -kv https://<your_domain_name> --resolve <your_domain_name>:443:<your_nginx_ingress_controller_ip> |
openssl
通过 servername
参数,也能够很好的解决这个问题:
1 | openssl s_client -showcerts -connect <your_nginx_ingress_controller_ip>:443 -servername <your_domain_name> |
通过命令验证挂载在 Nginx Ingress 上的证书
https://warnerchen.github.io/2025/09/30/通过命令验证挂载在-Nginx-Ingress-上的证书/
install_url
to use ShareThis. Please set it in _config.yml
.