新着: プロジェクトの最新情報はこちらで入手できますTwitterMastodon

RFC-2136

このドキュメントの目的は、BIND namedなどのRFC2136準拠DNSサーバーに対してcert-managerをデプロイするために必要な各種機能の設定概要を提供することです。この機能は一般的に「ダイナミックDNS」として知られています。

他のcert-manager DNS統合と異なり、namedはドメインネームサーバーの「スイスアーミーナイフ」のようなものです。長年にわたり、単一ノードでの最大限の垂直方向のスケーラビリティ、およびサービスプロバイダーインターフェースによる水平方向のスケーラビリティを実現するために高度に最適化されてきました。この柔軟性により、ユーザーが実行する可能性のあるあらゆるnamedデプロイメントについて説明することは不可能です。そのため、このドキュメントでは、サーバーがコマンドラインツールを使用してcert-managerからのリクエストを受け入れる準備ができていることを確認し、その後、両者の連携方法について説明します。

トランザクション署名 ⇒ TSIG

ダイナミックDNS更新は、基本的にリソースレコード(RR)を返す可能性のあるサーバークエリです。DNSサーバーは一般的にパブリックインターネットに公開されているため、クエリに応答するサーバーに認証されていない更新をプッシュできることは、すぐに実行不可能になります。

namedアーキテクトの観点から、この問題に対する一般的な解決策は2つあります。1つ目は、example.comなど、ゾーンレベルで更新を手動で有効にする必要があることです。単純なネットワークでは、ゾーン更新にセキュリティを必要とする要件はなく、クライアントは認証なしで更新を提供できるよう構成できます。これは、DHCPを使用してブートするマシンに役立つ例です。この場合、マシンは自分自身について認識しており、DNSサーバーは構成されているアドレスから更新が来た場合に更新を受け入れるように構成できます。

これは明らかに、cert-managerとDNS01チャレンジのような状況では制限があります。この環境では、ACMEサーバーとの調整後にTXT RRを作成する必要があります。ACMEサーバーとネゴシエートした後、ドメインに公開されたTXT RRは、ドメインがそのための証明書作成プロセスに正当に関連していることを検証します。DNSのより大きな視点では、これは任意のアクター(この場合はcert-manager)がこれらのKVマッピングの1つをドメインに追加し、証明書が発行された後に削除できる必要があることを意味します。cert-managerには、リクエストを検証するためのDHCP割り当てなどの便利な物理的特性がありません。

このような場合、DNSサーバーに送信されるリクエストに署名できる必要があります。これは、TSIG(トランザクション署名)を使用して行います。

設定ステップ1 - セキュアな動的更新のためにDNSサーバーを設定する

基本的なnamedサーバーを動的更新のために準備する方法を説明する優れたチュートリアルが多数インターネット上に存在します。

より複雑なnamedデプロイメントでは、テキストファイルではなく、リソースレコードのデータベースとしてLDAPまたはSQLを使用することがあります。追加の要素として、ゾーンの動的更新の有効化やアクセス制御リスト(ACL)など、ゾーンメタデータの設定があります。ここでは説明しきれませんが、関連するドキュメントを見つけることができるはずです。

どのようなデプロイメントであっても、この段階の目標はcert-managerとは関係なく、nsupdateというツールを使用してTSIGで署名された更新を生成することにあります。これが完了したら、はるかに自信を持ってcert-managerの設定に取り組むことができます。

nsupdateの使用

BIND namedの設定におけるほとんどの方法は、dnssec-keygenを使用することです。このコマンドラインツールは、TSIGリクエストの署名に使用される名前付き秘密鍵を生成します。リクエストに署名すると、署名と秘密鍵の名前の両方が暗号化されていない形式でリクエストに添付されます。このようにして、リクエストを受信すると、秘密鍵の名前を使用して受信者が秘密鍵自体を見つけ、それを使用して新しい署名を構築し、2つの署名を比較して承認できます。

namedサーバーの誤った構成方法は数十種類あるため、先に進む前に、nsupdateを使用してサーバーが期待通りに動作することをテストします。https://debian-administration.org/article/591/Using_the_dynamic_DNS_editor_nsupdateは、ツールの使用方法を詳しく説明しています。

開始するには、単にnsupdate -k <keyID>を実行します。ここで、keyIDdnssec-keygenから返された値です。これにより、ディスクからキーが読み取られ、コマンドを発行するためのコマンドプロンプトが表示されます。一般的に、単純なTXT RRを作成し、削除できることを確認する必要があります。

$ nsupdate -k <keyID>
update add www1.example.com 60 txt testing
send
test here with `nslookup`
update delete www1.example.com txt
send
test here with `nslookup`

レコードの書き込み、読み取り、または削除に失敗すると、構成がどれだけうまく行われていても、cert-managerも実行できなくなります。

設定ステップ2 - cert-managerを設定する

さて、すべてが機能する様子を見てみましょう。ACME DNS01イシューアーとチャレンジメカニズム、およびrfc2136プロバイダーを設定する必要があることを忘れないでください。ドキュメントでは他の部分が十分に説明されているため、ここではプロバイダーに焦点を当てます。

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: example-issuer
spec:
acme:
...
solvers:
- dns01:
rfc2136:
nameserver: <address of authoritative nameserver configured above>
tsigKeyName: <key name used in `dnssec-keygen`, use something semantically meaningful in both environments>
tsigAlgorithm: HMACSHA512 // should be matched to the algo you chose in `dnssec-keygen`
tsigSecretSecretRef:
name: <the name of the k8s secret holding the TSIG key.. not the key itself!>
key: <name of the key *inside* the secret>

例:

rfc2136:
nameserver: 1.2.3.4:53
tsigKeyName: example-com-secret
tsigAlgorithm: HMACSHA512
tsigSecretSecretRef:
name: tsig-secret
key: tsig-secret-key

この設定例では、次の2つのコマンドが必要です。最初のものは、namedサーバーでキーを生成します。example-com-secretが上記のtsigKeyNameと後続のdnssec-keygenコマンドの両方にあることに注意してください。

$ dnssec-keygen -r /dev/urandom -a HMAC-SHA512 -b 512 -n HOST example-com-secret

また、tsigAlgorithmが構成とkeygenコマンドの両方に指定されていることにも注意してください。https://github.com/miekg/dns/blob/v1.0.12/tsig.go#L18-L23にリストされています。

Kubernetes側で必要な設定の2つ目は、シークレットを作成することです。上記の<key>.privateファイルからシークレットキー文字列を取得し、以下のプレースホルダーで使用します。

$ kubectl -n cert-manager create secret generic tsig-secret --from-literal=tsig-secret-key=<somesecret>

tsig-secrettsig-secret-keyが上記のtsigSecretSecretRefの設定と一致することに注意してください。

レート制限

rfc2136プロバイダーは、ドメインのSOA RR内のすべてのネームサーバーが同じ結果で応答するまで待機してから、Let's Encryptに連絡してチャレンジプロセスを完了します。これは、チャレンジサーバーが再帰クエリ(ローカルで保持していないレコードのクエリ)を実行する非権威DNSサーバーに連絡するためです。SOA内のサーバーに正しい値が含まれていない場合、非権威サーバーにも間違った情報が含まれている可能性が高く、リクエストがレート制限に抵触し、最終的にプロセスがロックアウトされる可能性があります。

このプロセスは、サーバーの誤った構成によってサーバーの構成が修復された後も持続するより微妙なロックアウトが発生するのを防ぐために実施されています。

他の場所で説明されているように、本番サーバーを使用する前に、ACMEステージングサーバーを使用して構成を完全にデバッグすることをお勧めします。ステージングサーバーのレート制限はそれほど厳しくありませんが、発行される証明書はブラウザーで信頼されているルート証明書で署名されていません。

次のステップ

これまでの設定では実際には何も実行されません。 こちらで説明されているように、証明書をリクエストする必要があります。証明書がリクエストされると、プロバイダーはリクエストの処理を開始します。

トラブルシューティング

  • 最初に、nsupdate を使用してDNSサーバーの更新を完全にテストしてください。ファイアウォール問題がないことを確認するために、理想的にはrfc2136 プロバイダーと同じ名前空間内のポッドから実行します。
  • cert-manager ポッドのログが役立ちます。コンテナ起動時に--v=5 引数を追加することで、追加のログを生成できます。
  • TSIGキーはbase64でエンコードされていますが、Kubernetes APIサーバーは、キーリテラルが保存される前にデコードされることも期待しています。場合によっては、キーを二重にエンコードする必要があります。(nsupdateを使用してテストした場合、この問題に遭遇しているかどうかは簡単にわかります。)
  • 作業中のゾーンのリフレッシュ時間にご注意ください。トラフィックが少ないゾーンの場合、初期の証明書を取得する際にリフレッシュ時間を約5分に短縮しても大きな違いはありません。プロセスが機能し始めたら、cert-managerの利点は、リフレッシュ時間のために更新に数時間かかっても問題ないことです。すべて自動化されています!
  • DNS RRを変更するためにREST APIを頻繁に使用する他のプロバイダーと比較して、このプロバイダーは少し時間がかかる場合があります。何が起こっているかを表示するには、kubectl certificate yourcert をwatchできます。プロセス全体で5分かかることは珍しくありません。