最新消息:在TwitterMastodon取得專案更新

HTTP 驗證

使用 HTTP 驗證簽發 ACME 憑證

cert-manager 可以使用 ACME 協議從 CA 取得憑證。ACME 協議支援各種挑戰機制,用於證明網域的所有權,以便為該網域簽發有效的憑證。

其中一種挑戰機制是 HTTP01 挑戰。透過 HTTP01 挑戰,您可以透過確保網域上存在特定檔案來證明網域的所有權。假設您可以將給定的檔案發佈在給定的路徑下,則您控制該網域。

以下簽發者定義了啟用 HTTP 驗證的必要資訊。您可以在簽發者文件中閱讀更多關於簽發者資源的資訊。

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
namespace: default
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: user@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
# 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/v1
kind: Certificate
metadata:
name: example-com
namespace: default
spec:
secretName: example-com-tls
issuerRef:
name: letsencrypt-staging
commonName: example.com
dnsNames:
- www.example.com

憑證資源描述了我們想要的憑證以及可以用來取得憑證的方法。您可以在文件中了解更多關於憑證資源的資訊。如果憑證成功取得,則產生的金鑰對將儲存在與憑證相同命名空間中名為 example-com-tls 的密鑰中。

憑證的通用名稱將為 example.com,而主體別名 (SAN) 將為 example.comwww.example.com。請注意,只有這些 SAN 會受到 TLS 客戶端的尊重。

在我們的憑證中,我們引用了上述 letsencrypt-staging 簽發者。簽發者必須與憑證位於相同的命名空間中。如果您想要引用 ClusterIssuer(這是簽發者的叢集範圍版本),則必須將 kind: ClusterIssuer 新增至 issuerRef 節中。

如需更多關於 ClusterIssuer 的資訊,請閱讀 ClusterIssuer 文件

acme 節定義了我們 ACME 挑戰的設定。在這裡,我們定義了 HTTP01 挑戰的設定,該設定將用於驗證網域所有權。為了驗證 http01 節中提及的每個網域的所有權,cert-manager 將會建立一個 Pod、服務和 Ingress,公開符合 HTTP01 挑戰的 HTTP 端點。

http01 節中的欄位 ingressClassNameclassname 可用於控制 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-com
Events:
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" validation
Normal DomainVerified 55m cert-manager Domain "www.example.com" verified with "http-01" validation
Normal IssueCert 55m cert-manager Issuing certificate...
Normal CertObtained 55m cert-manager Obtained certificate from ACME server
Normal CertIssued 55m cert-manager Certificate issued successfully

您也可以使用 kubectl get secret example-com-tls -o yaml 檢查是否成功簽發。您應該會看到 base64 編碼的已簽署 TLS 金鑰對。

取得憑證後,cert-manager 會定期檢查其有效性,並在憑證即將到期時嘗試續訂。當憑證上的「Not After」欄位小於目前時間加上 30 天時,cert-manager 會認為憑證即將到期。