【问题标题】:Why is my k8s Nginx ingress controller serving two certificates (one of which is a Kubernetes Fake Certificate)?为什么我的 k8s Nginx 入口控制器提供两个证书(其中一个是 Kubernetes 假证书)?
【发布时间】:2021-05-08 11:50:04
【问题描述】:

我们正在 Azure 上运行 AKS Kubernetes 集群。我正在使用“NGINX Ingress Controller”和“cert-manager”进行路由和证书生成(通过 Let's Encrypt)。我遵循了 Microsoft 文档中的基本设置建议:https://docs.microsoft.com/en-us/azure/aks/ingress-tls

当在网络浏览器中访问我们的页面时,我们一开始并没有发现任何异常 - HTTPS 工作正常。浏览器可以验证 Let's Encrypt 证书。但是,我们后来注意到入口控制器实际上提供了两个证书(其中一个有一个通用名称:“Kubernetes Ingress Controller Fake Certificate”,另一个名称:“ingress.local”):https://www.ssllabs.com/ssltest/analyze.html?d=test-aks-ingress.switzerlandnorth.cloudapp.azure.com&hideResults=on

长话短说 - 昨天,我尝试了各种方法,从重新安装 Nginx-ingress 和 cert-manager 到从头开始启动新的 Azure Kubernetes 服务,但每次都遇到同样的情况。

我已经阅读了许多遇到类似问题的人的讨论。通常,它们有点不同,因为它们实际上根本看不到有效的证书。我确认我们正在使用生产版 Let's Encrypt ClusterIssuer

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ***@***
    privateKeySecretRef:
      name: letsencrypt
    solvers:
    - http01:
        ingress:
          class: nginx
          podTemplate:
            spec:
              nodeSelector:
                "kubernetes.io/os": linux

我还使用测试入口创建了一个新的测试应用:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
    cert-manager.io/cluster-issuer: letsencrypt
spec:
  tls:
  - hosts:
    - test-aks-ingress.switzerlandnorth.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: test-aks-ingress.switzerlandnorth.cloudapp.azure.com
    http:
      paths:
      - backend:
          serviceName: aks-helloworld-one
          servicePort: 80
        path: /hello-world-one(/|$)(.*)

据我了解,secret 对于之前报告过此问题的人来说通常存在一些问题。这里我假设ClusterIssuer会生成相关证书并将其存储在自动生成的tls-secret中:

Name:         tls-secret                                                                       
Namespace:    test                                                                             
Labels:       <none>                                                                           
Annotations:  cert-manager.io/alt-names: test-aks-ingress.switzerlandnorth.cloudapp.azure.com  
              cert-manager.io/certificate-name: tls-secret                                     
              cert-manager.io/common-name: test-aks-ingress.switzerlandnorth.cloudapp.azure.com
              cert-manager.io/ip-sans:                                                         
              cert-manager.io/issuer-group: cert-manager.io                                    
              cert-manager.io/issuer-kind: ClusterIssuer                                       
              cert-manager.io/issuer-name: letsencrypt                                         
              cert-manager.io/uri-sans:                                                        
                                                                                               
Type:  kubernetes.io/tls                                                                       
                                                                                               
Data                                                                                           
====                                                                                           
tls.crt:  3530 bytes                                                                           
tls.key:  1675 bytes  

也许我仍然对这里起作用的不同秘密/证书感到困惑。 cert-managercert-manager 命名空间中运行并在那里创建一个 letsencrypt 秘密,而我的测试设置在 test 命名空间中运行其他所有内容(包括入口控制器)。

[更新] 但这里的实际问题是什么?一切都在普通浏览器中“正常工作”,对吧?不幸的是,真正的问题是连接不适用于可能不支持 SNI 的特定客户端应用程序。

有没有办法不使用默认证书?我将如何更改此处的配置以默认提供“Let's Encrypt”签名证书 - 这可能吗?

【问题讨论】:

    标签: azure ssl kubernetes nginx-ingress cert-manager


    【解决方案1】:

    这是预期的行为。默认情况下,Ingress 控制器创建带有 CN 的自签名证书,表明它是假的。这在请求与 Ingress 中定义的规则不匹配时使用。因此,当我们从浏览器访问此 URL 时,它会返回正确的证书,但 openssl s_client 没有 servername 字段,它与 Ingress 中定义的规则不匹配,并转到默认后端并返回自签名证书。

    您还可以为 Ingress 指定默认证书。详情请参考https://github.com/kubernetes/ingress-nginx/issues/4674

    【讨论】:

    猜你喜欢
    • 2022-10-24
    • 2021-07-14
    • 2018-03-25
    • 2019-08-02
    • 1970-01-01
    • 2021-10-30
    • 2020-12-18
    • 2017-09-16
    • 1970-01-01
    相关资源
    最近更新 更多