イメージの脆弱性情報を取得

は、

Container Analysis では、Container Registry 内のコンテナ イメージの脆弱性情報を分析して保存します。

このページでは、Container Registry のイメージの脆弱性の表示、フィルタリング、通知の方法について説明します。

はじめに

  1. プロジェクトで Container Analysis API を有効にします。既存のプロジェクトで API を有効にすることも、新しいプロジェクトを作成して API を有効にすることもできます。

    Container Analysis API を有効にする

  2. Container Registry ページの設定で脆弱性スキャンを有効にします。

    脆弱性スキャンを有効にする

  3. Container Analysis の概要をお読みください。

コンテナ イメージの脆弱性を表示する

Container Registry 内のイメージの脆弱性を表示するには、GCP Console、gcloud コマンドライン ツール、Container Analysis API を使用します。

IAM 権限

このタスクを実行するには、次の IAM 権限が必要です。

  • containeranalysis.notes.listOccurrences

または、必要な権限が自動的に付与されるように、次の事前定義された IAM の役割を付与することもできます。

  • Container Analysis 実行回数の閲覧者

Console

  1. GCP Console で Container Registry ページを開きます。

    Container Registry ページを開く

  2. イメージ名をクリックします。

    イメージの脆弱性が [脆弱性] 列に表示されます。

    脆弱性のあるイメージのスクリーンショット

  3. 脆弱性をクリックすると、詳細が表示されます。

gcloud

脆弱性情報の概要を表示するには:

    gcloud alpha container images list-tags --show-occurrences \
        gcr.io/[PROJECT_ID]/[IMAGE_ID]

ここで:

  • [PROJECT_ID] は、イメージを含むプロジェクトの ID です。
  • [IMAGE_ID] は、脆弱性を表示するイメージの ID です。

タグまたはレイヤに関する情報を表示するには:

    gcloud alpha container images describe gcr.io/[PROJECT_ID]/[IMAGE_ID]:[TAG]

または

    gcloud alpha container images describe gcr.io/[PROJECT_ID]/[IMAGE_ID]@sha256:[HASH]

ここで:

  • [PROJECT_ID] は、イメージを含むプロジェクトの ID です。
  • [IMAGE_ID] は、脆弱性を表示するイメージの ID です。
  • [TAG] は、情報を取得するイメージのタグです。
  • [HASH] は、イメージのダイジェストです。

脆弱性をフィルタリングするには:

    gcloud alpha container images list-tags --show-occurrences \
        gcr.io/[PROJECT_ID]/[IMAGE_ID] --occurrence-filter=[FILTER_EXPRESSION]

ここで:

  • [PROJECT_ID] は、イメージを含むプロジェクトの ID です。
  • [IMAGE_ID] は、脆弱性を表示するイメージの ID です。
  • [FILTER_EXPRESSION] はサンプル フィルタ式です。詳細については、サンプル フィルタ式をご覧ください。

API

cURL を使用する

注記を取得するには:

curl -X GET -H "Content-Type: application/json" -H \
    "Authorization: Bearer $(gcloud auth print-access-token)" \
    https://containeranalysis.googleapis.com/v1alpha1/providers/[PROVIDER_PROJECT_ID]/notes/[NOTE_ID]

注記の一覧を表示するには:

curl -X GET -H "Content-Type: application/json" -H \
    "Authorization: Bearer $(gcloud auth print-access-token)" \
    https://containeranalysis.googleapis.com/v1alpha1/providers/[PROVIDER_PROJECT_ID]/notes?filter=[URL_ENCODED_FILTER_EXPRESSION]

オカレンスを取得するには:

curl -X GET -H "Content-Type: application/json" -H \
    "Authorization: Bearer $(gcloud auth print-access-token)" \
    https://containeranalysis.googleapis.com/v1alpha1/projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]

脆弱性のフィルタリング

脆弱性を表示する前にフィルタリングするには、gcloud コマンドと Container Analysis API で正規表現を使用します。いくつかのフィルタ式の例を次に示します。

Debian "Jessie" のすべての脆弱性を一覧表示するには:

vulnerabilityType.details.cpeUri = "cpe:/o:debian:debian_linux:8"

Debian "Jessie" / nginx のすべての脆弱性を一覧表示するには:

vulnerabilityType.details.cpeUri = "cpe:/o:debian:debian_linux:8" AND \
    vulnerabilityType.details.package = "nginx"

バージョン "1.6.2-5" に影響を与える Debian "Jessie" / nginx のすべての脆弱性を一覧表示するには:

vulnerabilityType.details.cpeUri = "cpe:/o:debian:debian_linux:8" AND \
    vulnerabilityType.details.package = "nginx" AND \
    vulnerabilityType.details.fixedLocation.version > version("1.6.2-5")

Debian "Jessie" / nginx で重大度の高いすべての脆弱性を一覧表示するには:

vulnerabilityType.details.cpeUri = "cpe:/o:debian:debian_linux:8" AND \
    vulnerabilityType.details.package = "nginx" AND \
    vulnerabilityType.severity = "HIGH"

resourceUrl のすべての脆弱性のオカレンスを一覧表示するには:

kind="PACKAGE_VULNERABILITY" \
    AND has_prefix(resource_url, "https://gcr.io/path/to/resource")

検出オカレンスの表示

イメージが Container Registry に最初に push されるときに、コンテナ イメージの初期スキャンに関する情報を含めた検出オカレンスが作成されます。

IAM 権限

このタスクを実行するには、次の IAM 権限が必要です。

  • containeranalysis.notes.listOccurrences

または、必要な権限が自動的に付与されるように、次の事前定義された IAM の役割の 1 つを付与することもできます。

  • Container Analysis 実行回数の閲覧者

イメージの検出オカレンスを取得するには、次のフィルタ式を使用します。

kind="DISCOVERY" AND resourceUrl="[RESOURCE_URL]"

次のスニペットでは、上記のフィルタ式を使用してイメージの検出オカレンスを表示する方法を示しています。

API

検出オカレンスを取得するには、次のように上記のフィルタ式を URL エンコード型にして、GET リクエストに埋め込む必要があります。

GET https://containeranalysis.googleapis.com/v1alpha1/projects/PROJECT_ID/occurrences?filter=kind%3D%22DISCOVERY%22%20AND%20resourceUrl%3D%22ENCODED_RESOURCE_URL%22

詳しくは、projects.occurrences.get API エンドポイントをご覧ください。

Java

/**
 * Retrieves and prints the Discovery Occurrence created for a specified image
 * The Discovery Occurrence contains information about the initial scan on the image
 * @param client The Grafeas client used to perform the API requests.
 * @param imageUrl the Container Registry URL associated with the image
 *                 example: "https://gcr.io/project/image@sha256:foo"
 * @param projectId the GCP project the image belongs to
 */
public static void getDiscoveryInfo(GrafeasV1Beta1Client client, String imageUrl,
    String projectId) {
  String filterStr = "kind=\"DISCOVERY\" AND resourceUrl=\"" + imageUrl + "\"";
  final String projectName = ProjectName.format(projectId);

  for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) {
    System.out.println(o);
  }
}

イメージのすべてのオカレンスの表示

IAM 権限

このタスクを実行するには、次の IAM 権限が必要です。

  • containeranalysis.notes.listOccurrences

または、必要な権限が自動的に付与されるように、次の事前定義された IAM の役割の 1 つを付与することもできます。

  • Container Analysis 実行回数の閲覧者

特定のコンテナ イメージに対して検出されたすべてのオカレンスを表示するには、フィルタ式を使用してクエリを作成します。

kind="PACKAGE_VULNERABILITY" \
    AND has_prefix(resource_url, "https://gcr.io/path/to/resource")

次のスニペットでは、上記のフィルタ式を使用してイメージのすべてのオカレンスを表示する方法を示しています。

API

必要なリソース URL は、次のように URL エンコード型にして、GET リクエストに埋め込む必要があります。

GET https://containeranalysis.googleapis.com/v1alpha1/projects/PROJECT_ID/occurrences?filter=resourceUrl%3D%22ENCODED_RESOURCE_URL%22

詳しくは、projects.occurrences.get API エンドポイントをご覧ください。

Java

/**
 * Retrieves all the Occurrences associated with a specified image
 * Here, all Occurrences are simply printed and counted
 * @param client The Grafeas client used to perform the API requests.
 * @param imageUrl the Container Registry URL associated with the image
 *                 example: "https://gcr.io/project/image@sha256:foo"
 * @param projectId the GCP project to search for Occurrences in
 * @return number of Occurrences found
 */
public static int getOccurrencesForImage(GrafeasV1Beta1Client client, String imageUrl,
    String projectId) {
  final String filterStr = "resourceUrl=\"" + imageUrl + "\"";
  final String projectName = ProjectName.format(projectId);
  int i = 0;

  for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) {
    // Write custom code to process each Occurrence here
    System.out.println(o.getName());
    i = i + 1;
  }
  return i;
}

Cloud Pub/Sub の通知

IAM 権限: このタスクを実行するには、適切な IAM 権限が必要です。必要な権限と役割の詳細については、PUB/ SUB で使用する IAM 権限をご覧ください。

Container Registry は、脆弱性のスキャン時に Cloud Pub/Sub 経由で通知を送信します。Container Analysis API を有効にすると、次の Cloud Pub/Sub トピックがプロジェクトに作成されます。

  • resource-notes-occurrences-v1alpha1

オカレンスが作成または更新されるたびに、それぞれのトピックにメッセージがパブリッシュされます。

Pub/Sub ペイロードは JSON 形式で、スキーマは次のとおりです。

{
    "occurrenceName": "projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]"
}

こうしたイベントをリッスンするには、トピックに関連付けられた Pub/Sub サブスクリプションを作成し、到着時に通知を処理できる MessageReceiver サブクラスを作成します。次のサンプルでは、MessageReceiver によってメッセージの到着時にログに記録され、カウントされます。

API

Cloud Pub/Sub イベントを受信するには、まず resource-notes-occurrences-v1alpha1 トピックに関連付けられたサブスクリプションを作成する必要があります。

gcloud beta pubsub subscriptions create
--topic resource-notes-occurrences-v1alpha1 occurrences

新しいサブスクリプションを使用して、オカレンスに関するメッセージを pull できるようになります。

gcloud beta pubsub subscriptions pull
--auto-ack occurrences

Java

/**
 * Handle incoming Occurrences using a Cloud Pub/Sub subscription
 * @param subId the user-specified identifier for the Pub/Sub subscription
 * @param timeout the amount of time to listen for Pub/Sub messages (in seconds)
 * @param projectId the GCP project the Pub/Sub subscription belongs to
 * @return number of Occurrence Pub/Sub messages received before exiting
 * @throws InterruptedException on errors with the subscription client
 */
public static int pubSub(String subId, int timeout, String projectId)
    throws InterruptedException {
  Subscriber subscriber = null;
  MessageReceiverExample receiver = new MessageReceiverExample();

  try {
    // Subscribe to the requested Pub/Sub channel
    ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId);
    subscriber = Subscriber.newBuilder(subName, receiver).build();
    subscriber.startAsync().awaitRunning();
    // Listen to messages for 'timeout' seconds
    for (int i = 0; i < timeout; i++) {
      sleep(1000);
    }
  } finally {
    // Stop listening to the channel
    if (subscriber != null) {
      subscriber.stopAsync();
    }
  }
  // Print and return the number of Pub/Sub messages received
  System.out.println(receiver.messageCount);
  return receiver.messageCount;
}

/**
 * Custom class to handle incoming Pub/Sub messages
 * In this case, the class will simply log and count each message as it comes in
 */
static class MessageReceiverExample implements MessageReceiver {
  public int messageCount = 0;

  @Override
  public synchronized void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
    // Every time a Pub/Sub message comes in, print it and count it
    System.out.println("Message " + messageCount + ": " + message.getData().toStringUtf8());
    messageCount += 1;
    // Acknowledge the message
    consumer.ack();
  }
}

/**
 * Creates and returns a Pub/Sub subscription object listening to the Occurrence topic
 * @param subId the identifier you want to associate with the subscription
 * @param projectId the GCP project to create the subscription under
 * @throws IOException thrown on errors with the subscription client
 * @throws StatusRuntimeException if subscription already exists
 *
 */
public static Subscription createOccurrenceSubscription(String subId, String projectId)
    throws IOException, StatusRuntimeException {
  // This topic id will automatically receive messages when Occurrences are added or modified
  String topicId = "container-analysis-occurrences-v1beta1";
  SubscriptionAdminClient client = SubscriptionAdminClient.create();
  PushConfig config = PushConfig.getDefaultInstance();
  ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
  ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId);
  Subscription sub = client.createSubscription(subName, topicName, config, 0);
  return sub;
} 

サブスクライバー アプリケーションで使用できるのは、サブスクリプションの作成後にトピックにパブリッシュしたメッセージだけです。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...