2.4. コンテナーイメージの署名

Red Hat は、Red Hat Container Registry でイメージの署名を提供します。これらの署名は、Machine Config Operator (MCO) を使用して OpenShift Container Platform 4 クラスターにプルされる際に自動的に検証されます。

Quay.io は OpenShift Container Platform を設定するほとんどのイメージを提供し、リリースイメージのみが署名されます。リリースイメージは承認済みの OpenShift Container Platform イメージを参照するため、サプライチェーン攻撃からの一定レベルの保護が得られます。ただし、ロギング、モニタリング、サービスメッシュなどの OpenShift Container Platform への拡張機能の一部は、Operator Lifecycle Manager (OLM) から Operator として提供されます。それらのイメージは、Red Hat Ecosystem Catalog Container イメージ レジストリーから提供されます。

Red Hat レジストリーとインフラストラクチャー間のイメージの整合性を確認するには、署名の検証を有効にします。

2.4.1. Red Hat Container Registry の署名の検証の有効化

Red Hat Container レジストリーのコンテナー署名の検証を有効にするには、これらのレジストリーからのイメージを検証するキーを指定する署名検証ポリシーファイルを作成する必要があります。RHEL8 ノードの場合、レジストリーはデフォルトで /etc/containers/registries.d にすでに定義されています。

手順

  1. ワーカーノードに必要な設定を含む Butane 設定ファイル 51-worker-rh-registry-trust.bu を作成します。

    注記

    Butane の詳細は、Butane を使用したマシン設定の作成を参照してください。

    variant: openshift
    version: 4.12.0
    metadata:
      name: 51-worker-rh-registry-trust
      labels:
        machineconfiguration.openshift.io/role: worker
    storage:
      files:
      - path: /etc/containers/policy.json
        mode: 0644
        overwrite: true
        contents:
          inline: |
            {
              "default": [
                {
                  "type": "insecureAcceptAnything"
                }
              ],
              "transports": {
                "docker": {
                  "registry.access.redhat.com": [
                    {
                      "type": "signedBy",
                      "keyType": "GPGKeys",
                      "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                    }
                  ],
                  "registry.redhat.io": [
                    {
                      "type": "signedBy",
                      "keyType": "GPGKeys",
                      "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                    }
                  ]
                },
                "docker-daemon": {
                  "": [
                    {
                      "type": "insecureAcceptAnything"
                    }
                  ]
                }
              }
            }
  2. Butane を使用して、ワーカーノードのディスクに書き込まれるファイルが含まれるように、マシン設定 YAML ファイル 51-worker-rh-registry-trust.yaml を生成します。

    $ butane 51-worker-rh-registry-trust.bu -o 51-worker-rh-registry-trust.yaml
  3. 作成されたマシン設定を適用します。

    $ oc apply -f 51-worker-rh-registry-trust.yaml
  4. ワーカーマシン設定プールが新しいマシン設定でロールアウトされていることを確認します。

    1. 新しいマシン設定が作成されたことを確認します。

      $ oc get mc

      出力例

      NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
      00-master                                          a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      00-worker                                          a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-master-container-runtime                        a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-master-kubelet                                  a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-worker-container-runtime                        a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-worker-kubelet                                  a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      51-master-rh-registry-trust                                                                   3.2.0             13s
      51-worker-rh-registry-trust                                                                   3.2.0             53s 1
      99-master-generated-crio-seccomp-use-default                                                  3.2.0             25m
      99-master-generated-registries                     a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      99-master-ssh                                                                                 3.2.0             28m
      99-worker-generated-crio-seccomp-use-default                                                  3.2.0             25m
      99-worker-generated-registries                     a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      99-worker-ssh                                                                                 3.2.0             28m
      rendered-master-af1e7ff78da0a9c851bab4be2777773b   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             8s
      rendered-master-cd51fd0c47e91812bfef2765c52ec7e6   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             24m
      rendered-worker-2b52f75684fbc711bd1652dd86fd0b82   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             24m
      rendered-worker-be3b3bce4f4aa52a62902304bac9da3c   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             48s 2

      1
      新しいマシン設定
      2
      新しいレンダリングされたマシン設定
    2. ワーカーマシン設定プールが新しいマシン設定で更新されていることを確認します。

      $ oc get mcp

      出力例

      NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
      master   rendered-master-af1e7ff78da0a9c851bab4be2777773b   True      False      False      3              3                   3                     0                      30m
      worker   rendered-worker-be3b3bce4f4aa52a62902304bac9da3c   False     True       False      3              0                   0                     0                      30m 1

      1
      UPDATING フィールドが True の場合、マシン設定プールは新しいマシン設定で更新されます。フィールドが False になると、ワーカーマシン設定プールが新しいマシン設定にロールアウトされます。
  5. クラスターが RHEL7 ワーカーノードを使用している場合、ワーカーマシンの設定プールが更新されたら、それらのノードに YAML ファイルを /etc/containers/registries.d ディレクトリーに作成します。これにより、特定のレジストリーサーバーの切り離された署名の場所が指定されます。次の例は、registry.access.redhat.com および registry.redhat.io でホストされているイメージに対してのみ機能します。

    1. 各 RHEL7 ワーカーノードへのデバッグセッションを開始します。

      $ oc debug node/<node_name>
    2. ルートディレクトリーを /host に変更します。

      sh-4.2# chroot /host
    3. 以下を含む /etc/containers/registries.d/registry.redhat.io.yaml ファイルを作成します。

      docker:
           registry.redhat.io:
               sigstore: https://registry.redhat.io/containers/sigstore
    4. 以下を含む /etc/containers/registries.d/registry.access.redhat.com.yaml ファイルを作成します。

      docker:
           registry.access.redhat.com:
               sigstore: https://access.redhat.com/webassets/docker/content/sigstore
    5. デバッグセッションを終了します。

2.4.2. 署名の検証設定の確認

マシン設定をクラスターに適用すると、Machine Config Controller は新規の MachineConfig オブジェクトを検出し、新規の rendered-worker-<hash> バージョンを生成します。

前提条件

  • マシン設定ファイルを使用して署名の検証を有効にしている。

手順

  1. コマンドラインで以下のコマンドを実行し、必要なワーカーの情報を表示します。

    $ oc describe machineconfigpool/worker

    初期ワーカーモニタリングの出力例

    Name:         worker
    Namespace:
    Labels:       machineconfiguration.openshift.io/mco-built-in=
    Annotations:  <none>
    API Version:  machineconfiguration.openshift.io/v1
    Kind:         MachineConfigPool
    Metadata:
      Creation Timestamp:  2019-12-19T02:02:12Z
      Generation:          3
      Resource Version:    16229
      Self Link:           /apis/machineconfiguration.openshift.io/v1/machineconfigpools/worker
      UID:                 92697796-2203-11ea-b48c-fa163e3940e5
    Spec:
      Configuration:
        Name:  rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Source:
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         00-worker
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         01-worker-container-runtime
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         01-worker-kubelet
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         51-worker-rh-registry-trust
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         99-worker-92697796-2203-11ea-b48c-fa163e3940e5-registries
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         99-worker-ssh
      Machine Config Selector:
        Match Labels:
          machineconfiguration.openshift.io/role:  worker
      Node Selector:
        Match Labels:
          node-role.kubernetes.io/worker:
      Paused:                              false
    Status:
      Conditions:
        Last Transition Time:  2019-12-19T02:03:27Z
        Message:
        Reason:
        Status:                False
        Type:                  RenderDegraded
        Last Transition Time:  2019-12-19T02:03:43Z
        Message:
        Reason:
        Status:                False
        Type:                  NodeDegraded
        Last Transition Time:  2019-12-19T02:03:43Z
        Message:
        Reason:
        Status:                False
        Type:                  Degraded
        Last Transition Time:  2019-12-19T02:28:23Z
        Message:
        Reason:
        Status:                False
        Type:                  Updated
        Last Transition Time:  2019-12-19T02:28:23Z
        Message:               All nodes are updating to rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Reason:
        Status:                True
        Type:                  Updating
      Configuration:
        Name:  rendered-worker-d9b3f4ffcfd65c30dcf591a0e8cf9b2e
        Source:
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   00-worker
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-container-runtime
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-kubelet
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-92697796-2203-11ea-b48c-fa163e3940e5-registries
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-ssh
      Degraded Machine Count:     0
      Machine Count:              1
      Observed Generation:        3
      Ready Machine Count:        0
      Unavailable Machine Count:  1
      Updated Machine Count:      0
    Events:                       <none>

  2. oc describe コマンドを再度実行します。

    $ oc describe machineconfigpool/worker

    ワーカーの更新後の出力例

    ...
        Last Transition Time:  2019-12-19T04:53:09Z
        Message:               All nodes are updated with rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Reason:
        Status:                True
        Type:                  Updated
        Last Transition Time:  2019-12-19T04:53:09Z
        Message:
        Reason:
        Status:                False
        Type:                  Updating
      Configuration:
        Name:  rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Source:
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   00-worker
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-container-runtime
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-kubelet
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   51-worker-rh-registry-trust
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-92697796-2203-11ea-b48c-fa163e3940e5-registries
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-ssh
      Degraded Machine Count:     0
      Machine Count:              3
      Observed Generation:        4
      Ready Machine Count:        3
      Unavailable Machine Count:  0
      Updated Machine Count:      3
    ...

    注記

    Observed Generation パラメーターは、コントローラーで作成される設定の生成に基づいて増加するカウントを表示します。このコントローラーは、仕様の処理とリビジョンの生成に失敗する場合でも、この値を更新します。Configuration Source 値は 51-worker-rh-registry-trust 設定を参照します。

  3. 以下のコマンドを使用して、policy.json ファイルが存在することを確認します。

    $ oc debug node/<node> -- chroot /host cat /etc/containers/policy.json

    出力例

    Starting pod/<node>-debug ...
    To use host binaries, run `chroot /host`
    {
      "default": [
        {
          "type": "insecureAcceptAnything"
        }
      ],
      "transports": {
        "docker": {
          "registry.access.redhat.com": [
            {
              "type": "signedBy",
              "keyType": "GPGKeys",
              "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
            }
          ],
          "registry.redhat.io": [
            {
              "type": "signedBy",
              "keyType": "GPGKeys",
              "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
            }
          ]
        },
        "docker-daemon": {
          "": [
            {
              "type": "insecureAcceptAnything"
            }
          ]
        }
      }
    }

  4. 以下のコマンドを使用して、registry.redhat.io.yaml ファイルが存在することを確認します。

    $ oc debug node/<node> -- chroot /host cat /etc/containers/registries.d/registry.redhat.io.yaml

    出力例

    Starting pod/<node>-debug ...
    To use host binaries, run `chroot /host`
    docker:
         registry.redhat.io:
             sigstore: https://registry.redhat.io/containers/sigstore

  5. 以下のコマンドを使用して、registry.access.redhat.com.yaml ファイルが存在することを確認します。

    $ oc debug node/<node> -- chroot /host cat /etc/containers/registries.d/registry.access.redhat.com.yaml

    出力例

    Starting pod/<node>-debug ...
    To use host binaries, run `chroot /host`
    docker:
         registry.access.redhat.com:
             sigstore: https://access.redhat.com/webassets/docker/content/sigstore

2.4.3. 検証可能な署名がないコンテナーイメージの検証について

各 OpenShift Container Platform リリースイメージはイミュータブルであり、Red Hat プロダクションキーで署名されています。OpenShift Container Platform の更新またはインストール中に、検証可能な署名がないコンテナーイメージをリリースイメージがデプロイする可能性があります。各署名付きリリースイメージダイジェストはイミュータブルです。リリースイメージ内の各参照は、別のイメージのイミュータブルダイジェストに対するものであるため、コンテンツは推移的に信頼できます。言い換えれば、リリースイメージ上の署名は、すべてのリリース内容を検証します。

たとえば、検証可能な署名がないイメージ参照は、署名付き OpenShift Container Platform リリースイメージに含まれています。

リリース情報の出力例

$ oc adm release info  quay.io/openshift-release-dev/ ocp-release@sha256:2309578b68c5666dad62aed696f1f9d778ae1a089ee461060ba7b9514b7ca417 -o pullspec 1
quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9aafb914d5d7d0dec4edd800d02f811d7383a7d49e500af548eab5d00c1bffdb 2

1
署名付きリリースイメージ SHA。
2
リリースに含まれる検証可能な署名がないコンテナーイメージ。

2.4.3.1. 更新時の自動検証

署名の検証は自動的に行われます。OpenShift Cluster Version Operator (CVO) は、OpenShift Container Platform の更新中にリリースイメージの署名を検証します。これは内部プロセスです。自動検証が失敗すると、OpenShift Container Platform のインストールまたは更新は失敗します。

署名の検証は、skopeo コマンドラインユーティリティーを使用して手動で行うこともできます。

2.4.3.2. skopeo を使用して Red Hat コンテナーイメージの署名を検証する

OpenShift Container Platform リリースイメージに含まれるコンテナーイメージの署名は、OCP リリースミラーサイト から署名を取得して検証できます。ミラーサイトの署名は Podman や CRI-O が理解できる形式ではないため、skopeostandalone-verify コマンドを使用して、リリースイメージが Red Hat によって署名されていることを確認します。

前提条件

  • skopeo コマンドラインユーティリティーがインストールされている。

手順

  1. 次のコマンドを実行して、リリースの完全な SHA を取得します。

    $ oc adm release info <release_version>  \ 1
    1
    <release_version> をリリース番号に置き換えます (例: 4.14.3)。

    出力の抜粋例

    ---
    Pull From: quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55
    ---

  2. 次のコマンドを実行して、Red Hat リリースキーをプルダウンします。

    $ curl -o pub.key https://access.redhat.com/security/data/fd431d51.txt
  3. 次のコマンドを実行して、検証する特定のリリースの署名ファイルを取得します。

    $ curl -o signature-1 https://mirror.openshift.com/pub/openshift-v4/signatures/openshift-release-dev/ocp-release/sha256%<sha_from_version>/signature-1 \ 1
    1
    <sha_from_version> を、リリースの SHA に一致するミラーサイトへの完全なリンクの SHA 値に置き換えます。たとえば、4.12.23 リリースの署名へのリンクは https://mirror.openshift.com/pub/openshift-v4/signatures/openshift-release-dev/ocp-release/sha256%e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55/signature-1、SHA 値は e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55 です。
  4. 次のコマンドを実行して、リリースイメージのマニフェストを取得します。

    $ skopeo inspect --raw docker://<quay_link_to_release> > manifest.json \ 1
    1
    <quay_link_to_release> を、oc adm release info コマンドの出力に置き換えます。たとえば、quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55 です。
  5. skopeo を使用して署名を検証します。

    $ skopeo standalone-verify manifest.json quay.io/openshift-release-dev/ocp-release:<release_number>-<arch> any signature-1 --public-key-file pub.key

    ここでは、以下のようになります。

    <release_number>
    リリース番号を指定します (例: 4.14.3)。
    <arch>

    アーキテクチャーを指定します (例: x86_64)。

    出力例

    Signature verified using fingerprint 567E347AD0044ADE55BA8A5F199E2F91FD431D51, digest sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55

2.4.4. 関連情報