阻止Nginx Ingress为未匹配Ingress的主机提供无效证书
核心问题在于HTTPS请求的TLS握手优先级高于Nginx的请求处理逻辑:当请求的嵌套子域名(如super.fake.dev.domain1.com)没有匹配的TLS证书时,Nginx会使用默认证书(或第一个找到的证书)完成握手,导致浏览器提示证书不匹配错误,根本无法进入重定向逻辑。而HTTP请求无需握手,所以重定向正常。
以下是两种可行的解决方案:
方案1:默认TLS证书 + Catch-All Ingress重定向
这是最直接的实现方式,通过配置默认证书确保握手正常,再用通用Ingress规则处理重定向。
步骤1:配置Ingress Controller默认SSL证书
给ingress-nginx控制器指定一个最宽泛的泛域名证书(比如你的*.domain1.com证书),让所有未匹配具体TLS配置的HTTPS请求都用这个证书完成握手。
- 如果用Helm部署,修改
values.yaml:controller: extraArgs: default-ssl-certificate: "你的命名空间/你的泛域名证书Secret名称" - 如果是手动部署的Deployment,在容器启动参数中添加:
--default-ssl-certificate=你的命名空间/你的泛域名证书Secret名称
步骤2:创建可用的Catch-All Ingress
替换你之前的无效Ingress,用一个存在的" dummy服务"配合重定向配置:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: default-redirect annotations: nginx.ingress.kubernetes.io/server-snippet: | return 307 https://google.com; spec: ingressClassName: nginx rules: - host: "*.domain1.com" http: paths: - path: / pathType: Prefix backend: service: name: dummy-service port: number: 80 tls: - hosts: - "*.domain1.com" secretName: 你的泛域名证书Secret名称
步骤3:创建Dummy服务
需要一个存在的服务(无需后端Pod)来避免503错误:
apiVersion: v1 kind: Service metadata: name: dummy-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: dummy # 不需要对应任何Pod
这样所有匹配*.domain1.com的请求(包括嵌套子域名)都会进入这个规则,在到达后端前直接执行重定向。
方案2:Lua脚本动态匹配证书(进阶)
如果需要给不同层级的子域名匹配对应证书(比如*.dev.domain1.com用专属证书),可以用Lua脚本动态选择证书,确保握手时证书完全匹配。
步骤1:配置Lua证书选择逻辑
在ingress-nginx的ConfigMap中添加Lua脚本:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-configuration namespace: ingress-nginx data: ssl_certificate_by_lua_block: | local host = ngx.var.host -- 根据主机后缀匹配对应证书 if host:match(".*%.dev%.domain1%.com$") then ngx.var.ssl_certificate = "/etc/nginx/secrets/你的命名空间/tls-wildcard-dev-domain1/tls.crt" ngx.var.ssl_certificate_key = "/etc/nginx/secrets/你的命名空间/tls-wildcard-dev-domain1/tls.key" else ngx.var.ssl_certificate = "/etc/nginx/secrets/你的命名空间/tls-wildcard-domain1/tls.crt" ngx.var.ssl_certificate_key = "/etc/nginx/secrets/你的命名空间/tls-wildcard-domain1/tls.key" end
步骤2:复用方案1的Catch-All Ingress
配置完Lua脚本后,用方案1中的Ingress规则处理重定向即可,此时每个子域名都会用匹配的证书完成握手,再执行重定向。
不推荐DNS层面解决的原因
如果在Azure DNS中把未定义的子域名直接指向谷歌,会导致未来所有新增的子域名都直接跳转到谷歌,完全失去Kubernetes集群管理这些域名的灵活性,因此不建议采用这种方式。
内容的提问来源于stack exchange,提问作者theadzik

