Tutoriel : Obtenir les failles détectées sur les images

Ce tutoriel explique comment utiliser Container Analysis pour analyser les failles d'une image de conteneur stockée dans Container Registry, puis répertorier les failles sévères détectées sur celle-ci.

Objectifs

Ce tutoriel couvre les étapes suivantes :

  1. Créer une image Docker avec des failles connues ;
  2. stocker l'image dans le registre Container Registry de votre projet ;
  3. interroger Container Analysis pour compléter l'analyse initiale et l'analyse de l'image ;
  4. afficher les failles identifiées par Container Analysis ;
  5. répertorier les failles sévères sur l'image.

Coûts

Ce tutoriel utilise des composants facturables de Google Cloud. Pour en savoir plus sur la tarification, consultez la page Tarifs.

Remarque : La facturation commence immédiatement après l'activation de l'API Container Scanning. Une fois l'API activée, Container Analysis analyse automatiquement toute nouvelle image envoyée, mais n'analyse pas automatiquement les images existantes. Pour qu'une image existante soit analysée, vous devez l'envoyer à nouveau.

Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

Pour utiliser Container Analysis, vous devez activer et configurer Container Analysis et Container Registry.

  1. Connectez-vous à votre compte Google.

    Si vous n'en possédez pas déjà un, vous devez en créer un.

  2. Dans Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Cloud.

    Accéder à la page de sélection du projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Activez les Container Registry and Container Scanning API.

    Activer les API

  5. Installez et initialisez le SDK Cloud.
  6. Si vous ne l'avez pas déjà fait, effectuez l'une des opérations suivantes pour obtenir les autorisations IAM requises. Si vous êtes le propriétaire du projet, ignorez cette étape.
    • Pour afficher des occurrences, vous devez avoir les autorisations suivantes :
      containeranalysis.notes.listOccurrences
    • Vous pouvez également attribuer le rôle IAM prédéfini suivant, qui accordera automatiquement toutes les autorisations nécessaires :
      Container Analysis Occurrences Viewer
  7. Installez Docker. Si vous utilisez un système d'exploitation basé sur Linux, tel que Ubuntu ou Debian, ajoutez votre nom d'utilisateur au groupe docker afin de pouvoir exécuter Docker sans utiliser la commande sudo :
    sudo usermod -a -G docker ${USER}

    Une fois que vous vous serez ajouté au groupe docker, vous devrez peut-être redémarrer votre système.

  8. Ouvrez Docker. Pour vérifier que Docker est en cours d'exécution, exécutez la commande Docker suivante, qui renvoie la date et l'heure actuelles :
  9. docker run busybox date

Créer une image Docker

Pour ce tutoriel, générez l'image Docker suivante pour avoir une image à stocker dans Container Registry. Vous utilisez un environnement d'exécution Python avec des failles connues que Container Analysis identifie. L'image Docker contient une petite application Web en Python. Cette application utilise le framework Web Flask pour diffuser une page Web qui affiche le message "Hello, World!"

Pour créer l'image Docker, procédez comme suit :

  1. Créez un répertoire destiné à stocker les trois fichiers d'image Docker.

  2. Dans ce répertoire, créez les trois fichiers suivants : Dockerfile, requirements.txt et app.py. Les exemples ci-dessous décrivent le contenu que vous devez créer pour chacun de ces fichiers :

Dockerfile

# The file Dockerfile defines the image's environment
    # Import Python runtime and set up working directory
    # This specified runtime has known vulnerabilities so that vulnerability
    # scanning can be tested.
    FROM python:3.5-slim
    WORKDIR /app
    ADD . /app

    # Install any necessary dependencies
    RUN pip install -r requirements.txt

    # Open port 80 for serving the webpage
    EXPOSE 80

    # Run app.py when the container launches
    CMD ["python", "app.py"]
    

requirements.txt

# The file requirements.txt defines the image's dependencies
    Flask
    

app.py

# The Docker image contains the following code in app.py
    from flask import Flask
    import os
    import socket

    app = Flask(__name__)

    @app.route("/")
    def hello():
        html = "<h3>Hello, World!</h3>"
        return html

    if __name__ == "__main__":
      app.run(host='0.0.0.0', port=80)
    

Pour créer l'image Docker, exécutez la commande Docker suivante depuis le répertoire contenant les fichiers de l'image :

docker build -t vulnerabilities-tutorial-image .
    

Vous avez maintenant créé une image Docker sur votre ordinateur local.

Ajouter l'image dans Container Registry

Configurer docker pour utiliser l'outil de ligne de commande gcloud en tant qu'assistant d'identification

Avant de pouvoir stocker ou extraire des images, vous devez configurer Docker afin qu'il se serve de l'outil de ligne de commande gcloud pour authentifier les requêtes envoyées à Container Registry. Pour ce faire, exécutez la commande suivante (vous n'avez besoin de l'exécuter qu'une seule fois) :

gcloud auth configure-docker
    

Ajouter un tag de nom de registre à l'image

Avant de stocker l'image Docker dans Container Registry, vous devez lui ajouter un tag correspondant à son nom de registre. Cette action permet de configurer la commande docker push grâce à laquelle vous pouvez stocker l'image dans un emplacement précis. L'emplacement d'hôte utilisé dans ce guide de démarrage rapide est gcr.io.

Pour ajouter le tag à l'image Docker, exécutez la commande suivante :

docker tag vulnerabilities-tutorial-image gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image:tag1
    

où :

  • [PROJECT-ID] est l'ID de votre projet dans Google Cloud Console, que vous devez ajouter à la commande.
  • gcr.io correspond au nom d'hôte.
  • vulnerabilities-tutorial-image est le nom de l'image Docker.
  • tag1 est un tag que vous ajoutez à l'image Docker. Si vous ne spécifiez pas de tag, Docker applique le tag par défaut latest.

Vous êtes maintenant prêt à stocker votre image dans Container Registry.

Stocker l'image dans Container Registry

Une fois que vous avez configuré docker pour utiliser gcloud en tant qu'assistant d'identification et que vous avez ajouté un tag de nom de registre à l'image locale, vous pouvez stocker celle-ci dans Container Registry.

Pour stocker l'image Docker, exécutez la commande suivante :

docker push gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image:tag1
    

[PROJECT-ID] est l'ID du projet dans Google Cloud Console. Si l'ID du projet contient le signe deux-points (:), consultez la section Projets à l'échelle du domaine.

Lorsque vous stockez une image dans un nouvel emplacement hôte, le service crée un bucket de stockage sous-jacent unique pour votre projet. Vous pouvez afficher les images hébergées par Container Registry en accédant à Cloud Console ou en saisissant le nom du registre de l'image dans votre navigateur Web : http://gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image.

Vérifier le condensé de l'image

À l'étape suivante, vous aurez besoin du récapitulatif SHA256 de l'image. Il s'agit d'un hachage de l'image générée lorsque vous la transférez dans un registre.

Bien qu'il soit possible d'utiliser un tag pour marquer différentes versions à différents moments, un condensé est toujours propre à une version d'image.

curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https://gcr.io/v2/[PROJECT-ID]/vulnerabilities-tutorial-image/tags/list
    

La réponse renvoyée est un objet JSON contenant des informations sur les différentes versions de l'image que vous avez importée, ainsi que les tags associés.

{
      "child": [],
      "manifest": {
        "sha256:1e70b945e7266268e35b3db3ddc5c13e88fe4e42ee6ffbfa8962ec0b1562b51a": {
          "imageSizeBytes": "2803075",
          "layerId": "",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "tag": [],
          "timeCreatedMs": "1583923219860",
          "timeUploadedMs": "1583923231051"
        },
        "sha256:95d270793da3f9eb77ae6c0ebe84beaaa84a66c331c3fb2205f8645646568a98": {
          "imageSizeBytes": "61212796",
          "layerId": "",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "tag": [
            "tag1"
          ],
          "timeCreatedMs": "1583923518920",
          "timeUploadedMs": "1583923552668"
        }
      },
      "name": "[PROJECT-ID]/vulnerabilities-tutorial-image",
      "tags": [
        "tag1"
      ]
    }
    

Vous pouvez par exemple l'analyser à l'aide de l'outil JQ :

curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https://gcr.io/v2/[PROJECT-ID]/vulnerabilities-tutorial-image/tags/list | jq  '.manifest | to_entries[] | select(.value.tag | contains(["tag1"])) | .key'
    

Utiliser le sondage pour l'analyse initiale et les résultats d'analyse

Container Analysis effectue automatiquement une première analyse et une analyse de l'image. Il crée une occurrence de découverte qui inclut les informations collectées à partir de cette analyse initiale. Container Analysis met également à jour l'occurrence de découverte avec l'état actuel de l'analyse.

L'exemple de code suivant interroge l'état actuel de l'analyse initiale afin de savoir quand les informations sur les failles peuvent être visualisées.

Java

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Java.

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
    import io.grafeas.v1.DiscoveryOccurrence;
    import io.grafeas.v1.DiscoveryOccurrence.AnalysisStatus;
    import io.grafeas.v1.GrafeasClient;
    import io.grafeas.v1.Occurrence;
    import io.grafeas.v1.ProjectName;
    import java.io.IOException;
    import java.lang.InterruptedException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;

    public class PollDiscoveryOccurrenceFinished {
      // Repeatedly query the Container Analysis API for the latest discovery occurrence until it is
      // either in a terminal state, or the timeout value has been exceeded
      public static Occurrence pollDiscoveryOccurrenceFinished(String resourceUrl, String projectId,
          long timeoutSeconds) throws IOException, TimeoutException, InterruptedException {
        // String resourceUrl = "https://gcr.io/project/image@sha256:123";
        // String projectId = "my-project-id";
        // long timeoutSeconds = 30;
        final String projectName = ProjectName.format(projectId);
        long deadline = System.currentTimeMillis() + timeoutSeconds * 1000;

        // Initialize client that will be used to send requests. After completing all of your requests,
        // call the "close" method on the client to safely clean up any remaining background resources.
        GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();

        // find the discovery occurrence using a filter string
        Occurrence discoveryOccurrence = null;
        // vulbnerability discovery occurrences are always associated with the
        // PACKAGE_VULNERABILITY note in the "goog-analysis" GCP project
        String filter =  String.format("resourceUrl=\"%s\" AND noteProjectId=\"%s\" AND noteId=\"%s\"",
            resourceUrl, "goog-analysis",  "PACKAGE_VULNERABILITY");
        while (discoveryOccurrence == null) {
          for (Occurrence o : client.listOccurrences(projectName, filter).iterateAll()) {
            if (o.getDiscovery() != null) {
              // there should be only one valid discovery occurrence returned by the given filter
              discoveryOccurrence = o;
            }
          }
          TimeUnit.SECONDS.sleep(1);
          // check for timeout
          if (System.currentTimeMillis() > deadline) {
            throw new TimeoutException("discovery occurrence not found");
          }
        }

        // wait for discovery occurrence to enter a terminal state
        AnalysisStatus status = AnalysisStatus.PENDING;
        while (status != AnalysisStatus.FINISHED_SUCCESS
            && status != AnalysisStatus.FINISHED_FAILED
            && status != AnalysisStatus.FINISHED_UNSUPPORTED) {
          // update the occurrence state
          discoveryOccurrence = client.getOccurrence(discoveryOccurrence.getName());
          status = discoveryOccurrence.getDiscovery().getAnalysisStatus();
          TimeUnit.SECONDS.sleep(1);
          // check for timeout
          if (System.currentTimeMillis() > deadline) {
            throw new TimeoutException("discovery occurrence not in terminal state");
          }
        }
        return discoveryOccurrence;
      }
    }

Go

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Go.


    import (
    	"context"
    	"fmt"
    	"time"

    	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
    	"google.golang.org/api/iterator"
    	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
    )

    // pollDiscoveryOccurrenceFinished returns the discovery occurrence for a resource once it reaches a finished state.
    func pollDiscoveryOccurrenceFinished(resourceURL, projectID string, timeout time.Duration) (*grafeaspb.Occurrence, error) {
    	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
    	// timeout := time.Duration(5) * time.Second
    	ctx, cancel := context.WithTimeout(context.Background(), timeout)
    	defer cancel()

    	client, err := containeranalysis.NewClient(ctx)
    	if err != nil {
    		return nil, fmt.Errorf("NewClient: %v", err)
    	}
    	defer client.Close()

    	// ticker is used to poll once per second.
    	ticker := time.NewTicker(1 * time.Second)
    	defer ticker.Stop()

    	// Find the discovery occurrence using a filter string.
    	var discoveryOccurrence *grafeaspb.Occurrence
    	for discoveryOccurrence == nil {
    		select {
    		case <-ctx.Done():
    			return nil, fmt.Errorf("timeout while retrieving discovery occurrence")
    		case <-ticker.C:
    			req := &grafeaspb.ListOccurrencesRequest{
    				Parent: fmt.Sprintf("projects/%s", projectID),
    				// Vulnerability discovery occurrences are always associated with the
    				// PACKAGE_VULNERABILITY note in the "goog-analysis" GCP project.
    				Filter: fmt.Sprintf(`resourceUrl=%q AND noteProjectId="goog-analysis" AND noteId="PACKAGE_VULNERABILITY"`, resourceURL),
    			}
    			it := client.GetGrafeasClient().ListOccurrences(ctx, req)
    			// Only one occurrence should ever be returned by ListOccurrences
    			// and the given filter.
    			result, err := it.Next()
    			if err == iterator.Done {
    				break
    			}
    			if err != nil {
    				return nil, fmt.Errorf("it.Next: %v", err)
    			}
    			if result.GetDiscovery() != nil {
    				discoveryOccurrence = result
    			}
    		}
    	}

    	// Wait for the discovery occurrence to enter a terminal state.
    	for {
    		select {
    		case <-ctx.Done():
    			return nil, fmt.Errorf("timeout waiting for terminal state")
    		case <-ticker.C:
    			// Update the occurrence.
    			req := &grafeaspb.GetOccurrenceRequest{Name: discoveryOccurrence.GetName()}
    			updated, err := client.GetGrafeasClient().GetOccurrence(ctx, req)
    			if err != nil {
    				return nil, fmt.Errorf("GetOccurrence: %v", err)
    			}
    			switch updated.GetDiscovery().GetAnalysisStatus() {
    			case grafeaspb.DiscoveryOccurrence_FINISHED_SUCCESS,
    				grafeaspb.DiscoveryOccurrence_FINISHED_FAILED,
    				grafeaspb.DiscoveryOccurrence_FINISHED_UNSUPPORTED:
    				return discoveryOccurrence, nil
    			}
    		}
    	}
    }
    

Node.js

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Node.js.

/**
     * TODO(developer): Uncomment these variables before running the sample
     */
    // const projectId = 'your-project-id', // Your GCP Project ID
    // const imageUrl = 'https://gcr.io/my-project/my-image:123', // Image to attach metadata to
    // const retries = 5 // The number of retries to listen for the new Pub/Sub messages

    // Import the library and create a client
    const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
    const client = new ContainerAnalysisClient();

    const formattedParent = client.getGrafeasClient().projectPath(projectId);

    let filter = `resourceUrl="${imageUrl}" AND noteProjectId="goog-analysis" AND noteId="PACKAGE_VULNERABILITY"`;

    // Repeatedly query the Container Analysis API for the latest discovery occurrence until it is
    // either in a terminal state, or the timeout value has been exceeded
    const pRetry = require('p-retry');
    const discoveryOccurrence = await pRetry(
      async () => {
        const [occurrences] = await client.getGrafeasClient().listOccurrences({
          parent: formattedParent,
          filter: filter,
        });
        if (occurrences.length < 0) {
          throw new Error('No occurrences found for ' + imageUrl);
        }
        return occurrences[0];
      },
      {
        retries: retries,
      }
    );

    // Wait for discovery occurrence to enter a terminal state or the timeout value has been exceeded
    const finishedOccurrence = await pRetry(
      async () => {
        let status = 'PENDING';
        const [updated] = await client.getGrafeasClient().getOccurrence({
          name: discoveryOccurrence.name,
        });
        status = updated.discovery.analysisStatus;
        if (
          status !== 'FINISHED_SUCCESS' &&
          status !== 'FINISHED_FAILED' &&
          status !== 'FINISHED_UNSUPPORTED'
        ) {
          throw new Error('Timeout while retrieving discovery occurrence');
        }
        return updated;
      },
      {
        retries: retries,
      }
    );
    console.log(
      `Found discovery occurrence ${finishedOccurrence.name}.  Status: ${finishedOccurrence.discovery.analysisStatus}`
    );

Ruby

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Ruby.

# resource_url    = "The URL of the resource associated with the occurrence.
    #                    e.g. https://gcr.io/project/image@sha256:123"
    # timeout_seconds = "The number of seconds to wait for the discovery
    #                    occurrence"
    # project_id      = "Your Google Cloud project ID"

    require "grafeas"

    deadline = Time.now + timeout_seconds

    # Initialize the client
    client = Grafeas.new
    formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id

    # Find the discovery occurrence using a filter string
    discovery_occurrence = nil
    while discovery_occurrence.nil?
      begin
        filter = 'resourceUrl="#{resource_url}" ' \
                 'AND noteProjectId="goog-analysis" ' \
                 'AND noteId="PACKAGE_VULNERABILITY"'
        # Only the discovery occurrence should be returned for the given filter
        discovery_occurrence = client.list_occurrences(formatted_parent, filter: filter).first
      rescue StandardError # If there is an error, keep trying until the deadline
        puts "discovery occurrence not yet found"
      ensure
        # check for timeout
        sleep 1
        if Time.now > deadline
          raise "Timeout while retrieving discovery occurrence."
        end
      end
    end

    # Wait for the discovery occurrence to enter a terminal state
    status = Grafeas::V1::DiscoveryOccurrence::AnalysisStatus::PENDING
    while status != :FINISHED_SUCCESS &&
          status != :FINISHED_FAILED &&
          status != :FINISHED_UNSUPPORTED
      # Update occurrence
      begin
        updated = client.get_occurrence discovery_occurrence.name
        status = updated.discovery.analysis_status
      rescue StandardError # If there is an error, keep trying until the deadline
        puts "discovery occurrence not yet in terminal state"
      ensure
        # check for timeout
        sleep 1
        if Time.now > deadline
          raise "Timeout while retrieving discovery occurrence."
        end
      end
    end
    puts "Found discovery occurrence #{updated.name}."
    puts "Status: #{updated.discovery.analysis_status}"

Python

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Python.

def poll_discovery_finished(resource_url, timeout_seconds, project_id):
        """Returns the discovery occurrence for a resource once it reaches a
        terminal state."""
        # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
        # timeout_seconds = 20
        # project_id = 'my-gcp-project'

        import time
        from grafeas.grafeas_v1.gapic.enums import DiscoveryOccurrence
        from google.cloud.devtools import containeranalysis_v1

        deadline = time.time() + timeout_seconds

        client = containeranalysis_v1.ContainerAnalysisClient()
        grafeas_client = client.get_grafeas_client()
        project_name = grafeas_client.project_path(project_id)

        discovery_occurrence = None
        while discovery_occurrence is None:
            time.sleep(1)
            filter_str = 'resourceUrl="{}" \
                          AND noteProjectId="goog-analysis" \
                          AND noteId="PACKAGE_VULNERABILITY"'.format(resource_url)
            result = grafeas_client.list_occurrences(project_name, filter_str)
            # only one occurrence should ever be returned by ListOccurrences
            # and the given filter
            for item in result:
                discovery_occurrence = item
            if time.time() > deadline:
                raise RuntimeError('timeout while retrieving discovery occurrence')

        status = DiscoveryOccurrence.AnalysisStatus.PENDING
        while status != DiscoveryOccurrence.AnalysisStatus.FINISHED_UNSUPPORTED \
                and status != DiscoveryOccurrence.AnalysisStatus.FINISHED_FAILED \
                and status != DiscoveryOccurrence.AnalysisStatus.FINISHED_SUCCESS:
            time.sleep(1)
            updated = grafeas_client.get_occurrence(discovery_occurrence.name)
            status = updated.discovery.analysis_status
            if time.time() > deadline:
                raise RuntimeError('timeout while waiting for terminal state')
        return discovery_occurrence

Lorsque le statut de l'analyse est FINISHED_SUCCESS, vous êtes prêt à afficher la liste des failles.

Répertorier toutes les failles associées à une image

Les failles connues sont stockées sous forme de notes. Container Analysis crée une occurrence pour chaque instance d'une note trouvée lors de l'analyse de l'image. Au fur et à mesure que Container Analysis recueille de nouvelles informations sur les failles, il met automatiquement à jour la liste des occurrences.

Vous pouvez récupérer des informations sur les notes et les occurrences à l'aide de la console GCP, de l'outil de ligne de commande gcloud ou de l'API Container Analysis. De plus, l'API est compatible avec un certain nombre d'expressions de filtre permettant de récupérer des informations spécifiques sur les notes ou les occurrences.

L'exemple de code suivant récupère les failles détectées pour une image.

Java

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Java.

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
    import io.grafeas.v1.GrafeasClient;
    import io.grafeas.v1.Occurrence;
    import io.grafeas.v1.ProjectName;
    import java.io.IOException;
    import java.util.LinkedList;
    import java.util.List;

    public class VulnerabilityOccurrencesForImage {
      // Retrieve a list of vulnerability occurrences assoviated with a resource
      public static List<Occurrence> findVulnerabilityOccurrencesForImage(String resourceUrl,
          String projectId) throws IOException {
        // String resourceUrl = "https://gcr.io/project/image@sha256:123";
        // String projectId = "my-project-id";
        final String projectName = ProjectName.format(projectId);
        String filterStr = String.format("kind=\"VULNERABILITY\" AND resourceUrl=\"%s\"", resourceUrl);

        // Initialize client that will be used to send requests. After completing all of your requests,
        // call the "close" method on the client to safely clean up any remaining background resources.
        GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
        LinkedList<Occurrence> vulnerabilitylist = new LinkedList<Occurrence>();
        for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) {
          vulnerabilitylist.add(o);
        }
        return vulnerabilitylist;
      }
    }

Go

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Go.


    import (
    	"context"
    	"fmt"

    	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
    	"google.golang.org/api/iterator"
    	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
    )

    // findVulnerabilityOccurrencesForImage retrieves all vulnerability Occurrences associated with a resource.
    func findVulnerabilityOccurrencesForImage(resourceURL, projectID string) ([]*grafeaspb.Occurrence, error) {
    	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
    	ctx := context.Background()
    	client, err := containeranalysis.NewClient(ctx)
    	if err != nil {
    		return nil, fmt.Errorf("NewClient: %v", err)
    	}
    	defer client.Close()

    	req := &grafeaspb.ListOccurrencesRequest{
    		Parent: fmt.Sprintf("projects/%s", projectID),
    		Filter: fmt.Sprintf("resourceUrl = %q kind = %q", resourceURL, "VULNERABILITY"),
    	}

    	var occurrenceList []*grafeaspb.Occurrence
    	it := client.GetGrafeasClient().ListOccurrences(ctx, req)
    	for {
    		occ, err := it.Next()
    		if err == iterator.Done {
    			break
    		}
    		if err != nil {
    			return nil, fmt.Errorf("occurrence iteration error: %v", err)
    		}
    		occurrenceList = append(occurrenceList, occ)
    	}

    	return occurrenceList, nil
    }
    

Node.js

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Node.js.

/**
     * TODO(developer): Uncomment these variables before running the sample
     */
    // const projectId = 'your-project-id', // Your GCP Project ID
    // const imageUrl = 'https://gcr.io/my-project/my-image:123' // Image to attach metadata to

    // Import the library and create a client
    const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
    const client = new ContainerAnalysisClient();

    const formattedParent = client.getGrafeasClient().projectPath(projectId);

    // Retrieve a list of vulnerability occurrences assoviated with a resource
    const [occurrences] = await client.getGrafeasClient().listOccurrences({
      parent: formattedParent,
      filter: `kind = "VULNERABILITY" AND resourceUrl = "${imageUrl}"`,
    });

    if (occurrences.length) {
      console.log(`All Vulnerabilities for ${imageUrl}`);
      occurrences.forEach(occurrence => {
        console.log(`${occurrence.name}:`);
      });
    } else {
      console.log('No occurrences found.');
    }

Ruby

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Ruby.

# resource_url = "The URL of the resource associated with the occurrence
    #                e.g. https://gcr.io/project/image@sha256:123"
    # project_id   = "The Google Cloud project ID of the vulnerabilities to find"

    require "grafeas"

    # Initialize the client
    client = Grafeas.new

    formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
    filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
    client.list_occurrences formatted_parent, filter: filter

Python

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Python.

def find_vulnerabilities_for_image(resource_url, project_id):
        """"Retrieves all vulnerability occurrences associated with a resource."""
        # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
        # project_id = 'my-gcp-project'

        from google.cloud.devtools import containeranalysis_v1

        client = containeranalysis_v1.ContainerAnalysisClient()
        grafeas_client = client.get_grafeas_client()
        project_name = grafeas_client.project_path(project_id)

        filter_str = 'kind="VULNERABILITY" AND resourceUrl="{}"'\
            .format(resource_url)
        return list(grafeas_client.list_occurrences(project_name, filter_str))

Répertorier les failles sévères

Un niveau de gravité est associé à chaque faille. Container Analysis utilise les informations de niveau de gravité fournies par les distributions Linux compatibles. Si les niveaux de gravité propres à la distribution ne sont pas disponibles, les niveaux attribués sont basés sur les scores CVSS.

Pour définir les priorités de correction des failles, vous pouvez affiner votre liste de failles pour n'afficher que les failles sévères.

L'exemple de code suivant récupère la liste des failles pour une image présentant des failles sévères ou critiques.

Java

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Java.

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
    import io.grafeas.v1.GrafeasClient;
    import io.grafeas.v1.Occurrence;
    import io.grafeas.v1.ProjectName;
    import io.grafeas.v1.Severity;
    import java.io.IOException;
    import java.util.LinkedList;
    import java.util.List;

    public class HighVulnerabilitiesForImage {
      // Retrieve a list of vulnerability occurrences with a severity level of 'HIGH' or greater
      public static List<Occurrence> findHighSeverityVulnerabilitiesForImage(String resourceUrl,
          String projectId) throws IOException {
        // String resourceUrl = "https://gcr.io/project/image@sha256:123";
        // String projectId = "my-project-id";
        final String projectName = ProjectName.format(projectId);
        String filterStr = String.format("kind=\"VULNERABILITY\" AND resourceUrl=\"%s\"", resourceUrl);

        // Initialize client that will be used to send requests. After completing all of your requests,
        // call the "close" method on the client to safely clean up any remaining background resources.
        GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
        LinkedList<Occurrence> vulnerabilitylist = new LinkedList<Occurrence>();
        for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) {
          Severity severity = o.getVulnerability().getSeverity();
          if (severity == Severity.HIGH || severity == Severity.CRITICAL) {
            vulnerabilitylist.add(o);
          }
        }
        return vulnerabilitylist;
      }
    }

Go

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Go.


    import (
    	"context"
    	"fmt"

    	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
    	"google.golang.org/api/iterator"
    	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
    )

    // findHighSeverityVulnerabilitiesForImage retrieves a list of only high vulnerability occurrences associated with a resource.
    func findHighSeverityVulnerabilitiesForImage(resourceURL, projectID string) ([]*grafeaspb.Occurrence, error) {
    	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
    	ctx := context.Background()
    	client, err := containeranalysis.NewClient(ctx)
    	if err != nil {
    		return nil, fmt.Errorf("NewClient: %v", err)
    	}
    	defer client.Close()

    	req := &grafeaspb.ListOccurrencesRequest{
    		Parent: fmt.Sprintf("projects/%s", projectID),
    		Filter: fmt.Sprintf("resourceUrl = %q kind = %q", resourceURL, "VULNERABILITY"),
    	}

    	var occurrenceList []*grafeaspb.Occurrence
    	it := client.GetGrafeasClient().ListOccurrences(ctx, req)
    	for {
    		occ, err := it.Next()
    		if err == iterator.Done {
    			break
    		}
    		if err != nil {
    			return nil, fmt.Errorf("occurrence iteration error: %v", err)
    		}

    		severityLevel := occ.GetVulnerability().GetEffectiveSeverity()
    		if severityLevel == grafeaspb.Severity_HIGH || severityLevel == grafeaspb.Severity_CRITICAL {
    			occurrenceList = append(occurrenceList, occ)
    		}
    	}

    	return occurrenceList, nil
    }
    

Node.js

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Node.js.

/**
     * TODO(developer): Uncomment these variables before running the sample
     */
    // const projectId = 'your-project-id', // Your GCP Project ID
    // const imageUrl = 'https://gcr.io/my-project/my-image:123' // Image to attach metadata to

    // Import the library and create a client
    const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
    const client = new ContainerAnalysisClient();

    const formattedParent = client.getGrafeasClient().projectPath(projectId);

    // Retrieve a list of vulnerability occurrences with a severity level of 'HIGH' or greater
    const [occurrences] = await client.getGrafeasClient().listOccurrences({
      parent: formattedParent,
      filter: `kind = "VULNERABILITY" AND resourceUrl = "${imageUrl}"`,
    });

    if (occurrences.length) {
      console.log(`High Severity Vulnerabilities for ${imageUrl}`);
      occurrences.forEach(occurrence => {
        if (
          occurrence.vulnerability.severity === 'HIGH' ||
          occurrence.vulnerability.severity === 'CRITICAL'
        ) {
          console.log(`${occurrence.name}:`);
        }
      });
    } else {
      console.log('No occurrences found.');
    }

Ruby

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Ruby.

# resource_url = "The URL of the resource associated with the occurrence,
    #                 e.g. https://gcr.io/project/image@sha256:123"
    # project_id   = "The Google Cloud project ID of the vulnerabilities to find"

    require "grafeas"

    # Initialize the client
    client = Grafeas.new

    formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
    filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
    vulnerability_list = client
                         .list_occurrences(formatted_parent, filter: filter)
    # Filter the list to include only "high" and "critical" vulnerabilities
    vulnerability_list.select do |item|
      item.vulnerability.severity == :HIGH || item.vulnerability.severity == :CRITICAL
    end

Python

Pour apprendre à installer et à utiliser la bibliothèque cliente pour Container Registry, consultez la page Bibliothèques clientes Container Registry. Pour en savoir plus, consultez la documentation de référence sur l'API Container Registry en langage Python.

def find_high_severity_vulnerabilities_for_image(resource_url, project_id):
        """Retrieves a list of only high vulnerability occurrences associated
        with a resource."""
        # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
        # project_id = 'my-gcp-project'

        from grafeas.grafeas_v1.gapic.enums import Severity
        from google.cloud.devtools import containeranalysis_v1

        client = containeranalysis_v1.ContainerAnalysisClient()
        grafeas_client = client.get_grafeas_client()
        project_name = grafeas_client.project_path(project_id)

        filter_str = 'kind="VULNERABILITY" AND resourceUrl="{}"'\
            .format(resource_url)
        vulnerabilities = grafeas_client.list_occurrences(project_name, filter_str)
        filtered_list = []
        for v in vulnerabilities:
            if v.severity == Severity.HIGH or v.severity == Severity.CRITICAL:
                filtered_list.append(v)
        return filtered_list

Nettoyer

Pour éviter que les ressources utilisées dans ce tutoriel soient facturées sur votre compte Google Cloud Platform :

Supprimer l'image

Si vous souhaitez ne supprimer que l'image Docker que vous avez ajoutée, exécutez la commande ci-dessous pour supprimer l'image Docker de Container Registry.

gcloud container images delete gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image:tag1 --force-delete-tags
    

[PROJECT-ID] est l'ID du projet dans Google Cloud Console. Si l'ID du projet contient le signe deux-points (:), consultez la section Projets à l'échelle du domaine.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  1. Dans Cloud Console, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étape suivante