簡體   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