为什么我的 k8s Nginx 入口控制器提供两个证书(其中一个是 Kubernetes 假证书)?
Why is my k8s Nginx ingress controller serving two certificates (one of which is a Kubernetes Fake Certificate)?
我们是 运行 Azure 上的 AKS Kubernetes 集群。我正在使用“NGINX Ingress Controller" and "cert-manager" for routing and certificate generation (through Let's Encrypt). I followed the basic setup advice from the Microsoft documentation: 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
我还使用 test-ingress 创建了一个新的测试应用程序:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
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-manager
在 cert-manager
命名空间中运行并在那里创建一个 letsencrypt
秘密,而我的测试设置是 运行 test
命名空间中的所有其他内容(包括入口控制器)。
[更新]
但这里的实际问题是什么?一切都在普通浏览器中“正常工作”,对吗?不幸的是,真正的问题是连接不适用于可能不支持 SNI 的特定客户端应用程序。
有没有办法不用默认证书?我将如何更改此处的配置以默认提供“让我们加密”签名证书 - 这可能吗?
这是预期的行为。默认情况下,Ingress 控制器会创建带有 CN 的自签名证书,表明它是假的。当请求与 Ingress 中定义的规则不匹配时使用。因此,当我们从浏览器访问此 URL 时,它 returns 正确的证书但是 openssl s_client 没有 servername 字段,它不匹配 Ingress 中定义的规则并转到默认后端和 returns 自签名证书。
您还可以为 Ingress 指定默认证书。请参阅 https://github.com/kubernetes/ingress-nginx/issues/4674 了解更多详情。
我们是 运行 Azure 上的 AKS Kubernetes 集群。我正在使用“NGINX Ingress Controller" and "cert-manager" for routing and certificate generation (through Let's Encrypt). I followed the basic setup advice from the Microsoft documentation: 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
我还使用 test-ingress 创建了一个新的测试应用程序:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
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-manager
在 cert-manager
命名空间中运行并在那里创建一个 letsencrypt
秘密,而我的测试设置是 运行 test
命名空间中的所有其他内容(包括入口控制器)。
[更新] 但这里的实际问题是什么?一切都在普通浏览器中“正常工作”,对吗?不幸的是,真正的问题是连接不适用于可能不支持 SNI 的特定客户端应用程序。
有没有办法不用默认证书?我将如何更改此处的配置以默认提供“让我们加密”签名证书 - 这可能吗?
这是预期的行为。默认情况下,Ingress 控制器会创建带有 CN 的自签名证书,表明它是假的。当请求与 Ingress 中定义的规则不匹配时使用。因此,当我们从浏览器访问此 URL 时,它 returns 正确的证书但是 openssl s_client 没有 servername 字段,它不匹配 Ingress 中定义的规则并转到默认后端和 returns 自签名证书。
您还可以为 Ingress 指定默认证书。请参阅 https://github.com/kubernetes/ingress-nginx/issues/4674 了解更多详情。