You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

阻止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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 16:05:38