15.3. Tang サーバーの暗号化キー管理
暗号キーを再作成するための暗号化メカニズムは、ノードに保管されている ブラインドキーと関係する Tang サーバーの秘密鍵に基づいています。Tang サーバーの秘密鍵とノードの暗号化ディスクの両方を取得した者による攻撃から保護するには、定期的にキーを再生成することを推奨します。
Tang サーバーから古いキーを削除する前に、すべてのノードでキー変更操作を実行する必要があります。以下のセクションでは、古いキーを再生成し、削除する手順を説明します。
15.3.1. Tang サーバーのキーのバックアップ
Tang サーバーは /usr/libexec/tangd-keygen
を使用して新しいキーを生成し、デフォルトで /var/db/tang
ディレクトリーに保存します。障害が発生した場合に Tang サーバーを回復するには、このディレクトリーをバックアップします。キーは機密性が高く、使用した全ホストのブートディスクを復号化できるため、キーは適切に保護される必要があります。
手順
-
バックアップキーを
/var/db/tang
ディレクトリーから、キーを復元できる temp ディレクトリーにコピーします。
15.3.2. Tang サーバーのキーのリカバリー
バックアップからキーにアクセスして、Tang サーバーのキーを回復できます。
手順
キーをバックアップフォルダーから
/var/db/tang/
ディレクトリーに復元します。Tang サーバーの起動時に、これらの復元されたキーをアドバタイズして使用します。
15.3.3. Tang サーバーのキー変更
以下の手順では、例として一意のキーが割り当てられた 3 つの Tang サーバーセットを使用します。
冗長な Tang サーバーを使用すると、ノードの自動起動に失敗する可能性が低減します。
Tang サーバーおよび関連付けられたすべての NBDE 暗号化ノードのキーは 3 つの手順を使用して、再生成します。
前提条件
- 1 つ以上のノードで機能する Network-Bound Disk Encryption(NBDE) をインストールしておく。
手順
- 新しい Tang サーバーキーを生成します。
- NBDE で暗号化された全ノードに新規キーを使用するようにキーを再生成します。
古い Tang サーバーキーを削除します。
注記NBDE で暗号化されたすべてのノードがキーの再生成を完了する前に古いキーを削除すると、それらのノードは他の設定済みの Tang サーバーに過度に依存するようになります。
図15.1 Tang サーバーのキー再生成のワークフロー例
15.3.3.1. 新しい Tang サーバーキーの生成
前提条件
- Tang サーバーを実行する Linux マシンのルートシェル。
Tang サーバーキーのローテーションを容易に検証するには、古いキーで小規模なテストファイルを暗号化します。
# echo plaintext | clevis encrypt tang '{"url":"http://localhost:7500”}' -y >/tmp/encrypted.oldkey
暗号化が正常に完了し、ファイルを復号化して同じ文字列
plaintext
を生成できることを確認します。# clevis decrypt </tmp/encrypted.oldkey
手順
Tang サーバーキーの保存先のディレクトリーを見つけてアクセスします。通常、これは
/var/db/tang
ディレクトリーです。現在公開されているキーのサムプリントを確認します。# tang-show-keys 7500
出力例
36AHjNH3NZDSnlONLz1-V4ie6t8
Tang サーバーのキーディレクトリーを入力します。
# cd /var/db/tang/
現在の Tang サーバーキーをリスト表示します。
# ls -A1
出力例
36AHjNH3NZDSnlONLz1-V4ie6t8.jwk gJZiNPMLRBnyo_ZKfK4_5SrnHYo.jwk
通常の Tang サーバーの操作時に、このディレクトリーには、署名および検証用とキー派生用の 2 つの
.jwk
ファイルがあります。古いキーのアドバタイズを無効にします。
# for key in *.jwk; do \ mv -- "$key" ".$key"; \ done
Network-Bound Disk Encryption(NBDE) を使用する新規クライアント、またはキーを要求する新規クライアントには古いキーは表示されなくなりました。既存のクライアントは、削除されるまで以前のキーにアクセスして使用できます。Tang サーバーは、
.
文字で始まる、UNIX の非表示ファイルに保存されているキーを読み取りますがアドバタイズはしません。新しいキーを生成します。
# /usr/libexec/tangd-keygen /var/db/tang
これらのファイルは非表示になり、新しいキーが存在するので、現在の Tang サーバーキーをリスト表示して古いキーがアドバタイズされなくなったことを確認します。
# ls -A1
出力例
.36AHjNH3NZDSnlONLz1-V4ie6t8.jwk .gJZiNPMLRBnyo_ZKfK4_5SrnHYo.jwk Bp8XjITceWSN_7XFfW7WfJDTomE.jwk WOjQYkyK7DxY_T5pMncMO5w0f6E.jwk
Tang は、新しいキーを自動的にアドバタイズします。
注記より新しい Tang サーバーのインストールには、アドバタイズを無効にして新規キーを同時に生成するヘルパー
/usr/libexec/tangd-rotate-keys
ディレクトリーが含まれます。- 同じキー情報を共有するロードバランサーの背後で複数の Tang サーバーを実行している場合は、続行する前に、ここで加えた変更が一連のサーバー全体に適切に同期されていることを確認します。
検証
Tang サーバーが、古いキーではなく、新しいキーをアドバタイズすることを確認します。
# tang-show-keys 7500
出力例
WOjQYkyK7DxY_T5pMncMO5w0f6E
アドバタイズされていない古いキーがまだ復号化要求に使用できることを確認します。
# clevis decrypt </tmp/encrypted.oldkey
15.3.3.2. 全 NBDE ノードのキー変更
リモートクラスターにダウンタイムを発生させずに DaemonSet
オブジェクトを使用することで、リモートクラスターのすべてのノードにキーを再生成できます。
キー設定時にノードの電源が切れると、起動できなくなる可能性があり、Red Hat Advanced Cluster Management(RHACM) または GitOps パイプラインを使用して再デプロイする必要があります。
前提条件
-
Network-Bound Disk Encryption(NBDE) ノードが割り当てられたすべてのクラスターへの
cluster-admin
アクセス。 - Tang サーバーのキーが変更されていない場合でも、キーの再生成が行われるすべての NBDE ノードからすべての Tang サーバーにアクセスできる必要があります。
- すべての Tang サーバーの Tang サーバーの URL およびキーのサムプリントを取得します。
手順
以下のテンプレートに基づいて
DaemonSet
オブジェクトを作成します。このテンプレートは 3 つの冗長 Tang サーバーを設定しますが、他の状況にも簡単に対応できます。NEW_TANG_PIN
環境の Tang サーバーの URL およびサムプリントを、実際の環境に合わせて変更します。apiVersion: apps/v1 kind: DaemonSet metadata: name: tang-rekey namespace: openshift-machine-config-operator spec: selector: matchLabels: name: tang-rekey template: metadata: labels: name: tang-rekey spec: containers: - name: tang-rekey image: registry.access.redhat.com/ubi8/ubi-minimal:8.4 imagePullPolicy: IfNotPresent command: - "/sbin/chroot" - "/host" - "/bin/bash" - "-ec" args: - | rm -f /tmp/rekey-complete || true echo "Current tang pin:" clevis-luks-list -d $ROOT_DEV -s 1 echo "Applying new tang pin: $NEW_TANG_PIN" clevis-luks-edit -f -d $ROOT_DEV -s 1 -c "$NEW_TANG_PIN" echo "Pin applied successfully" touch /tmp/rekey-complete sleep infinity readinessProbe: exec: command: - cat - /host/tmp/rekey-complete initialDelaySeconds: 30 periodSeconds: 10 env: - name: ROOT_DEV value: /dev/disk/by-partlabel/root - name: NEW_TANG_PIN value: >- {"t":1,"pins":{"tang":[ {"url":"http://tangserver01:7500","thp":"WOjQYkyK7DxY_T5pMncMO5w0f6E"}, {"url":"http://tangserver02:7500","thp":"I5Ynh2JefoAO3tNH9TgI4obIaXI"}, {"url":"http://tangserver03:7500","thp":"38qWZVeDKzCPG9pHLqKzs6k1ons"} ]}} volumeMounts: - name: hostroot mountPath: /host securityContext: privileged: true volumes: - name: hostroot hostPath: path: / nodeSelector: kubernetes.io/os: linux priorityClassName: system-node-critical restartPolicy: Always serviceAccount: machine-config-daemon serviceAccountName: machine-config-daemon
この場合は、
tangserver01
のキーを再生成していても、tangserver01
の新規サムプリントだけでなく、その他すべての Tang サーバーの現在のサムプリントも指定する必要があります。キーの再生成操作にすべてのサムプリントの指定に失敗すると、中間者攻撃の可能性が高まります。キーの再生成が必要なすべてのクラスターにデーモンセットを配布するには、次のコマンドを実行します。
$ oc apply -f tang-rekey.yaml
ただし、スケーリングで実行するには、デーモンセットを ACM ポリシーでラップします。この ACM 設定には、デーモンセットをデプロイするポリシーが 1 つ、すべてのデーモンセット Pod が READY であることを確認する 2 番目のポリシー、およびクラスターの適切なセットに適用する配置ルールを含める必要があります。
デーモンセットのすべてのサーバーが正常に再割り当てされたことを確認したら、デーモンセットを削除します。デーモンセットを削除しない場合は、次回のキー再生成操作の前にこれを削除する必要があります。
検証
デーモンセットを配布したら、デーモンセットを監視し、キー作成が正常に完了したことを確認します。サンプルのデーモンセットのスクリプトは、キー変更に失敗するとエラーで終了し、成功した場合には CURRENT
状態のままになります。また、キーの再生成が正常に実行されると、Pod に READY
のマークを付ける readiness プローブもあります。
以下は、キー変更が完了する前に設定されたデーモンセットの出力リストの例です。
$ oc get -n openshift-machine-config-operator ds tang-rekey
出力例
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE tang-rekey 1 1 0 1 0 kubernetes.io/os=linux 11s
以下は、キーの変更が正常に実行された後のデーモンセットの出力リストの例です。
$ oc get -n openshift-machine-config-operator ds tang-rekey
出力例
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE tang-rekey 1 1 1 1 1 kubernetes.io/os=linux 13h
キーの再生成には、通常完了までに数分かかります。
ACM ポリシーを使用してデーモンセットを複数のクラスターに分散する場合には、すべてのデーモンセットの READY の数が DESIRED の数と等しいことを確認するコンプライアンスポリシーを含める必要があります。こうすることで、このようなポリシーに準拠すると、すべてのデーモンセット Pod が READY で、キーの再生成が正常に実行されていることが分かります。ACM 検索を使用して、デーモンセットのすべての状態をクエリーすることもできます。
15.3.3.3. Tang サーバーの一時的な再生成エラーのトラブルシューティング
Tang サーバーのキーの再生成のエラー状態が一時的かどうかを判別するには、以下の手順を実行します。一時的なエラー状態には以下が含まれます。
- 一時的なネットワークの停止
- Tang サーバーのメンテナンス
通常、これらのタイプの一時的なエラー状態が発生した場合には、デーモンセットがエラーを解決して成功するまで待機するか、デーモンセットを削除し、一時的なエラー状態が解決されるまで再試行しないようにします。
手順
- 通常の Kubernetes Pod 再起動ポリシーを使用してキーの再生成操作を実行する Pod を再起動します。
- 関連付けられた Tang サーバーのいずれかが利用できない場合は、すべてのサーバーがオンラインに戻るまでキーの再生成を試みます。
15.3.3.4. Tang サーバーの永続的な再生成エラーのトラブルシューティング
Tang サーバーのキーを再生成した後に、長期間経過しても READY
の数が DESIRED
の数と等しくない場合は、永続的な障害状態を示している可能性があります。この場合、以下のような状況である場合があります。
-
NEW_TANG_PIN
定義で Tang サーバーの URL またはサムプリントの誤字がある。 - Tang サーバーが無効になっているか、キーが完全に失われている。
前提条件
- この手順で説明されているコマンドが、Tang サーバーまたは Tang サーバーへのネットワークアクセスのある Linux システムで実行できる。
手順
デーモンセットの定義に従って各 Tang サーバーの設定に対して単純な暗号化および復号化操作を実行して、Tang サーバー設定を検証します。
これは、不適切なサムプリントで暗号化および復号化を試行する例です。
$ echo "okay" | clevis encrypt tang \ '{"url":"http://tangserver02:7500","thp":"badthumbprint"}' | \ clevis decrypt
出力例
Unable to fetch advertisement: 'http://tangserver02:7500/adv/badthumbprint'!
これは、正常なサムプリントで暗号化および復号化を試行する例です。
$ echo "okay" | clevis encrypt tang \ '{"url":"http://tangserver03:7500","thp":"goodthumbprint"}' | \ clevis decrypt
出力例
okay
根本的な原因を特定した後に、その原因となる状況に対応します。
- 機能しないデーモンセットを削除します。
デーモンセットの定義を編集して基礎となる問題を修正します。これには、以下のアクションのいずれかが含まれる場合があります。
- Tang サーバーのエントリーを編集して URL とサムプリントを修正します。
- 使用されなくなった Tang サーバーを削除します。
- 使用停止したサーバーの代わりとなる、新規の Tang サーバーを追加します。
- 更新されたデーモンセットを再度配布します。
Tang サーバーを設定から置き換え、削除、または追加する場合に、現在キーの再生成が行われているサーバーを含め、少なくとも 1 つの元のサーバーが機能している限り、キーの再生成操作は成功します。元の Tang サーバーのいずれも機能しなくなるか、復元できない場合には、システムの回復は不可能で、影響を受けるノードを再デプロイする必要があります。
検証
デーモンセットの各 Pod からのログをチェックして、キーの再生成が正常に完了したかどうかを判断します。キーの再生成に成功しなかった場合には、その失敗している状態がログに表示される可能性があります。
デーモンセットによって作成されたコンテナーの名前を見つけます。
$ oc get pods -A | grep tang-rekey
出力例
openshift-machine-config-operator tang-rekey-7ks6h 1/1 Running 20 (8m39s ago) 89m
コンテナーからログを印刷します。キーの再生成操作に成功すると、以下のログのようになります。
$ oc logs tang-rekey-7ks6h
出力例
Current tang pin: 1: sss '{"t":1,"pins":{"tang":[{"url":"http://10.46.55.192:7500"},{"url":"http://10.46.55.192:7501"},{"url":"http://10.46.55.192:7502"}]}}' Applying new tang pin: {"t":1,"pins":{"tang":[ {"url":"http://tangserver01:7500","thp":"WOjQYkyK7DxY_T5pMncMO5w0f6E"}, {"url":"http://tangserver02:7500","thp":"I5Ynh2JefoAO3tNH9TgI4obIaXI"}, {"url":"http://tangserver03:7500","thp":"38qWZVeDKzCPG9pHLqKzs6k1ons"} ]}} Updating binding... Binding edited successfully Pin applied successfully
15.3.4. 古い Tang サーバーキーの削除
前提条件
- Tang サーバーを実行する Linux マシンのルートシェル。
手順
Tang サーバーキーが保存されるディレクトリーを見つけ、これにアクセスします。通常、これは
/var/db/tang
ディレクトリーです。# cd /var/db/tang/
現在の Tang サーバーキーをリスト表示し、アドバタイズされたキーと、されていないキーを表示します。
# ls -A1
出力例
.36AHjNH3NZDSnlONLz1-V4ie6t8.jwk .gJZiNPMLRBnyo_ZKfK4_5SrnHYo.jwk Bp8XjITceWSN_7XFfW7WfJDTomE.jwk WOjQYkyK7DxY_T5pMncMO5w0f6E.jwk
古いキーを削除します。
# rm .*.jwk
現在の Tang サーバーのキーをリスト表示し、アドバタイズされていないキーが存在しなくなったことを確認します。
# ls -A1
出力例
Bp8XjITceWSN_7XFfW7WfJDTomE.jwk WOjQYkyK7DxY_T5pMncMO5w0f6E.jwk
検証
この時点では、サーバーは新しいキーを引き続きアドバタイズしますが、古いキーをもとに復号化の試行は失敗します。
Tang サーバーに、現在公開されているキーのサムプリントについてクエリーします。
# tang-show-keys 7500
出力例
WOjQYkyK7DxY_T5pMncMO5w0f6E
先に作成したテストファイルを復号化して、以前のキーに対して復号化を検証します。
# clevis decrypt </tmp/encryptValidation
出力例
Error communicating with the server!
同じキー情報を共有するロードバランサーの背後に複数の Tang サーバーを実行している場合は、続行する前に、一連のサーバーで変更が適切に同期されていることを確認します。