ACME
ACME発行者タイプは、Automated Certificate Management Environment (ACME) 証明機関サーバーに登録された単一のアカウントを表します。新しいACME Issuer
を作成すると、cert-managerはACMEサーバーであなたを識別するために使用される秘密鍵を生成します。
パブリックACMEサーバーによって発行された証明書は、通常、クライアントのコンピュータによってデフォルトで信頼されます。つまり、たとえば、そのURLに対して発行されたACME証明書によってバックアップされているWebサイトにアクセスすると、ほとんどのクライアントのWebブラウザによってデフォルトで信頼されます。ACME証明書は通常無料です。
チャレンジの解決
ACME CAサーバーが、クライアントが証明書を要求しているドメインを所有していることを検証するためには、クライアントは「チャレンジ」を完了する必要があります。これは、クライアントが所有していないドメインの証明書を要求し、結果として他者のサイトを不正に偽装することを防ぐためです。RFC8555に詳しく説明されているように、cert-managerはHTTP01とDNS01の2つのチャレンジ検証を提供しています。
HTTP01チャレンジは、HTTP URLエンドポイントに存在し、インターネット経由でルーティング可能な計算されたキーを提示することで完了します。このURLは、証明書を要求したドメイン名を使用します。ACMEサーバーがインターネット経由でこのURLからこのキーを取得できると、ACMEサーバーはあなたがこのドメインの所有者であることを検証できます。HTTP01チャレンジが作成されると、cert-managerは、このURLへのトラフィックをこのキーを提示する小さなWebサーバーにルーティングするように、クラスターのイングレスを自動的に構成します。
DNS01チャレンジは、DNS TXTレコードに存在する計算されたキーを提供することで完了します。このTXTレコードがインターネット全体に伝播されると、ACMEサーバーはDNSルックアップを介してこのキーを正常に取得でき、クライアントが要求された証明書のドメインを所有していることを検証できます。適切な権限があれば、cert-managerは、指定されたDNSプロバイダーに対してこのTXTレコードを自動的に提示します。
設定
基本的なACME Issuerの作成
すべてのACME Issuers
は、同様の設定構造に従います。クライアントのemail
、server
URL、privateKeySecretRef
、および1つ以上のsolvers
です。以下に、シンプルなACME Issuerの例を示します。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: letsencrypt-stagingspec:acme:# You must replace this email address with your own.# Let's Encrypt will use this to contact you about expiring# certificates, and issues related to your account.email: user@example.comserver: https://acme-staging-v02.api.letsencrypt.org/directoryprivateKeySecretRef:# Secret resource that will be used to store the account's private key.name: example-issuer-account-key# Add a single challenge solver, HTTP01 using nginxsolvers:- http01:ingress:ingressClassName: nginx
ソルバーは、dns01
およびhttp01
スタンザの形式で提供されます。これらのソルバータイプの構成方法の詳細については、それぞれのドキュメント - DNS01、HTTP01を参照してください。
外部アカウントバインディング
cert-managerは、ACMEアカウントで外部アカウントバインディングを使用することをサポートしています。外部アカウントバインディングは、ACMEアカウントをCAカスタムデータベースなどの外部アカウントに関連付けるために使用されます。これは、明示的に必要な場合を除き、ほとんどのcert-managerユーザーには通常必要ありません。
外部アカウントバインディングには、ACMEアカウントを表すACME Issuer
に2つのフィールドが必要です。これらのフィールドは次のとおりです。
keyID
- 外部アカウントバインディングが外部アカウントマネージャーによってインデックス付けされるキーIDまたはアカウントIDkeySecretRef
- 外部アカウントの対称MACキーのbase64エンコードされたURL文字列を含むシークレットの名前とキー
注:*ほとんどの*場合、MACキーは
base64URL
でエンコードする必要があります。次のコマンドは、キーをbase64エンコードし、base64URL
に変換します。$ echo 'my-secret-key' | base64 -w0 | sed -e 's/+/-/g' -e 's/\//_/g' -e 's/=//g'次に、次のコマンドでSecretリソースを作成できます。
$ kubectl create secret generic eab-secret --from-literal \secret={base64 encoded secret key}
外部アカウントバインディングを使用したACME Issuerの例を次に示します。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: my-acme-server-with-eabspec:acme:email: user@example.comserver: https://my-acme-server-with-eab.com/directoryexternalAccountBinding:keyID: my-keyID-1keySecretRef:name: eab-secretkey: secretprivateKeySecretRef:name: example-issuer-account-keysolvers:- http01:ingress:ingressClassName: nginx
注:cert-managerの
v1.3.0
より前のバージョンでは、ユーザーはIssuer.spec.acme.externalAccountBinding.keyAlgorithm
フィールドを設定することにより、EABのMACアルゴリズムも指定する必要がありました。アップストリームのGox/crypto
ライブラリがアルゴリズムをHS256
にハードコードしているため、このフィールドは現在非推奨になっています。(アップストリームの関連するディスカッションについては、CL#41430
を参照してください)。
ACMEアカウントの再利用
複数のクラスター間で単一のACMEアカウントを再利用したい場合があります。これは、特にEABを使用する場合に役立つ可能性があります。disableAccountKeyGeneration
フィールドが設定されている場合、cert-managerは新しいACMEアカウントを作成せず、privateKeySecretRef
で指定された既存のキーを使用します。 Secret
が提供されるまで、Issuer
/ClusterIssuer
は準備が整っておらず、再試行を続行することに注意してください。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: my-acme-server-with-existing-acme-accountspec:acme:email: user@example.comdisableAccountKeyGeneration: trueprivateKeySecretRef:name: example-issuer-account-key
複数のソルバータイプの追加
たとえば、HTTP01
を使用して検証された他の証明書とともにDNS01
を使用してワイルドカード証明書を発行する場合など、異なるイングレスコントローラーに対して異なるタイプのチャレンジソルバー構成を使用したい場合があります。
solvers
スタンザには、オプションのselector
フィールドがあり、これにより、どのCertificates
、さらにそれらのCertificates
上のどのDNS名を使用してチャレンジを解決するかを指定できます。
ソルバーに選択されるためにCertificate
が満たす必要のある要件を形成するために使用できる3つのセレクタータイプがあります - matchLabels
、dnsNames
、およびdnsZones
。単一のソルバーにこれらの3つのセレクターをいくつでも含めることができます。
ラベルの一致
matchLabel
セレクターでは、すべてのCertificates
が、そのスタンザの文字列マップリストで定義されているすべてのラベルと一致する必要があります。たとえば、次のIssuer
は、"user-cloudflare-solver": "true"
および"email": "user@example.com"
というラベルを持つCertificates
でのみ一致します。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: letsencrypt-stagingspec:acme:...solvers:- dns01:cloudflare:email: user@example.comapiKeySecretRef:name: cloudflare-apikey-secretkey: apikeyselector:matchLabels:"use-cloudflare-solver": "true""email": "user@example.com"
DNS名
dnsNames
セレクターは、ソルバーにマッピングする必要のある正確なDNS名のリストです。これは、これらのDNS名のいずれかを含むCertificates
が選択されることを意味します。一致が見つかった場合、dnsNames
セレクターは、dnsZones
セレクターよりも優先されます。同じdnsNames
値で複数のソルバーが一致する場合、matchLabels
で最も多く一致するラベルを持つソルバーが選択されます。どちらもより多く一致するものがない場合は、リストで先に定義されているソルバーが選択されます。
以下の例では、DNS名がexample.com
と*.example.com
である証明書
の課題を解決します。
注意:
dnsNames
は完全一致を対象とし、ワイルドカードを解決しません。つまり、以下のIssuer
はfoo.example.com
のようなDNS名を解決しません。ゾーン内のすべてのサブドメインに一致させるには、dnsZones
セレクタータイプを使用してください。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: letsencrypt-stagingspec:acme:...solvers:- dns01:cloudflare:email: user@example.comapiKeySecretRef:name: cloudflare-apikey-secretkey: apikeyselector:dnsNames:- 'example.com'- '*.example.com'
DNSゾーン
dnsZones
スタンザは、このソルバーで解決できるDNSゾーンのリストを定義します。DNS名が完全一致であるか、指定されたdnsZones
のいずれかのサブドメインである場合、より具体的なdnsNames
の一致が構成されていない限り、このソルバーが使用されます。これは、ドメインwww.sys.example.com
に対して、example.com
を指定するのではなく、sys.example.com
が選択されることを意味します。複数のソルバーが同じdnsZones
の値で一致する場合、matchLabels
で最も一致するラベルが多いソルバーが選択されます。どちらも一致が多い場合は、リストで先に定義されたソルバーが選択されます。
以下の例では、このソルバーはドメインexample.com
と、そのすべてのサブドメイン*.example.com
の課題を解決します。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: letsencrypt-stagingspec:acme:...solvers:- dns01:cloudflare:email: user@example.comapiKeySecretRef:name: cloudflare-apikey-secretkey: apikeyselector:dnsZones:- 'example.com'
すべてまとめると
各ソルバーは、定義された3つのセレクタータイプをいくつでも持つことができます。以下の例では、CloudFlare用のDNS01
ソルバーは、DNS名a.example.com
とb.example.com
を含む証明書
のドメインの課題を解決するために使用されます。Google CloudDNS用のDNS01
ソルバーは、DNS名がゾーンtest.example.com
およびそのすべてのサブドメイン(例:foo.test.example.com
)に一致する証明書
の課題を解決するために使用されます。
他のすべての課題については、証明書
にラベル"use-http01-solver": "true"
も含まれている場合にのみ、HTTP01
ソルバーが使用されます。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: letsencrypt-stagingspec:acme:...solvers:- http01:ingress:ingressClassName: nginxselector:matchLabels:"use-http01-solver": "true"- dns01:cloudflare:email: user@example.comapiKeySecretRef:name: cloudflare-apikey-secretkey: apikeyselector:dnsNames:- 'a.example.com'- 'b.example.com'- dns01:cloudDNS:project: my-project-idhostedZoneName: 'test-example.com'serviceAccountSecretRef:key: saname: gcp-sa-secretselector:dnsZones:- 'test.example.com' # This should be the DNS name of the zone
各個別のセレクターブロックには、複数のセレクタータイプを含めることができます。例:
solvers:- dns01:cloudflare:email: user@example.comapiKeySecretRef:name: cloudflare-apikey-secretkey: apikeyselector:matchLabels:'email': 'user@example.com''solver': 'cloudflare'dnsZones:- 'test.example.com'- 'example.dev'
この場合、Cloudflare用のDNS01
ソルバーは、証明書
にmatchLabels
のラベルがあり、かつDNS名がdnsZones
のゾーンと一致する場合にのみ、DNS名の課題を解決するために使用されます。
プライベートACMEサーバー
cert-managerは、ACME仕様に従っている限り、プライベートまたはセルフホストのACMEサーバーでも動作するはずです。
ACMEサーバーが公開的に信頼された証明書を使用していない場合は、cert-manager 1.11以降から、Issuerを作成するときに使用する信頼できるCAを渡すことができます。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: my-acme-server-issuerspec:acme:server: https://my-acme-server.example.comcaBundle: <base64 encoded CA Bundle in PEM format>...
代替証明書チェーン
ACMEサーバーから証明書を取得するときに、代替の証明書チェーンを選択できます。これにより、発行者は移行期間中に新しいルート証明書にスムーズに移行させることができます。最も有名な例は、Let's Encryptの"ISRGルート"の変更でした。
この機能はLet's Encryptだけのものではありません。ACMEサーバーが複数のCAによる署名をサポートしている場合は、証明書のIssuer部分に、目的のチェーンのコモンネームの値を持つpreferredChain
を使用できます。コモンネームが異なるチェーンと一致する場合、サーバーはその新しいチェーンを使用して返すことを選択できます。
preferredChain
が証明書と一致しない場合、サーバーはデフォルトの証明書と見なすものを返します。
例として、以下は、(完了した)「ISRGルート」の変更前に、ユーザーが代替チェーンをどのように要求していたかを示していますが、この変更はすでに発生しているため、Let's Encryptではこれを行う必要がなくなったことに注意してください。
apiVersion: cert-manager.io/v1kind: Issuermetadata:name: letsencryptspec:acme:server: https://acme-v02.api.letsencrypt.org/directorypreferredChain: "ISRG Root X1"