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

DNS 驗證

使用 DNS 驗證簽發 ACME 憑證

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

其中一種挑戰機制是 DNS01。使用 DNS01 挑戰,您需要證明您控制網域的 DNS 記錄,以證明您擁有該網域。方法是建立一個具有特定內容的 TXT 記錄,以證明您控制了網域的 DNS 記錄。

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

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
namespace: default
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: user@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# ACME DNS-01 provider configurations
solvers:
# An empty 'selector' means that this solver matches all domains
- selector: {}
dns01:
cloudDNS:
# The ID of the GCP project
# reference: https://cert-manager.dev.org.tw/docs/tutorials/acme/dns-validation/
project: $PROJECT_ID
# This is the secret used to access the service account
serviceAccountSecretRef:
name: clouddns-dns01-solver-svc-acct
key: key.json
# We only use cloudflare to solve challenges for example.org.
# Alternative options such as 'matchLabels' and 'dnsZones' can be specified
# as part of a solver's selector too.
- selector:
dnsNames:
- example.org
dns01:
cloudflare:
email: my-cloudflare-acc@example.com
# !! Remember to create a k8s secret before
# kubectl create secret generic cloudflare-api-key-secret
apiKeySecretRef:
name: cloudflare-api-key-secret
key: api-key

我們已指定 Let's Encrypt 的測試環境的 ACME 伺服器 URL。測試環境不會簽發受信任的憑證,而是用於確保驗證過程在轉移到生產環境之前正常運作。Let's Encrypt 的生產環境有更嚴格的速率限制,因此為了減少您達到這些限制的可能性,強烈建議從使用測試環境開始。若要轉移到生產環境,只需建立一個新的簽發者,並將 URL 設定為https://acme-v02.api.letsencrypt.org/directory即可。

ACME 協定的第一階段是讓用戶端向 ACME 伺服器註冊。此階段包括產生一個非對稱金鑰對,然後將其與簽發者中指定的電子郵件地址相關聯。請務必將此電子郵件地址變更為您擁有的有效地址。它通常用於在憑證即將到期時發送到期通知。產生的私密金鑰儲存在名為letsencrypt-staging的 Secret 中。

dns01小節包含可用於解決 DNS 挑戰的 DNS01 提供者清單。我們的簽發者定義了兩個提供者。這讓我們在取得憑證時可以選擇要使用哪一個。

有關 DNS 提供者組態的更多資訊,包括支援的提供者清單,可以在DNS01 參考文件中找到。

建立上述簽發者後,我們就可以使用它來取得憑證。

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
namespace: default
spec:
secretName: example-com-tls
issuerRef:
name: letsencrypt-staging
dnsNames:
- '*.example.com'
- example.com
- example.org

憑證資源描述了我們想要的憑證,以及可以用來取得它的可能方法。您可以像取得任何其他憑證一樣,取得萬用字元網域的憑證。請務必在 YAML 資源中用星號括住萬用字元網域,以避免格式問題。如果您在同一個憑證上同時指定example.com*.example.com,則執行驗證的時間會稍長,因為每個網域都必須逐一驗證。您可以在文件中了解更多關於憑證資源的資訊。如果憑證成功取得,產生的金鑰對將會儲存在與憑證相同命名空間中,名為example-com-tls的 Secret 中。

憑證的通用名稱將為*.example.com,而主體別名 (SAN)將為*.example.comexample.comexample.org

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

如需更多有關ClusterIssuers的資訊,請閱讀簽發者概念

acme小節定義了我們的 ACME 挑戰的組態。在這裡,我們定義了 DNS 挑戰的組態,將用於驗證網域所有權。對於dns01小節中提及的每個網域,cert-manager 將使用參照的簽發者的提供者憑證,建立一個名為_acme-challenge的 TXT 記錄。然後,ACME 伺服器將驗證此記錄,以便簽發憑證。驗證網域所有權後,將清除任何受 cert-manager 影響的記錄。

注意:您有責任確保選取的提供者是您網域的權威提供者。

建立上述憑證後,我們可以使用 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 "dns-01" validation
Normal DomainVerified 55m cert-manager Domain "example.com" verified with "dns-01" validation
Normal DomainVerified 55m cert-manager Domain "example.org" verified with "dns-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 會認為憑證快到期。