新着: プロジェクトの最新情報をTwitterMastodonで入手できます。

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は、同様の設定構造に従います。クライアントのemailserver URL、privateKeySecretRef、および1つ以上のsolversです。以下に、シンプルなACME Issuerの例を示します。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
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.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# 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 nginx
solvers:
- http01:
ingress:
ingressClassName: nginx

ソルバーは、dns01およびhttp01スタンザの形式で提供されます。これらのソルバータイプの構成方法の詳細については、それぞれのドキュメント - DNS01HTTP01を参照してください。

外部アカウントバインディング

cert-managerは、ACMEアカウントで外部アカウントバインディングを使用することをサポートしています。外部アカウントバインディングは、ACMEアカウントをCAカスタムデータベースなどの外部アカウントに関連付けるために使用されます。これは、明示的に必要な場合を除き、ほとんどのcert-managerユーザーには通常必要ありません。

外部アカウントバインディングには、ACMEアカウントを表すACME Issuerに2つのフィールドが必要です。これらのフィールドは次のとおりです。

  • keyID - 外部アカウントバインディングが外部アカウントマネージャーによってインデックス付けされるキーIDまたはアカウントID
  • keySecretRef - 外部アカウントの対称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/v1
kind: ClusterIssuer
metadata:
name: my-acme-server-with-eab
spec:
acme:
email: user@example.com
server: https://my-acme-server-with-eab.com/directory
externalAccountBinding:
keyID: my-keyID-1
keySecretRef:
name: eab-secret
key: secret
privateKeySecretRef:
name: example-issuer-account-key
solvers:
- http01:
ingress:
ingressClassName: nginx

注:cert-managerのv1.3.0より前のバージョンでは、ユーザーはIssuer.spec.acme.externalAccountBinding.keyAlgorithmフィールドを設定することにより、EABのMACアルゴリズムも指定する必要がありました。アップストリームのGo x/cryptoライブラリがアルゴリズムをHS256にハードコードしているため、このフィールドは現在非推奨になっています。(アップストリームの関連するディスカッションについては、CL#41430を参照してください)。

ACMEアカウントの再利用

複数のクラスター間で単一のACMEアカウントを再利用したい場合があります。これは、特にEABを使用する場合に役立つ可能性があります。disableAccountKeyGenerationフィールドが設定されている場合、cert-managerは新しいACMEアカウントを作成せず、privateKeySecretRefで指定された既存のキーを使用します。 Secretが提供されるまで、Issuer/ClusterIssuerは準備が整っておらず、再試行を続行することに注意してください。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: my-acme-server-with-existing-acme-account
spec:
acme:
email: user@example.com
disableAccountKeyGeneration: true
privateKeySecretRef:
name: example-issuer-account-key

複数のソルバータイプの追加

たとえば、HTTP01を使用して検証された他の証明書とともにDNS01を使用してワイルドカード証明書を発行する場合など、異なるイングレスコントローラーに対して異なるタイプのチャレンジソルバー構成を使用したい場合があります。

solversスタンザには、オプションのselectorフィールドがあり、これにより、どのCertificates、さらにそれらのCertificates上のどのDNS名を使用してチャレンジを解決するかを指定できます。

ソルバーに選択されるためにCertificateが満たす必要のある要件を形成するために使用できる3つのセレクタータイプがあります - matchLabelsdnsNames、およびdnsZones。単一のソルバーにこれらの3つのセレクターをいくつでも含めることができます。

ラベルの一致

matchLabelセレクターでは、すべてのCertificatesが、そのスタンザの文字列マップリストで定義されているすべてのラベルと一致する必要があります。たとえば、次のIssuerは、"user-cloudflare-solver": "true"および"email": "user@example.com"というラベルを持つCertificatesでのみ一致します。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
...
solvers:
- dns01:
cloudflare:
email: user@example.com
apiKeySecretRef:
name: cloudflare-apikey-secret
key: apikey
selector:
matchLabels:
"use-cloudflare-solver": "true"
"email": "user@example.com"

DNS名

dnsNamesセレクターは、ソルバーにマッピングする必要のある正確なDNS名のリストです。これは、これらのDNS名のいずれかを含むCertificatesが選択されることを意味します。一致が見つかった場合、dnsNamesセレクターは、dnsZonesセレクターよりも優先されます。同じdnsNames値で複数のソルバーが一致する場合、matchLabelsで最も多く一致するラベルを持つソルバーが選択されます。どちらもより多く一致するものがない場合は、リストで先に定義されているソルバーが選択されます。

以下の例では、DNS名がexample.com*.example.comである証明書の課題を解決します。

注意: dnsNamesは完全一致を対象とし、ワイルドカードを解決しません。つまり、以下のIssuerfoo.example.comのようなDNS名を解決しません。ゾーン内のすべてのサブドメインに一致させるには、dnsZonesセレクタータイプを使用してください。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
...
solvers:
- dns01:
cloudflare:
email: user@example.com
apiKeySecretRef:
name: cloudflare-apikey-secret
key: apikey
selector:
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/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
...
solvers:
- dns01:
cloudflare:
email: user@example.com
apiKeySecretRef:
name: cloudflare-apikey-secret
key: apikey
selector:
dnsZones:
- 'example.com'

すべてまとめると

各ソルバーは、定義された3つのセレクタータイプをいくつでも持つことができます。以下の例では、CloudFlare用のDNS01ソルバーは、DNS名a.example.comb.example.comを含む証明書のドメインの課題を解決するために使用されます。Google CloudDNS用のDNS01ソルバーは、DNS名がゾーンtest.example.comおよびそのすべてのサブドメイン(例:foo.test.example.com)に一致する証明書の課題を解決するために使用されます。

他のすべての課題については、証明書にラベル"use-http01-solver": "true"も含まれている場合にのみHTTP01ソルバーが使用されます。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
...
solvers:
- http01:
ingress:
ingressClassName: nginx
selector:
matchLabels:
"use-http01-solver": "true"
- dns01:
cloudflare:
email: user@example.com
apiKeySecretRef:
name: cloudflare-apikey-secret
key: apikey
selector:
dnsNames:
- 'a.example.com'
- 'b.example.com'
- dns01:
cloudDNS:
project: my-project-id
hostedZoneName: 'test-example.com'
serviceAccountSecretRef:
key: sa
name: gcp-sa-secret
selector:
dnsZones:
- 'test.example.com' # This should be the DNS name of the zone

各個別のセレクターブロックには、複数のセレクタータイプを含めることができます。例:

solvers:
- dns01:
cloudflare:
email: user@example.com
apiKeySecretRef:
name: cloudflare-apikey-secret
key: apikey
selector:
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/v1
kind: ClusterIssuer
metadata:
name: my-acme-server-issuer
spec:
acme:
server: https://my-acme-server.example.com
caBundle: <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/v1
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
preferredChain: "ISRG Root X1"