HTTP 驗證
使用 HTTP 驗證簽發 ACME 憑證
cert-manager 可以使用 ACME 協議從 CA 取得憑證。ACME 協議支援各種挑戰機制,用於證明網域的所有權,以便為該網域簽發有效的憑證。
其中一種挑戰機制是 HTTP01 挑戰。透過 HTTP01 挑戰,您可以透過確保網域上存在特定檔案來證明網域的所有權。假設您可以將給定的檔案發佈在給定的路徑下,則您控制該網域。
以下簽發者定義了啟用 HTTP 驗證的必要資訊。您可以在簽發者文件中閱讀更多關於簽發者資源的資訊。
apiVersion: cert-manager.io/v1kind: Issuermetadata:name: letsencrypt-stagingnamespace: defaultspec:acme:# The ACME server URLserver: https://acme-staging-v02.api.letsencrypt.org/directory# Email address used for ACME registrationemail: user@example.com# Name of a secret used to store the ACME account private keyprivateKeySecretRef:name: letsencrypt-staging# Enable the HTTP-01 challenge providersolvers:# An empty 'selector' means that this solver matches all domains- selector: {}http01:ingress:ingressClassName: nginx
我們已為 Let's Encrypt 的暫存環境指定了 ACME 伺服器 URL。暫存環境不會簽發受信任的憑證,但用於確保驗證過程在移至生產環境之前正常運作。Let's Encrypt 的生產環境施加更嚴格的速率限制,因此為了減少您達到這些限制的機會,強烈建議您先從使用暫存環境開始。若要移至生產環境,只需建立一個新的簽發者,並將 URL 設定為 https://acme-v02.api.letsencrypt.org/directory
。
ACME 協議的第一階段是讓客戶端向 ACME 伺服器註冊。此階段包括產生一個非對稱金鑰對,然後將其與簽發者中指定的電子郵件地址關聯。請務必將此電子郵件地址更改為您擁有的有效電子郵件地址。它通常用於在憑證即將到期時傳送到期通知。產生的私鑰儲存在名為 letsencrypt-staging
的密鑰中。
我們必須提供一或多個 Solver 來處理 ACME 挑戰。在此情況下,我們希望使用 HTTP 驗證,因此我們指定一個 http01
Solver。我們也可以選擇將不同的網域對應到不同的 Solver 設定。
建立上述簽發者後,我們可以使用它來取得憑證。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-comnamespace: defaultspec:secretName: example-com-tlsissuerRef:name: letsencrypt-stagingcommonName: example.comdnsNames:- www.example.com
憑證資源描述了我們想要的憑證以及可以用來取得憑證的方法。您可以在文件中了解更多關於憑證資源的資訊。如果憑證成功取得,則產生的金鑰對將儲存在與憑證相同命名空間中名為 example-com-tls
的密鑰中。
憑證的通用名稱將為 example.com
,而主體別名 (SAN) 將為 example.com
和 www.example.com
。請注意,只有這些 SAN 會受到 TLS 客戶端的尊重。
在我們的憑證中,我們引用了上述 letsencrypt-staging
簽發者。簽發者必須與憑證位於相同的命名空間中。如果您想要引用 ClusterIssuer
(這是簽發者的叢集範圍版本),則必須將 kind: ClusterIssuer
新增至 issuerRef
節中。
如需更多關於 ClusterIssuer
的資訊,請閱讀 ClusterIssuer
文件。
acme
節定義了我們 ACME 挑戰的設定。在這裡,我們定義了 HTTP01 挑戰的設定,該設定將用於驗證網域所有權。為了驗證 http01
節中提及的每個網域的所有權,cert-manager 將會建立一個 Pod、服務和 Ingress,公開符合 HTTP01 挑戰的 HTTP 端點。
http01
節中的欄位 ingressClassName
、class
和 name
可用於控制 cert-manager 如何與 Ingress 資源互動
-
如果指定了
ingressClassName
欄位,則會建立一個具有隨機產生名稱的新 ingress 資源,以解決挑戰。這個新資源的欄位ingressClassName
的值會與ingressClassName
欄位的值相同。這是建議用來設定應使用哪個 Ingress 控制器的方式。它適用於 NGINX ingress 控制器等。 -
如果指定了
class
欄位,則會建立一個具有隨機產生名稱的新 ingress 資源,以解決挑戰。這個新資源將有一個註釋,其鍵為kubernetes.io/ingress.class
,其值設定為class
欄位的值。此欄位僅建議與 ingress-gce 一起使用,而 ingress-gce 不支援ingressClassName
欄位。 -
如果指定了
name
欄位,則必須已存在與憑證相同命名空間中具有相同名稱的 Ingress 資源,並且只會修改該資源以新增適當的規則來解決挑戰。這個欄位對於 Google Cloud Loadbalancer ingress 控制器以及許多其他控制器很有用,這些控制器會為每個 ingress 資源指派一個公有 IP 位址。若沒有人工介入,建立新的 ingress 資源會導致任何挑戰失敗。 -
如果兩者都未指定,則會建立具有隨機產生名稱的新 ingress 資源,但它們不會設定 ingress 類別註釋。
-
如果兩者都指定,則
ingress
欄位將優先。
驗證網域所有權後,將會清除或刪除任何受 cert-manager 影響的資源。
注意:您有責任將每個網域名稱指向您的 ingress 控制器的正確 IP 位址。
建立上述憑證後,我們可以使用 kubectl describe
檢查是否已成功取得該憑證
$ kubectl describe certificate example-comEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal CreateOrder 57m cert-manager Created new ACME order, attempting validation...Normal DomainVerified 55m cert-manager Domain "example.com" verified with "http-01" validationNormal DomainVerified 55m cert-manager Domain "www.example.com" verified with "http-01" validationNormal IssueCert 55m cert-manager Issuing certificate...Normal CertObtained 55m cert-manager Obtained certificate from ACME serverNormal CertIssued 55m cert-manager Certificate issued successfully
您也可以使用 kubectl get secret example-com-tls -o yaml
檢查是否成功簽發。您應該會看到 base64 編碼的已簽署 TLS 金鑰對。
取得憑證後,cert-manager 會定期檢查其有效性,並在憑證即將到期時嘗試續訂。當憑證上的「Not After」欄位小於目前時間加上 30 天時,cert-manager 會認為憑證即將到期。