繁体   English   中英

Lets-encrypt Ingress - NewOrder 请求没有包含足够短的 SAN 以适应 CN

[英]Lets-encrypt Ingress - NewOrder request did not include a SAN short enough to fit in CN

我们在 AWS 中有一个 EKS 集群。 使用以下命令指向我们的 eks 集群后,

aws eks --region us-east-1 update-kubeconfig --name cluster-name

然后我们使用以下 shell 脚本为该集群部署了 nginx。

file: 1_cert_manager.sh

###Nginx
# This script install nginx and cert manager using helm install..

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install nginx-ingress ingress-nginx/ingress-nginx \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux

sleep 60
kubectl get service nginx-ingress-ingress-nginx-controller


###########
#Cert-manager
##########


# Label the cert-manager namespace to disable resource validation
kubectl label  cert-manager.io/disable-validation=true

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# Install the cert-manager Helm chart
helm install \
  cert-manager \
  --version v0.16.1 \
  --set installCRDs=true \
  --set nodeSelector."beta\.kubernetes\.io/os"=linux \
  jetstack/cert-manager

我们使用运行上述脚本

chmod +x ./1_cert_manager.sh

sh ./1_cert_manager.sh

安装 nginx 后,我们可以在访问 AWS 负载均衡器中提供的 DNS 时看到 nginx 主页。

kubectl get services了负载均衡器的 DNS 地址。

该页面使用 http 加载。 为了启用对 https 的支持,我们安装了证书管理器。

我们已经安装了letsencrypt-issuer ClusterIssuer。

File: 2_cluster-issuer.yaml

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

我们已经使用以下命令安装了 Cluster issuer。

kubectl apply -f 2_cluster-issuer.yaml

然后我们安装了一个示例 hello world 服务。

file:3_service.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: console
spec:
  selector:
    matchLabels:
      app: console
      tier: console
      track: stable
  replicas: 1
  template:
    metadata:
      labels:
        app: console
        tier: console
        track: stable
    spec:
      containers:
        - name: console
          image: "gcr.io/google-samples/hello-go-gke:1.0"
          ports:
            - name: http
              containerPort: 80
---
---
apiVersion: v1
kind: Service
metadata:
  name: console
spec:
  selector:
    app: console
    tier: console
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

kubectl apply -f 3_service.yaml

我们有 2-3 个服务将在不同的端口上运行。 出于测试目的,我们只安装了一项服务。

该服务已成功安装,我们已使用kubectl get podskubectl get services进行了验证。

最后我们部署了入口 yaml 文件来提供主机详细信息和路由信息。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nandha-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-issuer
    nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    nginx.ingress.kubernetes.io/client-body-buffer-size: "16m"
    nginx.ingress.kubernetes.io/proxy-body-size: "16m"
    nginx.ingress.kubernetes.io/enable-modsecurity: "true"
spec:
  tls:
      - hosts:
        - a2e858295f1201234aab29d960a10bfa-41041144.us-east-1.elb.amazonaws.com
        secretName: tls-secret
  rules:
    - host: a2e858295f1201234aab29d960a10bfa-41041144.us-east-1.elb.amazonaws.com
      http:
        paths:
          - pathType: Prefix
            backend:
              service:
                name: console
                port:
                  number: 80
            path: /(.*)

kubectl apply -f 4_ingress.yaml

如果前面的命令成功执行,我们应该准备好我们的 tls-secret 证书。 (对于 GCP,它工作正常)。

我们调试使用

kubectl get certificates

kubectl describe certificates tls-secret

对于 describe 命令,我们收到以下错误,

无法创建订单:400 urn:ietf:params:acme:error:rejectedIdentifier:NewOrder 请求未包含足够短的 SAN 以适合 CN

当我们搜索错误时,我们发现问题出在 DNS 的长度上。 AWS DNS 的长度大于 64。

当前解决方法:我们为 AWS DNS url 创建了一个 CNAME 映射,我们在第 4 步中使用了该短映射 url,而不是实际 url。 到目前为止,这有效。 但是我们还需要为实际的 DNS 启用 SSL。

如何为 AWS DNS 值启用 SSL?

当我们启动 EKS 时,这 (a2e858295f1201234aab29d960a10bfa-41041144.us-east-1.elb.amazonaws.com) 是我们的主机。 目前我们的 EKS 已终止。

“AWS DNS 的长度大于 64。”

不,这不是问题。 每个 DNS 标签最多限制为 63 个字符(实际上是字节),而您的第一个标签长度为 42,所以没问题。 另一条规则是全名最多只能包含 255 个字符/字节,但实际上是 253。这对您的名字也可以。

问题出在其他地方,因为 LDAP/X520/certificate 参考说完整的 CN 必须小于 64,但它与 DNS 无关(CN 一开始通常是个人或组织名称,后来被劫持以放置 DNS 名称在那里,直到 SAN 扩展被写入(现在是默认设置),DV 证书的主题实际上不再相关,部分原因是这些限制;SAN 中的名称又名 dnsName 被定义为有一个最大值实现,但也定义为有效域名,因此在实践中,上述规则适用于每个标签 63/255 个总数)。

这就是您的问题所在。

现代基于主机的证书只需要一个适当的 SAN,CN 现在与浏览器无关。 因此,您需要在 SAN 中生成包含所有良好数据的证书,但在 CN 中生成另一个虚假数据。 这似乎是您所做的,但不确定是否理解。 该证书对 SAN 中的所有名称都有效。

有关想法,请参阅https://community.letsencrypt.org/t/a-certificate-for-a-63-character-domain/78870/6 基本上添加另一个名称作为名字,它更小并且您也可以控制,以便能够获得验证以颁发证书。

正如https://github.com/letsencrypt/boulder/issues/2093所解释的那样,真正的解决方案只是让 CA 摆脱 CN,但这似乎被其他地方的其他标准化工作所阻止。

同时,您还应该向您的云提供商寻求帮助。

在与云支持团队核实后,我们得到了以下回复。 他们建议创建自定义域映射并建议使用我们已经在做的。

DNS 是通过组合load balancer name + random string + region + 'elb.amazonaws.com'

如果我们能够从 helm 安装方式为负载均衡器提供自定义名称,我们就可以解决我们的问题。 目前我们正在尝试执行此步骤。

附上云支持团队的回复。

根据 RFC 5280 ( https://datatracker.ietf.org/doc/html/rfc5280 ),您在此步骤中输入的域名(技术上是通用名称)的长度不能超过 64 个八位字节(字符),包括时期。 您在下一步中提供的每个后续主题备用名称 (SAN) 的长度最多可达 253 个八位字节。

您遇到此错误,因为您的主机名 (a2e858295f1204618aab29d960a10bfa-41041143.us-east-1.elb.amazonaws.com ( http://a2e858295f1204618aab29d960a10bfa-41041143.us-east-1.elb.amazonaws.com/ ) is more)超过 64 个字符。

为了克服这个问题,我们可以为您的负载均衡器配置一个自定义域名。 每个 Classic Load Balancer 都会收到一个默认域名系统 (DNS) 名称。 此 DNS 名称包括创建负载均衡器的 AWS 区域的名称。 例如,如果您在美国西部(俄勒冈)区域创建名为 my-loadbalancer 的负载均衡器,您的负载均衡器会收到一个 DNS 名称,例如 my-loadbalancer-1234567890.us-west-2.elb.amazonaws.com。

要访问您的实例上的网站,请将此 DNS 名称粘贴到 Web 浏览器的地址字段中。 在我们的示例中,此 DNS 的字符数超过了 64 的限制。如果您希望为负载均衡器使用友好的 DNS 名称,例如www.example.com ,而不是默认的 DNS 名称,您可以创建自定义域名并将其与负载均衡器的 DNS 名称相关联。 当客户端使用此自定义域名发出请求时,DNS 服务器会将其解析为负载均衡器的 DNS 名称。 然后我们可以在配置入口文件时使用这个自定义域来代替我们的主机名。

可以应用此解决方法来实现您的用例。 要将您的自定义域名与您的负载均衡器名称相关联,您必须注册您的域名。 互联网名称与数字地址分配机构 (ICANN) 管理互联网上的域名。 您使用域名注册商注册域名,该注册商是 ICANN 认可的管理域名注册的组织。 您的注册商的网站将提供有关注册域名的详细说明和定价信息。

接下来,使用您的 DNS 服务(例如您的域名注册商)创建 CNAME 记录以将查询路由到您的负载均衡器。

或者,您可以使用 Route 53 作为您的 DNS 服务。 您创建一个托管区域,其中包含有关如何在 Internet 上为您的域路由流量的信息,以及一个别名资源记录集,它将对您的域名的查询路由到您的负载均衡器。 Route 53 不对别名记录集的 DNS 查询收费,您可以使用别名记录集将 DNS 查询路由到您的域顶点(例如,example.com)的负载均衡器。 有关将现有域的 DNS 服务转移到 Route 53 的信息,请参阅在 Amazon Route 中将 Route 53 配置为您的 DNS 服务 ( https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-configuring.html ) 53 开发人员指南。

[#] https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/using-domain-names-with-elb.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM