14.3. Tang サーバーの暗号化キー管理

暗号キーを再作成するための暗号化メカニズムは、ノードに保管されている ブラインドキーと関係する Tang サーバーの秘密鍵に基づいています。Tang サーバーの秘密鍵とノードの暗号化ディスクの両方を取得した者による攻撃から保護するには、定期的にキーを再生成することを推奨します。

Tang サーバーから古いキーを削除する前に、すべてのノードでキー変更操作を実行する必要があります。以下のセクションでは、古いキーを再生成し、削除する手順を説明します。

14.3.1. Tang サーバーのキーのバックアップ

Tang サーバーは /usr/libexec/tangd-keygen を使用して新しいキーを生成し、デフォルトで /var/db/tang ディレクトリーに保存します。障害が発生した場合に Tang サーバーを回復するには、このディレクトリーをバックアップします。キーは機密性が高く、使用した全ホストのブートディスクを復号化できるため、キーは適切に保護される必要があります。

手順

  • バックアップキーを /var/db/tang ディレクトリーから、キーを復元できる temp ディレクトリーにコピーします。

14.3.2. Tang サーバーのキーのリカバリー

バックアップからキーにアクセスして、Tang サーバーのキーを回復できます。

手順

  • キーをバックアップフォルダーから /var/db/tang/ ディレクトリーに復元します。

    Tang サーバーの起動時に、これらの復元されたキーをアドバタイズして使用します。

14.3.3. Tang サーバーのキー変更

以下の手順では、例として一意のキーが割り当てられた 3 つの Tang サーバーセットを使用します。

冗長な Tang サーバーを使用すると、ノードの自動起動に失敗する可能性が低減します。

Tang サーバーおよび関連付けられたすべての NBDE 暗号化ノードのキーは 3 つの手順を使用して、再生成します。

前提条件

  • 1 つ以上のノードで機能する Network-Bound Disk Encryption(NBDE) をインストールしておく。

手順

  1. 新しい Tang サーバーキーを生成します。
  2. NBDE で暗号化された全ノードに新規キーを使用するようにキーを再生成します。
  3. 古い Tang サーバーキーを削除します。

    注記

    NBDE で暗号化されたすべてのノードがキーの再生成を完了する前に古いキーを削除すると、それらのノードは他の設定済みの Tang サーバーに過度に依存するようになります。

図14.1 Tang サーバーのキー再生成のワークフロー例

Tang サーバーのキー変更

14.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

手順

  1. Tang サーバーキーの保存先のディレクトリーを見つけてアクセスします。通常、これは /var/db/tang ディレクトリーです。現在公開されているキーのサムプリントを確認します。

    # tang-show-keys 7500

    出力例

    36AHjNH3NZDSnlONLz1-V4ie6t8

  2. Tang サーバーのキーディレクトリーを入力します。

    # cd /var/db/tang/
  3. 現在の Tang サーバーキーを一覧表示します。

    # ls -A1

    出力例

    36AHjNH3NZDSnlONLz1-V4ie6t8.jwk
    gJZiNPMLRBnyo_ZKfK4_5SrnHYo.jwk

    通常の Tang サーバーの操作時に、このディレクトリーには、署名および検証用とキー派生用の 2 つの .jwk ファイルがあります。

  4. 古いキーのアドバタイズを無効にします。

    # for key in *.jwk; do \
      mv -- "$key" ".$key"; \
    done

    Network-Bound Disk Encryption(NBDE) を使用する新規クライアント、またはキーを要求する新規クライアントには古いキーは表示されなくなりました。既存のクライアントは、削除されるまで以前のキーにアクセスして使用できます。Tang サーバーは、. 文字で始まる、UNIX の非表示ファイルに保存されているキーを読み取りますがアドバタイズはしません。

  5. 新しいキーを生成します。

    # /usr/libexec/tangd-keygen /var/db/tang
  6. これらのファイルは非表示になり、新しいキーが存在するので、現在の Tang サーバーキーを一覧表示して古いキーがアドバタイズされなくなったことを確認します。

    # ls -A1

    出力例

    .36AHjNH3NZDSnlONLz1-V4ie6t8.jwk
    .gJZiNPMLRBnyo_ZKfK4_5SrnHYo.jwk
    Bp8XjITceWSN_7XFfW7WfJDTomE.jwk
    WOjQYkyK7DxY_T5pMncMO5w0f6E.jwk

    Tang は、新しいキーを自動的にアドバタイズします。

    注記

    より新しい Tang サーバーのインストールには、アドバタイズを無効にして新規キーを同時に生成するヘルパー /usr/libexec/tangd-rotate-keys ディレクトリーが含まれます。

  7. 同じキー情報を共有するロードバランサーの背後で複数の Tang サーバーを実行している場合は、続行する前に、ここで加えた変更が一連のサーバー全体に適切に同期されていることを確認します。

検証

  1. Tang サーバーが、古いキーではなく、新しいキーをアドバタイズすることを確認します。

    # tang-show-keys 7500

    出力例

    WOjQYkyK7DxY_T5pMncMO5w0f6E

  2. アドバタイズされていない古いキーがまだ復号化要求に使用できることを確認します。

    # clevis decrypt </tmp/encrypted.oldkey

14.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 およびキーのサムプリントを取得します。

手順

  1. 以下のテンプレートに基づいて 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 サーバーの現在のサムプリントも指定する必要があります。キーの再生成操作にすべてのサムプリントの指定に失敗すると、中間者攻撃の可能性が高まります。

  2. キーの再生成が必要なすべてのクラスターにデーモンセットを配布するには、次のコマンドを実行します。

    $ 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 検索を使用して、デーモンセットのすべての状態をクエリーすることもできます。

14.3.3.3. Tang サーバーの一時的な再生成エラーのトラブルシューティング

Tang サーバーのキーの再生成のエラー状態が一時的かどうかを判別するには、以下の手順を実行します。一時的なエラー状態には以下が含まれます。

  • 一時的なネットワークの停止
  • Tang サーバーのメンテナンス

通常、これらのタイプの一時的なエラー状態が発生した場合には、デーモンセットがエラーを解決して成功するまで待機するか、またはデーモンセットを削除し、一時的なエラー状態が解決されるまで再試行しないようにします。

手順

  1. 通常の Kubernetes Pod 再起動ポリシーを使用してキーの再生成操作を実行する Pod を再起動します。
  2. 関連付けられた Tang サーバーのいずれかが利用できない場合は、すべてのサーバーがオンラインに戻るまでキーの再生成を試みます。

14.3.3.4. Tang サーバーの永続的な再生成エラーのトラブルシューティング

Tang サーバーのキーを再生成した後に、長期間経過しても READY の数が DESIRED の数と等しくない場合は、永続的な障害状態を示している可能性があります。この場合、以下のような状況である場合があります。

  • NEW_TANG_PIN 定義で Tang サーバーの URL またはサムプリントの誤字がある。
  • Tang サーバーが無効になっているか、またはキーが完全に失われている。

前提条件

  • この手順で説明されているコマンドが、Tang サーバーまたは Tang サーバーへのネットワークアクセスのある Linux システムで実行できる。

手順

  1. デーモンセットの定義に従って各 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

  2. 根本的な原因を特定した後に、その原因となる状況に対応します。

    1. 機能しないデーモンセットを削除します。
    2. デーモンセットの定義を編集して基礎となる問題を修正します。これには、以下のアクションのいずれかが含まれる場合があります。

      • Tang サーバーのエントリーを編集して URL とサムプリントを修正します。
      • 使用されなくなった Tang サーバーを削除します。
      • 使用停止したサーバーの代わりとなる、新規の Tang サーバーを追加します。
  3. 更新されたデーモンセットを再度配布します。
注記

Tang サーバーを設定から置き換え、削除、または追加する場合に、現在キーの再生成が行われているサーバーを含め、少なくとも 1 つの元のサーバーが機能している限り、キーの再生成操作は成功します。元の Tang サーバーのいずれも機能しなくなるか、または復元できない場合には、システムの回復は不可能で、影響を受けるノードを再デプロイする必要があります。

検証

デーモンセットの各 Pod からのログをチェックして、キーの再生成が正常に完了したかどうかを判断します。キーの再生成に成功しなかった場合には、その失敗している状態がログに表示される可能性があります。

  1. デーモンセットによって作成されたコンテナーの名前を見つけます。

    $ oc get pods -A | grep tang-rekey

    出力例

    openshift-machine-config-operator  tang-rekey-7ks6h  1/1  Running   20 (8m39s ago)  89m

  2. コンテナーからログを印刷します。キーの再生成操作に成功すると、以下のログのようになります。

    $ 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

14.3.4. 古い Tang サーバーキーの削除

前提条件

  • Tang サーバーを実行する Linux マシンのルートシェル。

手順

  1. Tang サーバーキーが保存されるディレクトリーを見つけ、これにアクセスします。通常、これは /var/db/tang ディレクトリーです。

    # cd /var/db/tang/
  2. 現在の Tang サーバーキーを一覧表示し、アドバタイズされたキーと、されていないキーを表示します。

    # ls -A1

    出力例

    .36AHjNH3NZDSnlONLz1-V4ie6t8.jwk
    .gJZiNPMLRBnyo_ZKfK4_5SrnHYo.jwk
    Bp8XjITceWSN_7XFfW7WfJDTomE.jwk
    WOjQYkyK7DxY_T5pMncMO5w0f6E.jwk

  3. 古いキーを削除します。

    # rm .*.jwk
  4. 現在の Tang サーバーのキーを一覧表示し、アドバタイズされていないキーが存在しなくなったことを確認します。

    # ls -A1

    出力例

    Bp8XjITceWSN_7XFfW7WfJDTomE.jwk
    WOjQYkyK7DxY_T5pMncMO5w0f6E.jwk

検証

この時点では、サーバーは新しいキーを引き続きアドバタイズしますが、古いキーをもとに復号化の試行は失敗します。

  1. Tang サーバーに、現在公開されているキーのサムプリントについてクエリーします。

    # tang-show-keys 7500

    出力例

    WOjQYkyK7DxY_T5pMncMO5w0f6E

  2. 先に作成したテストファイルを復号化して、以前のキーに対して復号化を検証します。

    # clevis decrypt </tmp/encryptValidation

    出力例

    Error communicating with the server!

同じキー情報を共有するロードバランサーの背後に複数の Tang サーバーを実行している場合は、続行する前に、一連のサーバーで変更が適切に同期されていることを確認します。