启用rewrite-target后, cert-manager HTTP01证书挑战无法访问



我们在GKE中使用ingress-nginx控制器公开了十几个服务。

为了在同一域名上正确路由流量,我们需要使用重写目标规则。

自2019年推出以来,这些服务在没有任何维护的情况下运行良好,直到最近;当cert-manager突然停止更新"让我们加密"证书时,我们"解决了"。这是通过暂时删除"tls"节,强制我们的客户端使用HTTP版本。

之后,我们删除了所有cert-manager试图从头开始设置的痕迹。

现在,cert-manager正在创建证书签名请求,生成一个acme http求解器pod并将其添加到入口,但是在访问其url时,我可以看到它返回一个空响应,而不是预期的令牌。

这与rewrite-target注释有关,它把acme挑战的路由弄得一团糟。最让我困惑的是,这以前是行得通的。(这是由前雇员设置的)

不幸的是,禁用rewrite-target不是一个选项,因为它会阻止路由正常工作。

使用dns01将无法工作,因为我们的ISP不支持编程式更改DNS记录。

是否有一种方法可以使此工作而不禁用重写目标?

注:以下是Github上报告的一些类似案例:

  • https://github.com/cert-manager/cert-manager/issues/2826
  • https://github.com/cert-manager/cert-manager/issues/286
  • https://github.com/cert-manager/cert-manager/issues/487

都没用

下面是我的ClusterIssuer

的定义
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: mail@domain.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx

请共享您正在使用的群集发行者或问题。

ingressClass

如果ingressClass字段时,cert-manager将创建新入口资源,以便将流量路由到acmesolverpod,负责响应ACME挑战验证请求。

Ref: https://cert-manager.io/v0.12-docs/configuration/acme/http01/#ingressclass

大多数情况下,如果DNS或HTTP工作正常,我们不会看到HTTP求解器挑战它并被删除。

另外,确保你的入口没有ssl重定向注释,这也可能是证书背后的一个原因。没有生成

您是否尝试检查证书管理器的其他对象,如订单和证书状态请求?kubectl describe challenge你得到404

吗?如果您连续尝试,可能会有机会达到让我们加密请求生成证书的速率限制。

故障排除:https://cert-manager.io/docs/faq/troubleshooting/#troubleshooting-a-failed-certificate-request

如果这对任何人有帮助的话,我花了一天的时间才解决了这个问题。

解决方案是创建一个不重写的备用入口。最初的入口是这样的。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: reward-ingress-https
namespace: prod
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: public
tls: 
- hosts: 
- home.myhome.net 
secretName: my-secret
rules:
- host: "home.myhome.net"
http:
paths:
- pathType: Prefix
path: /reward(/|$)(.*)
backend:
service:
name: reward-service
port:
number: 7777

为了确保这不会干扰letsencrypt发出的请求,我创建了另一个入口:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: acme-ingress
namespace: prod
annotations:
cert-manager.io/cluster-issuer: prod-issuer 
acme.cert-manager.io/http01-edit-in-place: "true" 
spec:
ingressClassName: public
rules:
- host: "home.myhome.net"
http:
paths:
- pathType: Prefix
path: /.well-known/acme-challenge/
backend:
service:
name: cert-manager
port:
number: 8089

配置http01类型的Issuer时,默认的serviceType为NodePort。这意味着,它甚至不会通过入口控制器。来自文档:

默认情况下,当您不设置HTTP01或将serviceType设置为空字符串时,将使用NodePort类型。通常不需要更改。

我不确定其余的设置看起来像什么,但http01导致acme服务器发出HTTP请求(不是https)。你需要确保你的nginx有http(80)的监听器。它遵循重定向,所以你可以监听http并将所有流量重定向到https,这是合法的和工作的。

cert-manager创建ingress资源用于验证。它引导交通进入临时隔离区。这个入口有它自己的一套规则,你可以使用这个设置来控制它。您可以尝试禁用或修改此资源上的重写目标。

我想尝试的另一件事是从集群内部访问这个URL(绕过入口nginx)。如果它能直接工作,那么这是一个入口/网络问题,否则就是别的问题。

请分享相关的nginx和cert-manager日志,这可能有助于调试或了解问题所在。

相关内容

  • 没有找到相关文章

最新更新