Analyse des journaux de sécurité dans Google Cloud

Last reviewed 2023-02-06 UTC

Ce guide explique aux professionnels de la sécurité comment intégrer des journaux Google Cloud à utiliser dans les analyses de sécurité. En effectuant des analyses de sécurité, vous aidez votre organisation à prévenir, détecter et contrer des menaces telles que les logiciels malveillants, l'hameçonnage, les rançongiciels et les éléments mal configurés.

Cette page vous explique comment :

  • Activer les journaux à analyser.
  • Acheminez ces journaux vers une seule destination en fonction de l'outil d'analyse de sécurité de votre choix, tel que l'Analyse de journaux, BigQuery, Chronicle ou d'une technologie tierce de gestion des informations de sécurité et des événements (SIEM, Security Information and Event Management).
  • Analyser ces journaux pour auditer votre utilisation du cloud et détecter les menaces potentielles pour vos données et charges de travail, à l'aide d'exemples de requêtes issus du projet Community Security Analytics (CSA).

Les informations de ce guide font partie des opérations de sécurité autonomes de Google Cloud, qui incluent la transformation des pratiques de détection et de réponse par des ingénieurs, ainsi que des analyses de sécurité visant à améliorer vos capacités de détection des menaces.

Dans ce guide, les journaux fournissent la source de données à analyser. Toutefois, vous pouvez appliquer les concepts de ce guide pour analyser d'autres données complémentaires sur la sécurité de Google Cloud, telles que les résultats de sécurité de Security Command Center. Security Command Center Premium fournit une liste de détecteurs gérés régulièrement mis à jour pour identifier les menaces, les failles et les erreurs de configuration dans vos systèmes, presque en temps réel. En analysant ces signaux à partir de Security Command Center et en les mettant en corrélation avec les journaux ingérés dans votre outil d'analyse de sécurité comme décrit dans ce guide, vous pouvez obtenir une perspective plus large des menaces de sécurité potentielles.

Le schéma suivant montre comment les sources de données de sécurité, les outils d'analyse de sécurité et les requêtes CSA fonctionnent ensemble.

Outils d'analyse de sécurité et contenu.

Le schéma commence par les sources de données de sécurité suivantes : les journaux de Cloud Logging, les modifications d'éléments provenant de l'inventaire des éléments cloud et les résultats de sécurité de Security Command Center. Le schéma affiche ensuite les sources de données de sécurité en cours de routage dans l'outil d'analyse de sécurité de votre choix : Analyse de journaux dans Cloud Logging, BigQuery, Chronicle ou une solution SIEM tierce. Enfin, le schéma montre comment les données de sécurité classées sont analysées en utilisant des requêtes CSA avec votre outil d'analyse.

Workflow d'analyse des journaux de sécurité

Cette section décrit la procédure à suivre pour configurer l'analyse des journaux de sécurité dans Google Cloud. Le workflow se compose des trois étapes présentées dans le schéma suivant et décrits dans les paragraphes suivants :

Les trois étapes de configuration de l'analyse des journaux de sécurité : 1) activation des journaux, 2) routage des journaux et 3) analyse des journaux.

  • Activer les journaux : de nombreux journaux de sécurité sont disponibles dans Google Cloud. Chaque journal contient des informations différentes qui peuvent être utiles pour répondre à des questions de sécurité spécifiques. Certains journaux, comme les journaux d'audit pour les activités d'administration, sont activés par défaut. Les autres doivent être activés manuellement, car des coûts d'ingestion supplémentaires s'appliquent dans Cloud Logging. Par conséquent, la première étape du workflow consiste à hiérarchiser les journaux de sécurité les plus pertinents pour vos besoins d'analyse de sécurité et à activer individuellement ces journaux.

    Pour vous aider à évaluer les journaux en termes de visibilité et de couverture des menaces, ce guide inclut un outil de champ d'application des journaux. Cet outil mappe chaque journal avec les tactiques et techniques de menace pertinentes de la matrice MITRE ATT&CK® pour les entreprises. L'outil mappe également les règles Event Threat Detection aux journaux sur lesquels elles reposent dans Security Command Center. Vous pouvez évaluer les journaux à l'aide de l'outil de champ d'application des journaux, quel que soit l'outil d'analyse que vous utilisez.

  • Routage des journaux : après avoir identifié et activé les journaux à analyser, l'étape suivante consiste à acheminer et agréger les journaux de votre organisation, y compris les dossiers, les projets et les comptes de facturation qu'ils contiennent. La manière dont vous acheminez les journaux dépend de l'outil d'analyse que vous utilisez.

    Ce guide décrit les destinations courantes de routage des journaux et vous explique comment utiliser un récepteur agrégé Cloud Logging pour acheminer des journaux à l'échelle de l'organisation dans un bucket de journaux Cloud Logging ou un ensemble de données BigQuery selon que vous choisissez d'utiliser l'Analyse de journaux ou BigQuery pour les analyses.

  • Analyser les journaux : après avoir acheminé les journaux dans un outil d'analyse, l'étape suivante consiste à effectuer une analyse de ces journaux pour identifier les menaces de sécurité potentielles. La manière dont vous analysez les journaux dépend de l'outil d'analyse que vous utilisez. Si vous utilisez l'Analyse de journaux ou BigQuery, vous pouvez analyser les journaux à l'aide de requêtes SQL. Si vous utilisez Chronicle, vous analysez les journaux à l'aide de règles YARA-L. Si vous utilisez un outil SIEM tiers, utilisez le langage de requête spécifié par cet outil.

    Dans ce guide, vous trouverez des requêtes SQL permettant d'analyser les journaux dans l'Analyse de journaux ou BigQuery. Les requêtes SQL fournies dans ce guide proviennent du projet Community Security Analytics (CSA). CSA est un ensemble Open Source d'analyses de sécurité de base conçues pour vous fournir une référence de requêtes et de règles prédéfinies que vous pouvez réutiliser pour commencer à analyser vos journaux Google Cloud.

Les sections suivantes fournissent des informations détaillées sur la configuration et l'application de chaque étape du workflow d'analyse des journaux de sécurité.

Activer les journaux

Le processus d'activation des journaux comprend les étapes suivantes :

  1. Identifiez les journaux dont vous avez besoin à l'aide de l'outil de champ d'application des journaux de ce guide.
  2. Enregistrez le filtre de journal généré par l'outil de champ d'application des journaux afin de l'utiliser ultérieurement lors de la configuration du récepteur de journaux.
  3. Activez la journalisation pour chaque type de journal ou service Google Cloud identifié. Selon le service, vous devrez peut-être également activer les journaux d'audit d'accès aux données correspondants, comme indiqué plus loin dans cette section.

Identifier les journaux à l'aide de l'outil de champ d'application des journaux

Pour vous aider à identifier les journaux répondant à vos besoins de sécurité et de conformité, vous pouvez utiliser l'outil de champ d'application des journaux présenté dans cette section. Cet outil fournit une table interactive qui regroupe les journaux utiles à la sécurité présents dans Google Cloud, y compris les journaux Cloud Audit Logs, les journaux Access Transparency, les journaux réseau et plusieurs journaux de plate-forme. Cet outil mappe chaque type de journal sur les zones suivantes :

L'outil de champ d'application des journaux génère également un filtre de journal qui apparaît immédiatement après la table. Lorsque vous identifiez les journaux dont vous avez besoin, sélectionnez-les dans l'outil pour mettre à jour automatiquement ce filtre de journal.

Les procédures courtes suivantes expliquent comment utiliser l'outil de champ d'application des journaux :

  • Pour sélectionner ou supprimer un journal dans l'outil de champ d'application des journaux, cliquez sur le bouton d'activation/de désactivation situé à côté du nom du journal.
  • Pour sélectionner ou supprimer tous les journaux, cliquez sur le bouton d'activation/de désactivation à côté de l'en-tête Type de journal.
  • Pour connaître les techniques MITRE ATT&CK pouvant être surveillées par chaque type de journal, cliquez sur le bouton  à côté de l'en-tête Tactiques et techniques MITRE ATT&CK.

Outil de champ d'application des journaux

Enregistrer le filtre de journal

Le filtre de journal généré automatiquement par l'outil de champ d'application des journaux contient tous les journaux que vous avez sélectionnés dans l'outil. Vous pouvez utiliser le filtre tel quel ou l'affiner en fonction de vos besoins. Par exemple, vous pouvez inclure (ou exclure) des ressources uniquement dans un ou plusieurs projets spécifiques. Une fois que vous disposez d'un filtre de journal répondant à vos besoins de journalisation, vous devez l'enregistrer pour l'utiliser lors du routage des journaux. Par exemple, vous pouvez enregistrer le filtre dans un éditeur de texte ou l'enregistrer dans une variable d'environnement comme suit :

  1. Dans la section "Filtre de journal généré automatiquement" qui suit l'outil, copiez le code du filtre de journal.
  2. Facultatif : modifiez le code copié pour affiner le filtre.
  3. Dans Cloud Shell, créez une variable pour enregistrer le filtre de journal :

    export LOG_FILTER='LOG_FILTER'
    

    Remplacez LOG_FILTER par le code du filtre de journal.

Activer des journaux de plate-forme spécifiques aux services

Les journaux de plate-forme que vous sélectionnez dans l'outil de champ d'application des journaux doivent être activés service par service (généralement au niveau des ressources). Par exemple, les journaux Cloud DNS sont activés au niveau du réseau VPC. De même, les journaux de flux VPC sont activés au niveau du sous-réseau pour toutes les VM du sous-réseau et les journaux provenant de la journalisation des règles de pare-feu sont activés au niveau de la règle de pare-feu individuelle.

Chaque journal de plate-forme dispose de ses propres instructions concernant l'activation de la journalisation. Toutefois, vous pouvez utiliser l'outil de champ d'application des journaux pour ouvrir rapidement les instructions correspondantes pour chaque journal de plate-forme.

Pour savoir comment activer la journalisation pour un journal de plate-forme spécifique, procédez comme suit :

  1. Dans l'outil de champ d'application des journaux, localisez le journal de plate-forme que vous souhaitez activer.
  2. Dans la colonne Activé par défaut, cliquez sur le lien Activer correspondant à ce journal. Ce lien vous permet d'accéder à des instructions détaillées sur l'activation de la journalisation pour ce service.

Activer les journaux d'audit des accès aux données

Comme vous pouvez le constater dans l'outil de champ d'application des journaux, les journaux d'audit des accès aux données de Cloud Audit Logs offrent une couverture étendue de détection des menaces. Cependant, leur volume peut être assez important. L'activation de ces journaux d'audit peut donc entraîner des frais supplémentaires liés à leur ingestion, à leur stockage, à leur exportation et à leur traitement. Cette section explique comment activer ces journaux et présente certaines bonnes pratiques pour vous aider à trouver un compromis entre valeur et coût.

Les journaux d'audit pour l'accès aux données sont désactivés par défaut (sauf dans BigQuery). Pour configurer des journaux d'audit d'accès aux données pour les services Google Cloud autres que BigQuery, vous devez les activer explicitement à l'aide de la console Google Cloud ou de Google Cloud CLI afin de modifier les objets des stratégies Identity and Access Management (IAM). Lorsque vous activez les journaux d'audit des accès aux données, vous pouvez également configurer les types d'opérations enregistrés. Il existe trois types de journaux d'audit des accès aux données :

  • ADMIN_READ : enregistre les opérations de lecture des métadonnées ou des informations de configuration.
  • DATA_READ : enregistre les opérations de lecture des données fournies par l'utilisateur.
  • DATA_WRITE : enregistre les opérations d'écriture des données fournies par l'utilisateur.

Notez que vous ne pouvez pas configurer l'enregistrement des opérations ADMIN_WRITE qui permettent d'écrire des métadonnées ou des informations de configuration. Les opérations ADMIN_WRITE sont incluses dans les journaux d'audit pour les activités d'administration à partir de Cloud Audit Logs et ne peuvent donc pas être désactivées.

Gérer le volume des journaux d'audit des accès aux données

Lorsque vous activez des journaux d'audit pour l'accès aux données, l'objectif est d'optimiser leur valeur en termes de visibilité sur la sécurité, tout en limitant les coûts et les frais de gestion. Pour vous aider à atteindre cet objectif, nous vous recommandons de procéder comme suit afin de filtrer les journaux de faible valeur et volumineux :

  • Donnez la priorité aux services pertinents, tels que les services qui hébergent des charges de travail, des clés et des données sensibles. Pour obtenir des exemples spécifiques de services auxquels il peut être utile de donner la priorité, consultez la section Exemple de configuration d'un journal d'audit pour l'accès aux données.
  • Privilégiez les projets pertinents, tels que les projets hébergeant des charges de travail de production, plutôt que les projets hébergeant des environnements de développement et de préproduction. Pour filtrer tous les journaux d'un projet particulier, ajoutez l'expression suivante à votre filtre de journal pour votre récepteur. Remplacez PROJECT_ID par l'ID du projet à partir duquel vous souhaitez filtrer tous les journaux :

    Projet Expression de filtre de journal
    Exclure tous les journaux d'un projet donné
    
    NOT logName =~ "^projects/PROJECT_ID"
        
  • Donnez la priorité à un sous-ensemble d'opérations d'accès aux données, telles que ADMIN_READ, DATA_READ et DATA_WRITE, pour un ensemble minimal d'opérations enregistrées. Par exemple, certains services tels que Cloud DNS écrivent les trois types d'opérations, mais vous ne pouvez activer la journalisation que pour les opérations ADMIN_READ. Une fois que vous avez configuré un ou plusieurs de ces trois types d'opérations d'accès aux données, vous pouvez exclure des opérations spécifiques dont le volume est particulièrement élevé. Vous pouvez exclure ces opérations à volume élevé en modifiant le filtre de journal du récepteur. Par exemple, vous décidez d'activer la journalisation d'audit complète pour l'accès aux données, y compris les opérations DATA_READ sur certains services de stockage critiques. Pour exclure des opérations spécifiques de lecture de données à trafic élevé dans cette situation, vous pouvez ajouter les expressions de filtre de journal recommandées suivantes au filtre de journal de votre récepteur :

    Service Expression de filtre de journal
    Exclure des journaux à volume élevé de Cloud Storage
    
    NOT (resource.type="gcs_bucket" AND
        (protoPayload.methodName="storage.buckets.get" OR
        protoPayload.methodName="storage.buckets.list")) 
    Exclure des journaux à volume élevé de Cloud SQL
    
    NOT (resource.type="cloudsql_database" AND
        protoPayload.request.cmd="select") 
  • Donnez la priorité aux ressources pertinentes, telles que les ressources qui hébergent vos charges de travail et vos données les plus sensibles. Vous pouvez classer vos ressources en fonction de la valeur des données qu'elles traitent et du risque de sécurité qu'elles présentent, par exemple en fonction de leur disponibilité externe ou non. Bien que les journaux d'audit pour l'accès aux données soient activés par service, vous pouvez filtrer des ressources ou des types de ressources spécifiques via le filtre de journal.

  • Excluez des comptes principaux spécifiques de l'enregistrement de leurs accès aux données. Vous pouvez par exemple demander à ce que les opérations effectuées par vos comptes de test internes ne soient pas consignées. Pour en savoir plus, consultez la section Définir des exceptions dans la documentation sur les journaux d'audit pour l'accès aux données.

Exemple de configuration d'un journal d'audit pour l'accès aux données

Le tableau suivant fournit une configuration de référence pour les journaux d'audit d'accès aux données, que vous pouvez utiliser pour les projets Google Cloud afin de limiter les volumes de journaux tout en bénéficiant d'une visibilité précieuse sur la sécurité :

Niveau Services Types de journaux d'audit pour l'accès aux données Tactiques MITRE ATT&CK
Services d'authentification et d'autorisation IAM
Identity-Aware Proxy (IAP)1
Cloud KMS
Secret Manager
Resource Manager
ADMIN_READ
DATA_READ
Découverte
Accès aux identifiants
Élévation des privilèges
Services de stockage BigQuery (activé par défaut)
Cloud Storage1, 2
DATA_READ
DATA_WRITE
Collecte
Exfiltration
Services d'infrastructure Compute Engine
Règle d'organisation
ADMIN_READ Discovery

1 L'activation des journaux d'audit pour l'accès aux données pour IAP ou Cloud Storage peut générer des volumes de journaux importants lorsque le trafic vers les ressources Web protégées par IAP ou vers Cloud Storage est élevé.

2 L'activation des journaux d'audit d'accès aux données pour Cloud Storage peut interrompre l'utilisation de téléchargements de navigateurs authentifiés pour les objets non publics. Pour obtenir plus de détails et des solutions de contournement à ce problème, consultez le guide de dépannage de Cloud Storage.

Dans l'exemple de configuration, notez la façon dont les services sont regroupés par niveaux de sensibilité en fonction de leurs données, métadonnées ou configurations sous-jacentes. Ces niveaux illustrent les niveaux de précision suivants recommandés pour la journalisation d'audit pour l'accès aux données :

  • Services d'authentification et d'autorisation : pour ce niveau de services, nous vous recommandons d'effectuer un audit de toutes les opérations d'accès aux données. Ce niveau d'audit vous aide à surveiller l'accès à vos clés sensibles, à vos secrets et à vos stratégies IAM. Surveiller cet accès peut vous aider à détecter les tactiques MITRE ATT&CK telles que la détection, l'accès aux identifiants et l'élévation des privilèges.
  • Services de stockage : pour ce niveau de services, nous vous recommandons d'effectuer un audit des opérations d'accès aux données impliquant des données fournies par l'utilisateur. Ce niveau d'audit vous aide à surveiller l'accès à vos données sensibles et précieuses. La surveillance de cet accès peut vous aider à détecter les tactiques MITRE ATT&CK telles que la collecte et l'exfiltration en fonction de vos données.
  • Services d'infrastructure : pour ce niveau de services, nous vous recommandons d'effectuer un audit des opérations d'accès aux données impliquant des métadonnées ou des informations de configuration. Ce niveau d'audit vous aide à surveiller l'analyse de la configuration de l'infrastructure. La surveillance de cet accès peut vous aider à détecter les tactiques MITRE ATT&CK telles que la détection pour vos charges de travail.

Acheminer les journaux

Une fois les journaux identifiés et activés, l'étape suivante consiste à les acheminer vers une seule destination. La destination, le chemin et la complexité du routage varient en fonction des outils d'analyse que vous utilisez, comme illustré dans le schéma suivant.

Méthodes de routage des journaux : vers BigQuery et l'Analyse de journaux via un récepteur de journaux, vers une solution SIEM tierce via un récepteur de journaux et Pub/Sub, et vers Chronicle via l'ingestion directe.

Le schéma illustre les options de routage suivantes :

  • Si vous utilisez l'Analyse de journaux, vous avez besoin d'un récepteur agrégé pour agréger les journaux de votre organisation Google Cloud dans un seul bucket Cloud Logging.

  • Si vous utilisez BigQuery, vous avez besoin d'un récepteur agrégé pour agréger les journaux de votre organisation Google Cloud dans un seul ensemble de données BigQuery.

  • Si vous utilisez Chronicle et que ce sous-ensemble prédéfini de journaux répond à vos besoins d'analyse de sécurité, vous pouvez agréger automatiquement ces journaux dans votre compte Chronicle à l'aide de l'ingestion Chronicle intégrée. Vous pouvez également afficher cet ensemble prédéfini de journaux en consultant la colonne Exportable directement vers Chronicle de l'outil de champ d'application des journaux. Pour en savoir plus sur l'exportation de ces journaux prédéfinis, consultez la page Ingérer des journaux Google Cloud dans Chronicle.

  • Si vous utilisez BigQuery ou une solution SIEM tierce, ou si vous souhaitez exporter un ensemble étendu de journaux dans Chronicle, le schéma montre qu'une étape supplémentaire est nécessaire entre l'activation des journaux et leur analyse. Cette étape supplémentaire consiste à configurer un récepteur agrégé qui achemine les journaux sélectionnés de manière appropriée. Si vous utilisez BigQuery, ce récepteur suffit pour acheminer les journaux vers BigQuery. Si vous utilisez une solution SIEM tierce, vous devez demander au récepteur d'agréger les journaux sélectionnés dans Pub/Sub ou Cloud Storage pour qu'ils puissent être intégrés dans votre outil d'analyse.

Les options de routage vers Chronicle et une solution SIEM tierce ne sont pas traitées dans ce guide. Toutefois, les sections suivantes fournissent les étapes détaillées permettant d'acheminer les journaux vers l'Analyse de journaux ou BigQuery :

  1. Configurer une seule destination
  2. Créer un récepteur de journaux agrégé
  3. Accorder l'accès au récepteur
  4. Configurer l'accès en lecture à la destination
  5. Vérifier que les journaux sont acheminés vers la destination

Configurer une seule destination

Analyse de journaux

  1. Ouvrez la console Google Cloud dans le projet Google Cloud dans lequel vous souhaitez agréger des journaux.

    Accéder à Google Cloud Console

  2. Dans un terminal Cloud Shell, exécutez la commande gcloud suivante pour créer un bucket de journaux :

    gcloud logging buckets create BUCKET_NAME \
      --location=BUCKET_LOCATION \
      --project=PROJECT_ID
    

    Remplacez les éléments suivants :

    • PROJECT_ID : ID du projet Google Cloud dans lequel les journaux agrégés seront stockés.
    • BUCKET_NAME : nom du nouveau bucket Logging.
    • BUCKET_LOCATION : emplacement géographique du nouveau bucket Logging. Les emplacements acceptés sont global, us ou eu. Pour en savoir plus sur ces régions, consultez la page Régions compatibles. Si vous ne spécifiez pas d'emplacement, la région global est utilisée, ce qui signifie que les journaux peuvent se trouver physiquement dans n'importe quelle région.

  3. Vérifiez que le bucket a été créé :

    gcloud logging buckets list --project=PROJECT_ID
    
  4. (Facultatif) Définissez la durée de conservation des journaux dans le bucket. L'exemple suivant étend la conservation des journaux stockés dans le bucket à 365 jours :

    gcloud logging buckets update BUCKET_NAME \
      --location=BUCKET_LOCATION \
      --project=PROJECT_ID \
      --retention-days=365
    
  5. Mettez à jour votre nouveau bucket pour utiliser l'Analyse de journaux. Pour ce faire, suivez ces étapes.

BigQuery

  1. Ouvrez la console Google Cloud dans le projet Google Cloud dans lequel vous souhaitez agréger des journaux.

    Accéder à Google Cloud Console

  2. Dans un terminal Cloud Shell, exécutez la commande bq mk suivante pour créer un ensemble de données :

    bq --location=DATASET_LOCATION mk \
        --dataset \
        --default_partition_expiration=PARTITION_EXPIRATION \
        PROJECT_ID:DATASET_ID
    

    Remplacez les éléments suivants :

    • PROJECT_ID : ID du projet Google Cloud dans lequel les journaux agrégés seront stockés.
    • DATASET_ID : ID du nouvel ensemble de données BigQuery.
    • DATASET_LOCATION : emplacement géographique de l'ensemble de données. Une fois l'ensemble de données créé, l'emplacement ne peut plus être modifié.

    • PARTITION_EXPIRATION : durée de vie par défaut (en secondes) des partitions des tables partitionnées créées par le récepteur de journaux. Vous allez configurer le récepteur de journaux dans la section suivante. Le récepteur de journaux que vous configurez utilise des tables partitionnées par jour en fonction de l'horodatage de l'entrée de journal. Les partitions (y compris les entrées de journal associées) sont supprimées PARTITION_EXPIRATION secondes après la date de la partition.

Créer un récepteur de journaux agrégé

Pour acheminer des journaux d'organisation vers votre destination, vous devez créer un récepteur agrégé au niveau de l'organisation. Pour inclure tous les journaux que vous avez sélectionnés dans l'outil de champ d'application des journaux, vous devez configurer le récepteur avec le filtre de journal généré par l'outil de champ d'application des journaux.

Analyse de journaux

  1. Dans un terminal Cloud Shell, exécutez la commande gcloud suivante pour créer un récepteur agrégé au niveau de l'organisation :

    gcloud logging sinks create SINK_NAME \
      logging.googleapis.com/projects/PROJECT_ID/locations/BUCKET_LOCATION/buckets/BUCKET_NAME \
      --log-filter="LOG_FILTER" \
      --organization=ORGANIZATION_ID \
      --include-children
    

    Remplacez les éléments suivants :

    • SINK_NAME : nom du récepteur qui achemine les journaux.
    • PROJECT_ID : ID du projet Google Cloud dans lequel les journaux agrégés seront stockés.
    • BUCKET_LOCATION : emplacement du bucket Logging que vous avez créé pour le stockage des journaux.
    • BUCKET_NAME : nom du bucket Logging que vous avez créé pour le stockage des journaux.
    • LOG_FILTER : filtre de journal que vous avez enregistré à partir de l'outil de champ d'application des journaux.
    • ORGANIZATION_ID : ID de ressource pour votre organisation.

    L'option --include-children est importante pour que les journaux de tous les projets Google Cloud de votre organisation soient également inclus. Pour en savoir plus, consultez la section Générer et acheminer des journaux au niveau de l'organisation vers des destinations compatibles.

  2. Vérifiez que le récepteur a été créé :

    gcloud logging sinks list --organization=ORGANIZATION_ID
    
  3. Récupérez le nom du compte de service associé au récepteur que vous venez de créer :

    gcloud logging sinks describe SINK_NAME --organization=ORGANIZATION_ID
    

    La sortie ressemble à ceci :

    writerIdentity: serviceAccount:p1234567890-12345@logging-o1234567890.iam.gserviceaccount.com`
    
  4. Copiez la chaîne entière pour writerIdentity commençant par serviceAccount:. Il s'agit du compte de service du récepteur. Tant que vous n'accordez pas à ce compte de service un accès en écriture au bucket de journaux, le routage des journaux de ce récepteur échouera. Vous allez accorder un accès en écriture à l'identité du rédacteur du récepteur dans la section suivante.

BigQuery

  1. Dans un terminal Cloud Shell, exécutez la commande gcloud suivante pour créer un récepteur agrégé au niveau de l'organisation :

    gcloud logging sinks create SINK_NAME \
      bigquery.googleapis.com/projects/PROJECT_ID/datasets/DATASET_ID \
      --log-filter="LOG_FILTER" \
      --organization=ORGANIZATION_ID \
      --use-partitioned-tables \
      --include-children
    

    Remplacez les éléments suivants :

    • SINK_NAME : nom du récepteur qui achemine les journaux.
    • PROJECT_ID : ID du projet Google Cloud dans lequel vous souhaitez agréger les journaux.
    • DATASET_ID : ID de l'ensemble de données BigQuery que vous avez créé.
    • LOG_FILTER : filtre de journal que vous avez enregistré à partir de l'outil de champ d'application des journaux.
    • ORGANIZATION_ID : ID de ressource pour votre organisation.

    L'option --include-children est importante pour que les journaux de tous les projets Google Cloud de votre organisation soient également inclus. Pour en savoir plus, consultez la section Générer et acheminer des journaux au niveau de l'organisation vers des destinations compatibles.

    L'option --use-partitioned-tables est importante pour que les données soient partitionnées par jour en fonction du champ timestamp de l'entrée de journal. Cela simplifie l'interrogation des données et permet de réduire les coûts des requêtes en réduisant la quantité de données analysées par celles-ci. Un autre avantage des tables partitionnées est que vous pouvez définir une date d'expiration des partitions par défaut au niveau de l'ensemble de données pour répondre à vos exigences de conservation des journaux. Vous avez déjà défini un délai d'expiration des partitions par défaut lorsque vous avez créé la destination de l'ensemble de données dans la section précédente. Vous pouvez également définir un délai d'expiration des partitions au niveau de chaque table, ce qui vous permet de contrôler avec précision les données en fonction du type de journal.

  2. Vérifiez que le récepteur a été créé :

    gcloud logging sinks list --organization=ORGANIZATION_ID
    
  3. Récupérez le nom du compte de service associé au récepteur que vous venez de créer :

    gcloud logging sinks describe SINK_NAME --organization=ORGANIZATION_ID
    

    La sortie ressemble à ceci :

    writerIdentity: serviceAccount:p1234567890-12345@logging-o1234567890.iam.gserviceaccount.com`
    
  4. Copiez la chaîne entière pour writerIdentity commençant par serviceAccount:. Il s'agit du compte de service du récepteur. Tant que vous n'accordez pas à ce compte de service un accès en écriture à l'ensemble de données BigQuery, le routage des journaux de ce récepteur échouera. Vous allez accorder un accès en écriture à l'identité du rédacteur du récepteur dans la section suivante.

Accorder l'accès au récepteur

Après avoir créé le récepteur de journaux, vous devez l'autoriser à écrire dans sa destination, qu'il s'agisse du bucket Logging ou de l'ensemble de données BigQuery.

Analyse de journaux

Pour ajouter les autorisations au compte de service du récepteur, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page IAM.

    Accéder à la page IAM

  2. Assurez-vous d'avoir sélectionné le projet Google Cloud de destination qui contient le bucket Logging que vous avez créé pour le stockage de journaux central.

  3. Cliquez sur Accorder l'accès.

  4. Dans le champ Nouveaux comptes principaux, saisissez le compte de service du récepteur sans le préfixe serviceAccount:. Rappelez-vous que cette identité provient du champ writerIdentity que vous avez récupéré à la section précédente après la création du récepteur.

  5. Dans le menu déroulant Sélectionner un rôle, sélectionnez Rédacteur de bucket de journaux.

  6. Cliquez sur Ajouter une condition IAM pour limiter l'accès du compte de service au seul bucket de journaux que vous avez créé.

  7. Saisissez un titre et une description pour la condition.

  8. Dans le menu déroulant Type de condition, sélectionnez Ressource > Nom.

  9. Dans le menu déroulant Opérateur, sélectionnez Se termine par.

  10. Dans le champ Valeur, saisissez l'emplacement et le nom du bucket comme suit :

    locations/BUCKET_LOCATION/buckets/BUCKET_NAME
    
  11. Cliquez sur Enregistrer pour ajouter la condition.

  12. Cliquez sur Enregistrer pour définir les autorisations.

BigQuery

Pour ajouter les autorisations au compte de service du récepteur, procédez comme suit :

  1. Dans la console Google Cloud, accédez à BigQuery :

    Accéder à BigQuery

  2. Ouvrez l'ensemble de données BigQuery que vous avez créé pour le stockage de journaux central.

  3. Dans l'onglet "Informations sur l'ensemble de données", cliquez sur le menu déroulant Partage , puis sur Autorisations.

  4. Dans le panneau latéral "Autorisations d'ensemble de données", cliquez sur Ajouter un compte principal.

  5. Dans le champ Nouveaux comptes principaux, saisissez le compte de service du récepteur sans le préfixe serviceAccount:. Rappelez-vous que cette identité provient du champ writerIdentity que vous avez récupéré à la section précédente après la création du récepteur.

  6. Dans le menu déroulant Rôle, sélectionnez Éditeur de données BigQuery.

  7. Cliquez sur Enregistrer.

Une fois que vous avez accordé l'accès au récepteur, les entrées de journal commencent à remplir la destination du récepteur : le bucket Logging ou l'ensemble de données BigQuery.

Configurer l'accès en lecture à la destination

Maintenant que le récepteur de journaux achemine les journaux de l'ensemble de votre organisation vers une seule destination, vous pouvez effectuer une recherche dans tous ces journaux. Utilisez les autorisations IAM pour gérer les autorisations et accorder l'accès si nécessaire.

Analyse de journaux

Pour autoriser l'affichage et l'interrogation des journaux de votre nouveau bucket de journaux, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page IAM.

    Accéder à la page IAM

    Assurez-vous d'avoir sélectionné le projet Google Cloud que vous utilisez pour agréger les journaux.

  2. Cliquez sur Ajouter.

  3. Dans le champ Nouveau compte principal, ajoutez votre compte de messagerie.

  4. Dans le menu déroulant Sélectionner un rôle, sélectionnez Accesseur de vues de journaux.

    Ce rôle fournit au compte principal nouvellement ajouté un accès en lecture à toutes les vues de tous les buckets du projet Google Cloud. Pour limiter l'accès d'un utilisateur, ajoutez une condition qui limite l'accès en lecture de l'utilisateur uniquement à votre nouveau bucket.

    1. Cliquez sur Ajouter une condition :

    2. Saisissez un titre et une description pour la condition.

    3. Dans le menu déroulant Type de condition, sélectionnez Ressource > Nom.

    4. Dans le menu déroulant Opérateur, sélectionnez Se termine par.

    5. Dans le champ Valeur, saisissez l'emplacement et le nom du bucket, ainsi que la vue de journal par défaut _AllLogs, comme suit :

      locations/BUCKET_LOCATION/buckets/BUCKET_NAME/views/_AllLogs
      
    6. Cliquez sur Enregistrer pour ajouter la condition.

  5. Cliquez sur Enregistrer pour définir les autorisations.

BigQuery

Pour accorder l'accès permettant d'afficher et d'interroger les journaux dans votre ensemble de données BigQuery, suivez la procédure décrite dans la section Accorder l'accès à un ensemble de données de la documentation BigQuery.

Vérifier que les journaux sont acheminés vers la destination

Analyse de journaux

Lorsque vous acheminez des journaux vers un bucket de journaux mis à niveau vers l'Analyse de journaux, vous pouvez afficher et interroger toutes les entrées de journal via une seule vue de journal avec un schéma unifié pour tous les types de journaux. Pour vérifier que les journaux sont correctement acheminés, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page Analyse de journaux :

    Accéder à l'analyse de journaux

    Assurez-vous d'avoir sélectionné le projet Google Cloud que vous utilisez pour agréger les journaux.

  2. Cliquez sur l'onglet Vues de journaux.

  3. Développez les vues de journaux sous le bucket de journaux que vous avez créé (c'est-à-dire BUCKET_NAME) si ce n'est pas déjà fait.

  4. Sélectionnez la vue de journal _AllLogs par défaut. Vous pouvez maintenant inspecter l'intégralité du schéma de journal dans le panneau de droite, comme illustré dans la capture d'écran suivante :

    Analyse de journaux avec la table cloudaudit_googleapis_com_data_access sélectionnée.

  5. À côté de _AllLogs, cliquez sur Query (Requête). Cela remplit l'éditeur Query (Requête) avec un exemple de requête SQL pour récupérer les entrées de journal récemment acheminées.

  6. Cliquez sur Exécuter la requête pour afficher les entrées de journal récemment acheminées.

En fonction du niveau d'activité dans les projets Google Cloud de votre organisation, vous devrez peut-être attendre quelques minutes avant que certains journaux ne soient générés, puis acheminés vers votre bucket de journaux.

BigQuery

Lorsque vous acheminez des journaux vers un ensemble de données BigQuery, Cloud Logging crée des tables BigQuery pour conserver les entrées de journal, comme illustré dans la capture d'écran suivante :

Explorateur BigQuery avec la table cloudaudit_googleapis_com_data_access sélectionnée.

La capture d'écran montre comment Cloud Logging nomme chaque table BigQuery en fonction du nom du journal auquel une entrée de journal appartient. Par exemple, la table cloudaudit_googleapis_com_data_access sélectionnée dans la capture d'écran contient des journaux d'audit d'accès aux données dont l'ID de journal est cloudaudit.googleapis.com%2Fdata_access. En plus d'être nommées en fonction de l'entrée de journal correspondante, les tables sont également partitionnées selon les codes temporels de chaque entrée de journal.

En fonction du niveau d'activité dans les projets Google Cloud de votre organisation, vous devrez peut-être attendre quelques minutes avant que certains journaux ne soient générés, puis acheminés vers votre ensemble de données BigQuery.

Analyser des journaux

Vous pouvez exécuter un large éventail de requêtes sur vos journaux d'audit et de plate-forme. La liste suivante fournit un ensemble d'exemples de questions de sécurité que vous pouvez poser avec vos propres journaux. Pour chaque question figurant dans cette liste, il existe deux versions de la requête CSA correspondante : l'une pour une utilisation avec l'Analyse de journaux et l'autre avec BigQuery. Utilisez la version de requête qui correspond à la destination du récepteur que vous avez précédemment configurée.

Analyse de journaux

Avant d'utiliser l'une des requêtes SQL ci-dessous, remplacez MY_PROJECT_ID par l'ID du projet Google Cloud dans lequel vous avez créé le bucket de journaux (soit PROJECT_ID), et MY_DATASET_ID par la région et le nom de ce bucket de journaux (soit BUCKET_LOCATION.BUCKET_NAME).

Accéder à l'analyse de journaux

BigQuery

Avant d'utiliser l'une des requêtes SQL ci-dessous, remplacez MY_PROJECT_ID par l'ID du projet Google Cloud dans lequel vous avez créé l'ensemble de données BigQuery (soit PROJECT_ID), et MY_DATASET_ID par le nom de cet ensemble de données (soit DATASET_ID).

Accéder à BigQuery

  1. Questions sur la connexion et l'accès
  2. Questions sur les modifications des autorisations
  3. Questions sur l'activité de provisionnement
  4. Questions sur l'utilisation des charges de travail
  5. Questions sur l'accès aux données
  6. Questions sur la sécurité du réseau

Questions liées à la connexion et à l'accès

Ces exemples de requêtes effectuent une analyse pour détecter les tentatives de connexion suspectes ou les tentatives d'accès initiales à votre environnement Google Cloud.

Des tentatives de connexion suspectes signalées par Google Workspace ?

En recherchant les journaux Cloud Identity faisant partie de l'audit de connexion Google Workspace, la requête suivante détecte les tentatives de connexion suspectes signalées par Google Workspace. Ces tentatives de connexion peuvent provenir de la console Google Cloud, de la console d'administration ou de gcloud CLI.

Analyse de journaux


SELECT
  timestamp,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.request_metadata.caller_ip,
  proto_payload.audit_log.method_name, parameter
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`,
  UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.metadata.event[0].parameter)) AS parameter
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
  AND proto_payload.audit_log IS NOT NULL
  AND proto_payload.audit_log.service_name = "login.googleapis.com"
  AND proto_payload.audit_log.method_name = "google.login.LoginService.loginSuccess"
  AND JSON_VALUE(parameter.name) = "is_suspicious"
  AND JSON_VALUE(parameter.boolValue) = "true"

BigQuery


SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.requestMetadata.callerIp,
  protopayload_auditlog.methodName
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`,
  UNNEST(JSON_QUERY_ARRAY(protopayload_auditlog.metadataJson, '$.event[0].parameter')) AS parameter
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
  AND protopayload_auditlog.metadataJson IS NOT NULL
  AND protopayload_auditlog.serviceName = "login.googleapis.com"
  AND protopayload_auditlog.methodName = "google.login.LoginService.loginSuccess"
  AND JSON_VALUE(parameter, '$.name') = "is_suspicious"
  AND JSON_VALUE(parameter, '$.boolValue') = "true"

Des échecs de connexion excessifs liés à l'identité d'un utilisateur ?

En recherchant les journaux Cloud Identity faisant partie de l'audit de connexion Google Workspace, la requête suivante détecte les utilisateurs qui ont rencontré au moins trois échecs de connexion successifs au cours des dernières 24 heures.

Analyse de journaux


SELECT
  proto_payload.audit_log.authentication_info.principal_email,
  MIN(timestamp) AS earliest,
  MAX(timestamp) AS latest,
  count(*) AS attempts
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
  AND proto_payload.audit_log.service_name = "login.googleapis.com"
  AND proto_payload.audit_log.method_name = "google.login.LoginService.loginFailure"
GROUP BY
  1
HAVING
  attempts >= 3

BigQuery


SELECT
  protopayload_auditlog.authenticationInfo.principalEmail,
  MIN(timestamp) AS earliest,
  MAX(timestamp) AS latest,
  count(*) AS attempts
FROM
 `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
  AND protopayload_auditlog.serviceName="login.googleapis.com"
  AND protopayload_auditlog.methodName="google.login.LoginService.loginFailure"
GROUP BY
  1
HAVING
  attempts >= 3

Des tentatives d'accès ne respectent pas VPC Service Controls ?

En analysant les journaux d'audit des refus de règles à partir de Cloud Audit Logs, la requête suivante détecte les tentatives d'accès bloquées par VPC Service Controls. Tout résultat de requête peut indiquer une activité potentiellement malveillante, telle que des tentatives d'accès de réseaux non autorisés utilisant des identifiants volés.

Analyse de journaux


SELECT
  timestamp,
  log_name,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.request_metadata.caller_ip,
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.service_name,
  JSON_VALUE(proto_payload.audit_log.metadata.violationReason) as violationReason,
  IF(JSON_VALUE(proto_payload.audit_log.metadata.ingressViolations) IS NULL, 'ingress', 'egress') AS violationType,
  COALESCE(
    JSON_VALUE(proto_payload.audit_log.metadata.ingressViolations[0].targetResource),
    JSON_VALUE(proto_payload.audit_log.metadata.egressViolations[0].targetResource)
  ) AS  targetResource,
  COALESCE(
    JSON_VALUE(proto_payload.audit_log.metadata.ingressViolations[0].servicePerimeter),
    JSON_VALUE(proto_payload.audit_log.metadata.egressViolations[0].servicePerimeter)
  ) AS  servicePerimeter
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND proto_payload.audit_log IS NOT NULL
  AND JSON_VALUE(proto_payload.audit_log.metadata, '$."@type"') = 'type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata'
ORDER BY
  timestamp DESC
LIMIT 1000

BigQuery


SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.requestMetadata.callerIp,
  protopayload_auditlog.methodName,
  protopayload_auditlog.serviceName,
  JSON_VALUE(protopayload_auditlog.metadataJson, '$.violationReason') as violationReason,
  IF(JSON_VALUE(protopayload_auditlog.metadataJson, '$.ingressViolations') IS NULL, 'ingress', 'egress') AS violationType,
  COALESCE(
    JSON_VALUE(protopayload_auditlog.metadataJson, '$.ingressViolations[0].targetResource'),
    JSON_VALUE(protopayload_auditlog.metadataJson, '$.egressViolations[0].targetResource')
  ) AS  targetResource,
  COALESCE(
    JSON_VALUE(protopayload_auditlog.metadataJson, '$.ingressViolations[0].servicePerimeter'),
    JSON_VALUE(protopayload_auditlog.metadataJson, '$.egressViolations[0].servicePerimeter')
  ) AS  servicePerimeter
FROM
 `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_policy`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 400 DAY)
  AND JSON_VALUE(protopayload_auditlog.metadataJson, '$."@type"') = 'type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata'
ORDER BY
  timestamp DESC
LIMIT 1000

Des tentatives d'accès ne respectent pas les contrôles d'accès IAP ?

En analysant les journaux externes de l'équilibreur de charge d'application, la requête suivante détecte les tentatives d'accès bloquées par IAP. Tous les résultats de requête peuvent indiquer une tentative d'accès initiale ou une tentative d'exploitation de failles.

Analyse de journaux


SELECT
  timestamp,
  http_request.remote_ip,
  http_request.request_method,
  http_request.status,
  JSON_VALUE(resource.labels.backend_service_name) AS backend_service_name,
  http_request.request_url
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="http_load_balancer"
  AND JSON_VALUE(json_payload.statusDetails) = "handled_by_identity_aware_proxy"
ORDER BY
  timestamp DESC

BigQuery


SELECT
  timestamp,
  httpRequest.remoteIp,
  httpRequest.requestMethod,
  httpRequest.status,
  resource.labels.backend_service_name,
  httpRequest.requestUrl,
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].requests`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="http_load_balancer"
  AND jsonpayload_type_loadbalancerlogentry.statusdetails = "handled_by_identity_aware_proxy"
ORDER BY
  timestamp DESC

Questions sur les modifications des autorisations

Ces exemples de requêtes effectuent une analyse de l'activité des administrateurs qui modifie les autorisations, y compris les stratégies IAM, les groupes et les adhésions aux groupes, les comptes de service et les clés associées. Ces modifications d'autorisation peuvent fournir un niveau d'accès élevé aux données ou aux environnements sensibles.

Des utilisateurs ont-ils été ajoutés à des groupes hautement privilégiés ?

En analysant les journaux d'audit de l'audit des administrateurs Google Workspace, la requête suivante détecte les utilisateurs qui ont été ajoutés à l'un des groupes hautement privilégiés répertoriés dans la requête. Vous utilisez l'expression régulière dans la requête pour définir les groupes (tels que admin@example.com ou prod@example.com) à surveiller. Tous les résultats de requête peuvent indiquer une élévation de privilèges malveillante ou accidentelle.

Analyse de journaux


SELECT
  timestamp,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.resource_name,
  (SELECT JSON_VALUE(x.value)
   FROM UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.metadata.event[0].parameter)) AS x
   WHERE JSON_VALUE(x.name) = "USER_EMAIL") AS user_email,
  (SELECT JSON_VALUE(x.value)
   FROM UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.metadata.event[0].parameter)) AS x
   WHERE JSON_VALUE(x.name) = "GROUP_EMAIL") AS group_email,
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 120 DAY)
  AND proto_payload.audit_log.service_name = "admin.googleapis.com"
  AND proto_payload.audit_log.method_name = "google.admin.AdminService.addGroupMember"
  AND EXISTS(
    SELECT * FROM UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.metadata.event[0].parameter)) AS x
    WHERE
      JSON_VALUE(x.name) = "GROUP_EMAIL"
      AND REGEXP_CONTAINS(JSON_VALUE(x.value), r'(admin|prod).*') -- Update regexp with other sensitive groups if applicable
  )

BigQuery


SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.methodName,
  protopayload_auditlog.resourceName,
  (SELECT JSON_VALUE(x, '$.value')
   FROM UNNEST(JSON_QUERY_ARRAY(protopayload_auditlog.metadataJson, '$.event[0].parameter')) AS x
   WHERE JSON_VALUE(x, '$.name') = "USER_EMAIL") AS userEmail,
  (SELECT JSON_VALUE(x, '$.value')
   FROM UNNEST(JSON_QUERY_ARRAY(protopayload_auditlog.metadataJson, '$.event[0].parameter')) AS x
   WHERE JSON_VALUE(x, '$.name') = "GROUP_EMAIL") AS groupEmail,
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 120 DAY)
  AND protopayload_auditlog.serviceName = "admin.googleapis.com"
  AND protopayload_auditlog.methodName = "google.admin.AdminService.addGroupMember"
  AND EXISTS(
    SELECT * FROM UNNEST(JSON_QUERY_ARRAY(protopayload_auditlog.metadataJson, '$.event[0].parameter')) AS x
    WHERE
      JSON_VALUE(x, '$.name') = 'GROUP_EMAIL'
      AND REGEXP_CONTAINS(JSON_VALUE(x, '$.value'), r'(admin|prod).*') -- Update regexp with other sensitive groups if applicable
  )

Des autorisations sont-elles accordées via un compte de service ?

En analysant les journaux d'audit des activités d'administration à partir de Cloud Audit Logs, la requête suivante détecte toutes les autorisations accordées à un compte principal sur un compte de service. Voici des exemples d'autorisations pouvant être accordées : la possibilité d'emprunter l'identité de ce compte de service ou de créer des clés de compte de service. Tous les résultats de requête peuvent indiquer une instance d'élévation des privilèges ou un risque de fuite d'identifiants.

Analyse de journaux


SELECT
  timestamp,
  proto_payload.audit_log.authentication_info.principal_email as grantor,
  JSON_VALUE(bindingDelta.member) as grantee,
  JSON_VALUE(bindingDelta.role) as role,
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.method_name
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`,
  UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.service_data.policyDelta.bindingDeltas)) AS bindingDelta
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 400 DAY)
  -- AND log_id = "cloudaudit.googleapis.com/activity"
  AND (
    (resource.type = "service_account"
    AND proto_payload.audit_log.method_name LIKE "google.iam.admin.%.SetIAMPolicy")
    OR
    (resource.type IN ("project", "folder", "organization")
    AND proto_payload.audit_log.method_name = "SetIamPolicy"
    AND JSON_VALUE(bindingDelta.role) LIKE "roles/iam.serviceAccount%")
  )
  AND JSON_VALUE(bindingDelta.action) = "ADD"
  -- Principal (grantee) exclusions
  AND JSON_VALUE(bindingDelta.member) NOT LIKE "%@example.com"
ORDER BY
  timestamp DESC

BigQuery


SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail as grantor,
  bindingDelta.member as grantee,
  bindingDelta.role,
  protopayload_auditlog.resourceName,
  protopayload_auditlog.methodName,
FROM
  `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`,
  UNNEST(protopayload_auditlog.servicedata_v1_iam.policyDelta.bindingDeltas) AS bindingDelta
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 180 DAY)
  AND (
    (resource.type = "service_account"
    AND protopayload_auditlog.methodName LIKE "google.iam.admin.%.SetIAMPolicy")
    OR
    (resource.type IN ("project", "folder", "organization")
    AND protopayload_auditlog.methodName = "SetIamPolicy"
    AND bindingDelta.role LIKE "roles/iam.serviceAccount%")
  )
  AND bindingDelta.action = 'ADD'
  -- Principal (grantee) exclusions
  AND bindingDelta.member NOT LIKE "%@example.com"
ORDER BY
  timestamp DESC

Comptes de service ou clés créés par une identité non approuvée ?

En analysant les journaux d'audit pour les activités d'administration, la requête suivante détecte tous les comptes de service ou les clés créés manuellement par un utilisateur. Par exemple, vous pouvez suivre une bonne pratique qui consiste à autoriser uniquement la création de comptes de service par un compte de service approuvé au sein d'un workflow automatisé. Par conséquent, toute création de compte de service en dehors de ce workflow est considérée comme non conforme et peut être malveillante.

Analyse de journaux


SELECT
  timestamp,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.resource_name,
  JSON_VALUE(proto_payload.audit_log.response.email) as service_account_email
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="service_account"
  AND proto_payload.audit_log.method_name LIKE "%CreateServiceAccount%"
  AND proto_payload.audit_log.authentication_info.principal_email NOT LIKE "%.gserviceaccount.com"

BigQuery


SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.methodName,
  protopayload_auditlog.resourceName,
  JSON_VALUE(protopayload_auditlog.responseJson, "$.email") as serviceAccountEmail
FROM
  `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 180 DAY)
  AND resource.type="service_account"
  AND protopayload_auditlog.methodName LIKE "%CreateServiceAccount%"
  AND protopayload_auditlog.authenticationInfo.principalEmail NOT LIKE "%.gserviceaccount.com"

Un utilisateur a-t-il ajouté (ou supprimé) à une stratégie IAM sensible ?

En recherchant des journaux d'audit pour les activités d'administration, la requête suivante détecte toute modification d'accès d'utilisateur ou de groupe pour une ressource sécurisée par IAP, telle qu'un service de backend Compute Engine. La requête suivante recherche toutes les mises à jour de stratégie IAM pour les ressources IAP impliquant le rôle IAM roles/iap.httpsResourceAccessor. Ce rôle fournit des autorisations d'accès à la ressource HTTPS ou au service de backend. Tous les résultats de requête peuvent indiquer des tentatives de contournement des défenses d'un service de backend susceptible d'être exposé à Internet.

Analyse de journaux


SELECT
  timestamp,
  proto_payload.audit_log.authentication_info.principal_email,
  resource.type,
  proto_payload.audit_log.resource_name,
  JSON_VALUE(binding, '$.role') as role,
  JSON_VALUE_ARRAY(binding, '$.members') as members
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`,
  UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.response, '$.bindings')) AS binding
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  -- AND log_id = "cloudaudit.googleapis.com/activity"
  AND proto_payload.audit_log.service_name = "iap.googleapis.com"
  AND proto_payload.audit_log.method_name LIKE "%.IdentityAwareProxyAdminService.SetIamPolicy"
  AND JSON_VALUE(binding, '$.role') = "roles/iap.httpsResourceAccessor"
ORDER BY
  timestamp DESC

BigQuery


SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  resource.type,
  protopayload_auditlog.resourceName,
  JSON_VALUE(binding, '$.role') as role,
  JSON_VALUE_ARRAY(binding, '$.members') as members
FROM
  `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`,
  UNNEST(JSON_QUERY_ARRAY(protopayload_auditlog.responseJson, '$.bindings')) AS binding
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 400 DAY)
  AND protopayload_auditlog.serviceName = "iap.googleapis.com"
  AND protopayload_auditlog.methodName LIKE "%.IdentityAwareProxyAdminService.SetIamPolicy"
  AND JSON_VALUE(binding, '$.role') = "roles/iap.httpsResourceAccessor"
ORDER BY
  timestamp DESC

Questions sur l'activité de provisionnement

Ces exemples de requêtes effectuent une analyse pour détecter les activités d'administration suspectes ou anormales, telles que le provisionnement et la configuration des ressources.

Des modifications ont-elles été apportées aux paramètres de journalisation ?

En recherchant les journaux d'audit pour les activités d'administration, la requête suivante détecte toute modification apportée aux paramètres de journalisation. Les paramètres de journalisation de la surveillance vous permettent de détecter une désactivation accidentelle ou malveillante des journaux d'audit et des techniques d'éviction de défense similaires.

Analyse de journaux


SELECT
  receive_timestamp, timestamp AS eventTimestamp,
  proto_payload.audit_log.request_metadata.caller_ip,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.method_name
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  proto_payload.audit_log.service_name = "logging.googleapis.com"
  AND log_id = "cloudaudit.googleapis.com/activity"

BigQuery


SELECT
  receiveTimestamp, timestamp AS eventTimestamp,
  protopayload_auditlog.requestMetadata.callerIp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.resourceName,
  protopayload_auditlog.methodName
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
WHERE
  protopayload_auditlog.serviceName = "logging.googleapis.com"

Les journaux de flux VPC sont-ils activement désactivés ?

En recherchant les journaux d'audit pour les activités d'administration, la requête suivante détecte tous les sous-réseaux dont les journaux de flux VPC ont été activement désactivés. La surveillance des paramètres des journaux de flux VPC vous permet de détecter la désactivation accidentelle ou malveillante des journaux de flux VPC et d'autres techniques d'éviction de défense similaires.

Analyse de journaux


SELECT
  receive_timestamp, timestamp AS eventTimestamp,
  proto_payload.audit_log.request_metadata.caller_ip,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.method_name
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  proto_payload.audit_log.method_name = "v1.compute.subnetworks.patch"
  AND (
    JSON_VALUE(proto_payload.audit_log.request, "$.logConfig.enable") = "false"
    OR JSON_VALUE(proto_payload.audit_log.request, "$.enableFlowLogs") = "false"
  )

BigQuery


SELECT
  receiveTimestamp, timestamp AS eventTimestamp,
  protopayload_auditlog.requestMetadata.callerIp,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.resourceName,
  protopayload_auditlog.methodName
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
WHERE
protopayload_auditlog.methodName = "v1.compute.subnetworks.patch"
AND JSON_VALUE(protopayload_auditlog.requestJson, "$.logConfig.enable") = "false"

Un nombre inhabituel de règles de pare-feu modifiées au cours de la semaine passée ?

En recherchant les journaux d'audit pour les activités d'administration, la requête suivante détecte un nombre inhabituellement élevé de modifications des règles de pare-feu pour un jour donné au cours de la semaine écoulée. Pour déterminer s'il existe une anomalie, la requête effectue une analyse statistique sur le nombre quotidien de modifications des règles de pare-feu. Les moyennes et les écarts-types sont calculés pour chaque jour en examinant les nombres quotidiens précédents avec une période d'analyse de 90 jours. Une anomalie est prise en compte lorsque le nombre quotidien est supérieur à deux écarts types par rapport à la moyenne. La requête, y compris le facteur d'écart type et les périodes d'analyse, peuvent toutes être configurées pour s'adapter à votre profil d'activité de provisionnement cloud et pour minimiser les faux positifs.

Analyse de journaux

SELECT
  *
FROM (
  SELECT
    *,
    AVG(counter) OVER (
      ORDER BY day
      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS avg,
    STDDEV(counter) OVER (
      ORDER BY day
      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS stddev,
    COUNT(*) OVER (
      RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS numSamples
  FROM (
    SELECT
      EXTRACT(DATE FROM timestamp) AS day,
      ARRAY_AGG(DISTINCT proto_payload.audit_log.method_name IGNORE NULLS) AS actions,
      ARRAY_AGG(DISTINCT proto_payload.audit_log.authentication_info.principal_email IGNORE NULLS) AS actors,
      COUNT(*) AS counter
    FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
    WHERE
      timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
      AND proto_payload.audit_log.method_name LIKE "v1.compute.firewalls.%"
      AND proto_payload.audit_log.method_name NOT IN ("v1.compute.firewalls.list", "v1.compute.firewalls.get")
    GROUP BY
      day
  )
)
WHERE
  counter > avg + 2 * stddev
  AND day >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
ORDER BY
  counter DESC

BigQuery


SELECT
  *,
  AVG(counter) OVER (
    ORDER BY day
    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS avg,
  STDDEV(counter) OVER (
    ORDER BY day
    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS stddev,
  COUNT(*) OVER (
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS numSamples
FROM (
  SELECT
    EXTRACT(DATE FROM timestamp) AS day,
    ARRAY_AGG(DISTINCT protopayload_auditlog.methodName IGNORE NULLS) AS actions,
    ARRAY_AGG(DISTINCT protopayload_auditlog.authenticationInfo.principalEmail IGNORE NULLS) AS actors,
    COUNT(*) AS counter
  FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
  WHERE
    timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
    AND protopayload_auditlog.methodName LIKE "v1.compute.firewalls.%"
    AND protopayload_auditlog.methodName NOT IN ("v1.compute.firewalls.list", "v1.compute.firewalls.get")
  GROUP BY
    day
)
WHERE TRUE
QUALIFY
  counter > avg + 2 * stddev
  AND day >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
ORDER BY
  counter DESC

Des VM supprimées au cours de la semaine passée ?

En recherchant les journaux d'audit pour les activités d'administration, la requête suivante répertorie toutes les instances Compute Engine supprimées au cours de la semaine écoulée. Cette requête peut vous aider à auditer les suppressions de ressources et à détecter les activités malveillantes potentielles.

Analyse de journaux

SELECT
  timestamp,
  JSON_VALUE(resource.labels.instance_id) AS instance_id,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.method_name
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  resource.type = "gce_instance"
  AND proto_payload.audit_log.method_name = "v1.compute.instances.delete"
  AND operation.first IS TRUE
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY
  timestamp desc,
  instance_id
LIMIT
  1000

BigQuery


SELECT
  timestamp,
  resource.labels.instance_id,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.resourceName,
  protopayload_auditlog.methodName
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
WHERE
  resource.type = "gce_instance"
  AND protopayload_auditlog.methodName = "v1.compute.instances.delete"
  AND operation.first IS TRUE
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY
  timestamp desc,
  resource.labels.instance_id
LIMIT
  1000

Questions sur l'utilisation des charges de travail

Ces exemples de requêtes effectuent une analyse pour comprendre qui et ce qui consomme vos charges de travail et API Cloud, et vous aident à détecter d'éventuels comportements malveillants en interne ou en externe.

L'utilisation de l'API est-elle inhabituellement élevée par une identité utilisateur au cours de la semaine passée ?

En analysant tous les journaux d'audit Cloud, la requête suivante détecte une utilisation d'API inhabituellement élevée par une identité d'utilisateur sur un jour donné au cours de la semaine passée. Une utilisation inhabituellement élevée peut être un indicateur d'un abus potentiel d'API, d'une menace interne ou d'informations d'identification divulguées. Pour déterminer s'il existe une anomalie, cette requête effectue une analyse statistique du nombre quotidien d'actions par compte principal. Les moyennes et les écarts-types sont calculés pour chaque jour et pour chaque compte principal en examinant les nombres quotidiens précédents avec une période d'analyse de 60 jours. Une anomalie est prise en compte lorsque le nombre quotidien d'un utilisateur est supérieur à trois écarts types par rapport à sa moyenne. La requête, y compris le facteur d'écart type et les périodes d'analyse, peuvent toutes être configurées pour s'adapter à votre profil d'activité de provisionnement cloud et pour minimiser les faux positifs.

Analyse de journaux


SELECT
  *
FROM (
  SELECT
    *,
    AVG(counter) OVER (
      PARTITION BY principal_email
      ORDER BY day
      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS avg,
    STDDEV(counter) OVER (
      PARTITION BY principal_email
      ORDER BY day
      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS stddev,
    COUNT(*) OVER (
      PARTITION BY principal_email
      RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS numSamples
  FROM (
    SELECT
      proto_payload.audit_log.authentication_info.principal_email,
      EXTRACT(DATE FROM timestamp) AS day,
      ARRAY_AGG(DISTINCT proto_payload.audit_log.method_name IGNORE NULLS) AS actions,
      COUNT(*) AS counter
    FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
    WHERE
      timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
      AND proto_payload.audit_log.authentication_info.principal_email IS NOT NULL
      AND proto_payload.audit_log.method_name NOT LIKE "storage.%.get"
      AND proto_payload.audit_log.method_name NOT LIKE "v1.compute.%.list"
      AND proto_payload.audit_log.method_name NOT LIKE "beta.compute.%.list"
    GROUP BY
      proto_payload.audit_log.authentication_info.principal_email,
      day
  )
)
WHERE
  counter > avg + 3 * stddev
  AND day >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
ORDER BY
  counter DESC

BigQuery


SELECT
  *,
  AVG(counter) OVER (
    PARTITION BY principalEmail
    ORDER BY day
    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS avg,
  STDDEV(counter) OVER (
    PARTITION BY principalEmail
    ORDER BY day
    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS stddev,
  COUNT(*) OVER (
    PARTITION BY principalEmail
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS numSamples
FROM (
  SELECT
    protopayload_auditlog.authenticationInfo.principalEmail,
    EXTRACT(DATE FROM timestamp) AS day,
    ARRAY_AGG(DISTINCT protopayload_auditlog.methodName IGNORE NULLS) AS actions,
    COUNT(*) AS counter
  FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_*`
  WHERE
    timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
    AND protopayload_auditlog.authenticationInfo.principalEmail IS NOT NULL
    AND protopayload_auditlog.methodName NOT LIKE "storage.%.get"
    AND protopayload_auditlog.methodName NOT LIKE "v1.compute.%.list"
    AND protopayload_auditlog.methodName NOT LIKE "beta.compute.%.list"
  GROUP BY
    protopayload_auditlog.authenticationInfo.principalEmail,
    day
)
WHERE TRUE
QUALIFY
  counter > avg + 3 * stddev
  AND day >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
ORDER BY
  counter DESC

Quelle est l'utilisation quotidienne de l'autoscaling au cours du mois passé ?

En analysant les journaux d'audit pour les activités d'administration, la requête suivante indique l'utilisation de l'autoscaling par jour au cours du dernier mois. Cette requête peut être utilisée pour identifier des modèles ou des anomalies qui justifient un examen de sécurité plus approfondi.

Analyse de journaux


SELECT
  TIMESTAMP_TRUNC(timestamp, DAY) AS day,
  proto_payload.audit_log.method_name,
  COUNT(*) AS counter
FROM
   `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  resource.type = "gce_instance_group_manager"
  AND log_id = "cloudaudit.googleapis.com/activity"
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  1, 2
ORDER BY
  1, 2

BigQuery


SELECT
  TIMESTAMP_TRUNC(timestamp, DAY) AS day,
  protopayload_auditlog.methodName AS methodName,
  COUNT(*) AS counter
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_activity`
WHERE
  resource.type = "gce_instance_group_manager"
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  1, 2
ORDER BY
  1, 2

Questions sur l'accès aux données

Ces requêtes effectuent une analyse pour comprendre qui accède aux données ou les modifie dans Google Cloud.

Quels sont les utilisateurs ayant le plus consulté des données durant la semaine passée ?

La requête suivante utilise les journaux d'audit pour l'accès aux données pour identifier les utilisateurs qui ont le plus fréquemment accédé aux données des tables BigQuery au cours de la semaine écoulée.

Analyse de journaux


SELECT
  proto_payload.audit_log.authentication_info.principal_email,
  COUNT(*) AS COUNTER
FROM
   `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  (proto_payload.audit_log.method_name = "google.cloud.bigquery.v2.JobService.InsertJob" OR
   proto_payload.audit_log.method_name = "google.cloud.bigquery.v2.JobService.Query")
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
  AND log_id = "cloudaudit.googleapis.com/data_access"
GROUP BY
  1
ORDER BY
  2 desc, 1
LIMIT
  100

BigQuery


SELECT
  protopayload_auditlog.authenticationInfo.principalEmail,
  COUNT(*) AS COUNTER
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`
WHERE
  (protopayload_auditlog.methodName = "google.cloud.bigquery.v2.JobService.InsertJob" OR
   protopayload_auditlog.methodName = "google.cloud.bigquery.v2.JobService.Query")
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY
  1
ORDER BY
  2 desc, 1
LIMIT
  100

Quels utilisateurs ont accédé aux données de la table "accounts" le mois passé ?

La requête suivante utilise les journaux d'audit d'accès aux données pour identifier les utilisateurs qui ont le plus fréquemment interrogé une table accounts donnée au cours du mois écoulé. Outre les espaces réservés MY_DATASET_ID et MY_PROJECT_ID de votre destination d'exportation BigQuery, la requête suivante utilise les espaces réservés DATASET_ID et PROJECT_ID. Vous devez remplacer les espaces réservés DATASET_ID et PROJECT_ID pour spécifier la table cible dont l'accès est analysé, tel que la table accounts dans cet exemple.

Analyse de journaux


SELECT
  proto_payload.audit_log.authentication_info.principal_email,
  COUNT(*) AS COUNTER
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`,
  UNNEST(proto_payload.audit_log.authorization_info) authorization_info
WHERE
  (proto_payload.audit_log.method_name = "google.cloud.bigquery.v2.JobService.InsertJob" OR
   proto_payload.audit_log.method_name = "google.cloud.bigquery.v2.JobService.Query")
  AND authorization_info.permission = "bigquery.tables.getData"
  AND authorization_info.resource = "projects/[PROJECT_ID]/datasets/[DATASET_ID]/tables/accounts"
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  1
ORDER BY
  2 desc, 1
LIMIT
  100

BigQuery


SELECT
  protopayload_auditlog.authenticationInfo.principalEmail,
  COUNT(*) AS COUNTER
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`,
  UNNEST(protopayload_auditlog.authorizationInfo) authorizationInfo
WHERE
  (protopayload_auditlog.methodName = "google.cloud.bigquery.v2.JobService.InsertJob" OR
   protopayload_auditlog.methodName = "google.cloud.bigquery.v2.JobService.Query")
  AND authorizationInfo.permission = "bigquery.tables.getData"
  AND authorizationInfo.resource = "projects/[PROJECT_ID]/datasets/[DATASET_ID]/tables/accounts"
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  1
ORDER BY
  2 desc, 1
LIMIT
  100

Quelles sont les tables les plus fréquemment utilisées et par qui ?

La requête suivante utilise les journaux d'audit pour l'accès aux données pour identifier les tables BigQuery contenant les données les plus fréquemment lues et modifiées au cours du mois passé. Elle affiche l'identité de l'utilisateur associé, ainsi que la répartition du nombre total de fois où les données ont été lues et modifiées.

Analyse de journaux


SELECT
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.authentication_info.principal_email,
  COUNTIF(JSON_VALUE(proto_payload.audit_log.metadata, "$.tableDataRead") IS NOT NULL) AS dataReadEvents,
  COUNTIF(JSON_VALUE(proto_payload.audit_log.metadata, "$.tableDataChange") IS NOT NULL) AS dataChangeEvents,
  COUNT(*) AS totalEvents
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  STARTS_WITH(resource.type, 'bigquery') IS TRUE
  AND (JSON_VALUE(proto_payload.audit_log.metadata, "$.tableDataRead") IS NOT NULL
    OR JSON_VALUE(proto_payload.audit_log.metadata, "$.tableDataChange") IS NOT NULL)
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  1, 2
ORDER BY
  5 DESC, 1, 2
LIMIT 1000

BigQuery


SELECT
  protopayload_auditlog.resourceName,
  protopayload_auditlog.authenticationInfo.principalEmail,
  COUNTIF(JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataRead") IS NOT NULL) AS dataReadEvents,
  COUNTIF(JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataChange") IS NOT NULL) AS dataChangeEvents,
  COUNT(*) AS totalEvents
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`
WHERE
  STARTS_WITH(resource.type, 'bigquery') IS TRUE
  AND (JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataRead") IS NOT NULL
    OR JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataChange") IS NOT NULL)
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  1, 2
ORDER BY
  5 DESC, 1, 2
LIMIT 1000

Quelles sont les 10 requêtes les plus fréquentes dans BigQuery au cours de la semaine écoulée ?

La requête suivante utilise les journaux d'audit pour l'accès aux données pour identifier les requêtes les plus courantes au cours de la semaine écoulée. Elle répertorie également les utilisateurs correspondants et les tables référencées.

Analyse de journaux


SELECT
  COALESCE(
   JSON_VALUE(proto_payload.audit_log.metadata, "$.jobChange.job.jobConfig.queryConfig.query"),
   JSON_VALUE(proto_payload.audit_log.metadata, "$.jobInsertion.job.jobConfig.queryConfig.query")) as query,
  STRING_AGG(DISTINCT proto_payload.audit_log.authentication_info.principal_email, ',') as users,
  ANY_VALUE(COALESCE(
   JSON_EXTRACT_ARRAY(proto_payload.audit_log.metadata, "$.jobChange.job.jobStats.queryStats.referencedTables"),
   JSON_EXTRACT_ARRAY(proto_payload.audit_log.metadata, "$.jobInsertion.job.jobStats.queryStats.referencedTables"))) as tables,
  COUNT(*) AS counter
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  (resource.type = 'bigquery_project' OR resource.type = 'bigquery_dataset')
  AND operation.last IS TRUE
  AND (JSON_VALUE(proto_payload.audit_log.metadata, "$.jobChange") IS NOT NULL
    OR JSON_VALUE(proto_payload.audit_log.metadata, "$.jobInsertion") IS NOT NULL)
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY
  query
ORDER BY
  counter DESC
LIMIT 10

BigQuery


SELECT
  COALESCE(
   JSON_EXTRACT_SCALAR(protopayload_auditlog.metadataJson, "$.jobChange.job.jobConfig.queryConfig.query"),
   JSON_EXTRACT_SCALAR(protopayload_auditlog.metadataJson, "$.jobInsertion.job.jobConfig.queryConfig.query")) as query,
  STRING_AGG(DISTINCT protopayload_auditlog.authenticationInfo.principalEmail, ',') as users,
  ANY_VALUE(COALESCE(
   JSON_EXTRACT_ARRAY(protopayload_auditlog.metadataJson, "$.jobChange.job.jobStats.queryStats.referencedTables"),
   JSON_EXTRACT_ARRAY(protopayload_auditlog.metadataJson, "$.jobInsertion.job.jobStats.queryStats.referencedTables"))) as tables,
  COUNT(*) AS counter
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`
WHERE
  (resource.type = 'bigquery_project' OR resource.type = 'bigquery_dataset')
  AND operation.last IS TRUE
  AND (JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.jobChange") IS NOT NULL
    OR JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.jobInsertion") IS NOT NULL)
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY
  query
ORDER BY
  counter DESC
LIMIT 10

Quelles sont les actions les plus courantes enregistrées dans le journal d'accès aux données au cours du mois passé ?

La requête suivante utilise tous les journaux de Cloud Audit Logs pour identifier les 100 actions les plus fréquentes enregistrées au cours du mois passé.

Analyse de journaux


SELECT
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.service_name,
  resource.type,
  COUNT(*) AS counter
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND log_id="cloudaudit.googleapis.com/data_access"
GROUP BY
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.service_name,
  resource.type
ORDER BY
  counter DESC
LIMIT 100

BigQuery


SELECT
  protopayload_auditlog.methodName,
  protopayload_auditlog.serviceName,
  resource.type,
  COUNT(*) AS counter
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].cloudaudit_googleapis_com_data_access`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  protopayload_auditlog.methodName,
  protopayload_auditlog.serviceName,
  resource.type
ORDER BY
  counter DESC
LIMIT 100

Questions sur la sécurité du réseau

Ces exemples de requêtes effectuent une analyse de votre activité réseau dans Google Cloud.

Des connexions entre une nouvelle adresse IP et un sous-réseau spécifique ?

La requête suivante détecte les connexions de toute nouvelle adresse IP source à un sous-réseau donné en analysant les journaux de flux VPC. Dans cet exemple, une adresse IP source est considérée comme nouvelle si elle a été vue pour la première fois au cours des dernières 24 heures sur une période d'analyse de 60 jours. Vous pouvez utiliser et ajuster cette requête sur un sous-réseau soumis à une exigence de conformité particulière, telle que la norme PCI.

Analyse de journaux


SELECT
  JSON_VALUE(json_payload.connection.src_ip) as src_ip,
  -- TIMESTAMP supports up to 6 digits of fractional precision, so drop any more digits to avoid parse errors
  MIN(TIMESTAMP(REGEXP_REPLACE(JSON_VALUE(json_payload.start_time), r'\.(\d{0,6})\d+(Z)?$', '.\\1\\2'))) AS firstInstance,
  MAX(TIMESTAMP(REGEXP_REPLACE(JSON_VALUE(json_payload.start_time), r'\.(\d{0,6})\d+(Z)?$', '.\\1\\2'))) AS lastInstance,
  ARRAY_AGG(DISTINCT JSON_VALUE(resource.labels.subnetwork_name)) as subnetNames,
  ARRAY_AGG(DISTINCT JSON_VALUE(json_payload.dest_instance.vm_name)) as vmNames,
  COUNT(*) numSamples
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
  AND JSON_VALUE(json_payload.reporter) = 'DEST'
  AND JSON_VALUE(resource.labels.subnetwork_name) IN ('prod-customer-data')
GROUP BY
  src_ip
HAVING firstInstance >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
ORDER BY
  lastInstance DESC,
  numSamples DESC

BigQuery


SELECT
  jsonPayload.connection.src_ip as src_ip,
  -- TIMESTAMP supports up to 6 digits of fractional precision, so drop any more digits to avoid parse errors
  MIN(TIMESTAMP(REGEXP_REPLACE(jsonPayload.start_time, r'\.(\d{0,6})\d+(Z)?$', '.\\1\\2'))) AS firstInstance,
  MAX(TIMESTAMP(REGEXP_REPLACE(jsonPayload.start_time, r'\.(\d{0,6})\d+(Z)?$', '.\\1\\2'))) AS lastInstance,
  ARRAY_AGG(DISTINCT resource.labels.subnetwork_name) as subnetNames,
  ARRAY_AGG(DISTINCT jsonPayload.dest_instance.vm_name) as vmNames,
  COUNT(*) numSamples
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].compute_googleapis_com_vpc_flows`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
  AND jsonPayload.reporter = 'DEST'
  AND resource.labels.subnetwork_name IN ('prod-customer-data')
GROUP BY
  src_ip
HAVING firstInstance >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
ORDER BY
  lastInstance DESC,
  numSamples DESC

Des connexions bloquées par Google Cloud Armor ?

La requête suivante permet de détecter les tentatives d'exploitation potentielles en analysant les journaux d'équilibrage de charge d'application externes pour détecter toute connexion bloquée par la règle de sécurité configurée dans Google Cloud Armor. Cette requête suppose que vous avez configuré une règle de sécurité Google Cloud Armor sur votre équilibrage de charge d'application externe. Nous supposons également que vous avez activé la journalisation de l'équilibrage de charge d'application externe, comme décrit dans les instructions fournies par le lien Activer dans l'outil de champ d'application des journaux.

Analyse de journaux


SELECT
  timestamp,
  http_request.remote_ip,
  http_request.request_method,
  http_request.status,
  JSON_VALUE(json_payload.enforcedSecurityPolicy.name) AS security_policy_name,
  JSON_VALUE(resource.labels.backend_service_name) AS backend_service_name,
  http_request.request_url,
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="http_load_balancer"
  AND JSON_VALUE(json_payload.statusDetails) = "denied_by_security_policy"
ORDER BY
  timestamp DESC

BigQuery


SELECT
  timestamp,
  httpRequest.remoteIp,
  httpRequest.requestMethod,
  httpRequest.status,
  jsonpayload_type_loadbalancerlogentry.enforcedsecuritypolicy.name,
  resource.labels.backend_service_name,
  httpRequest.requestUrl,
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].requests`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="http_load_balancer"
  AND jsonpayload_type_loadbalancerlogentry.statusdetails = "denied_by_security_policy"
ORDER BY
  timestamp DESC

Un virus ou un logiciel malveillant de gravité élevée détecté par Cloud IDS ?

La requête suivante affiche les virus ou logiciels malveillants de gravité élevée éventuellement détectés par Cloud IDS en effectuant une recherche dans les journaux de menaces Cloud IDS. Dans cette requête, nous partons du principe que vous avez un point de terminaison Cloud IDS configuré.

Analyse de journaux


SELECT
  JSON_VALUE(json_payload.alert_time) AS alert_time,
  JSON_VALUE(json_payload.name) AS name,
  JSON_VALUE(json_payload.details) AS details,
  JSON_VALUE(json_payload.application) AS application,
  JSON_VALUE(json_payload.uri_or_filename) AS uri_or_filename,
  JSON_VALUE(json_payload.ip_protocol) AS ip_protocol,
FROM `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="ids.googleapis.com/Endpoint"
  AND JSON_VALUE(json_payload.alert_severity) IN ("HIGH", "CRITICAL")
  AND JSON_VALUE(json_payload.type) = "virus"
ORDER BY
  timestamp DESC

BigQuery


SELECT
  jsonPayload.alert_time,
  jsonPayload.name,
  jsonPayload.details,
  jsonPayload.application,
  jsonPayload.uri_or_filename,
  jsonPayload.ip_protocol
FROM `[MY_PROJECT_ID].[MY_DATASET_ID].ids_googleapis_com_threat`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND resource.type="ids.googleapis.com/Endpoint"
  AND jsonPayload.alert_severity IN ("HIGH", "CRITICAL")
  AND jsonPayload.type = "virus"
ORDER BY
  timestamp DESC

Quels sont les principaux domaines Cloud DNS interrogés à partir de votre réseau VPC ?

La requête suivante répertorie les 10 principaux domaines Cloud DNS interrogés depuis votre ou vos réseaux VPC au cours des 60 derniers jours. Cette requête suppose que vous avez activé la journalisation Cloud DNS pour vos réseaux VPC, comme décrit dans les instructions fournies par le lien Activer dans l'outil de champ d'application des journaux.

Analyse de journaux


SELECT
  JSON_VALUE(json_payload.queryName) AS query_name,
  COUNT(*) AS total_queries
FROM
  `[MY_PROJECT_ID].[MY_LOG_BUCKET_REGION].[MY_LOG_BUCKET_NAME]._AllLogs`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
  AND log_id="dns.googleapis.com/dns_queries"
GROUP BY
  query_name
ORDER BY
  total_queries DESC
LIMIT
  10

BigQuery


SELECT
 jsonPayload.queryname AS query_name,
 COUNT(*) AS total_queries
FROM
 `[MY_PROJECT_ID].[MY_DATASET_ID].dns_googleapis_com_dns_queries`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
GROUP BY
 query_name
ORDER BY
 total_queries DESC
LIMIT
 10

Étapes suivantes