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
サーバーを動的更新のために準備する方法を説明する優れたチュートリアルが多数インターネット上に存在します。
- https://www.cyberciti.biz/faq/unix-linux-bind-named-configuring-tsig/
- https://tomthorp.me/blog/using-tsig-enable-secure-zone-transfers-between-bind-9x-servers
より複雑な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>
を実行します。ここで、keyID
はdnssec-keygen
から返された値です。これにより、ディスクからキーが読み取られ、コマンドを発行するためのコマンドプロンプトが表示されます。一般的に、単純なTXT RRを作成し、削除できることを確認する必要があります。
$ nsupdate -k <keyID>update add www1.example.com 60 txt testingsend… test here with `nslookup`update delete www1.example.com txtsend… test here with `nslookup`
レコードの書き込み、読み取り、または削除に失敗すると、構成がどれだけうまく行われていても、cert-managerも実行できなくなります。
設定ステップ2 - cert-managerを設定する
さて、すべてが機能する様子を見てみましょう。ACME DNS01イシューアーとチャレンジメカニズム、およびrfc2136
プロバイダーを設定する必要があることを忘れないでください。ドキュメントでは他の部分が十分に説明されているため、ここではプロバイダーに焦点を当てます。
apiVersion: cert-manager.io/v1kind: Issuermetadata:name: example-issuerspec: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:53tsigKeyName: example-com-secrettsigAlgorithm: HMACSHA512tsigSecretSecretRef:name: tsig-secretkey: 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-secret
とtsig-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分かかることは珍しくありません。