Collecter les journaux Oracle Cloud Infrastructure
Ce document explique comment ingérer des journaux d'audit Oracle Cloud Infrastructure (OCI) dans Google Security Operations à l'aide de l'une des méthodes suivantes :
- Méthode 1 : Google Cloud Storage : une fonction OCI écrit les journaux dans un bucket Cloud Storage, et un flux Google SecOps les lit à partir du bucket.
- Méthode 2 : Webhook : une fonction OCI envoie les journaux directement à un flux de webhook Google SecOps. Cette méthode n'utilise pas de bucket Cloud Storage.
Les deux méthodes utilisent OCI Connector Hub pour envoyer les journaux d'audit à la fonction, car Oracle Cloud Infrastructure ne peut pas envoyer de journaux directement à Cloud Storage ni à un point de terminaison HTTPS.
Le service Oracle Cloud Infrastructure Audit enregistre automatiquement les appels vers tous les points de terminaison d'API (interface de programmation d'application) publics OCI compatibles en tant qu'événements de journal. Les événements de journaux enregistrés par le service d'audit incluent les appels d'API effectués par la console OCI, l'interface de ligne de commande (CLI), les kits de développement logiciel (SDK), vos propres clients personnalisés ou d'autres services OCI. Les informations contenues dans les journaux incluent l'heure à laquelle l'activité de l'API s'est produite, la source et la cible de l'activité, le type d'action et le type de réponse.
Avant de commencer
Assurez-vous de remplir les conditions suivantes :
- Une instance Google SecOps
- Accès privilégié à la console Oracle Cloud, avec les autorisations nécessaires pour créer et gérer les éléments suivants :
- Connecteurs Connector Hub
- Applications et fonctions Functions
- Stratégies IAM
- Un sous-réseau VCN avec accès à Internet pour la fonction OCI
- OCI Cloud Shell ou un environnement local avec la CLI Fn
- Pour la méthode 1 : un projet Google Cloud avec l'API Cloud Storage activée, et les autorisations nécessaires pour créer des buckets Cloud Storage, des comptes de service et des stratégies IAM (Identity and Access Management) de bucket
- Pour la méthode 2 : autorisation de créer des clés API dans le projet Google Cloud associé à votre instance Google SecOps
Méthode 1 : Cloud Storage
Créer un bucket Cloud Storage
- Accédez à la consoleGoogle Cloud .
- Sélectionnez votre projet ou créez-en un.
- Dans le menu de navigation, accédez à Cloud Storage > Buckets.
- Cliquez sur Créer un bucket.
Fournissez les informations de configuration suivantes :
Paramètre Valeur Attribuez un nom au bucket Saisissez un nom unique (par exemple, oci-audit-logs-gcs).Type d'emplacement Choisissez celle qui correspond le mieux à vos besoins (régionale, birégionale ou multirégionale). Emplacement Sélectionnez l'emplacement (par exemple, us-central1).Classe de stockage Standard (recommandé pour les journaux fréquemment consultés) Access control (Contrôle des accès) Uniforme (recommandé) Outils de protection Facultatif : Activez la gestion des versions d'objets ou la règle de conservation Cliquez sur Créer.
Configurer Oracle Cloud Infrastructure pour exporter les journaux d'audit vers Cloud Storage
Oracle Cloud Infrastructure n'est pas compatible avec l'exportation intégrée vers Cloud Storage. Vous utilisez le hub de connecteurs de service OCI avec une fonction OCI pour transférer les journaux d'audit vers Cloud Storage.
Créer une fonction Oracle Cloud Infrastructure pour transférer les journaux vers Cloud Storage
- Connectez-vous à la console Oracle Cloud.
- Ouvrez le menu de navigation, puis sélectionnez Developer Services> Functions> Applications.
- Sélectionnez le compartiment dans lequel vous souhaitez créer l'application de fonction.
- Cliquez sur Créer une application.
- Fournissez les informations de configuration suivantes :
- Nom : saisissez
audit-logs-to-gcs-app. - VCN : sélectionnez un réseau cloud virtuel.
- Sous-réseaux : sélectionnez un sous-réseau avec accès à Internet.
- Nom : saisissez
- Cliquez sur Créer.
- Une fois l'application créée, cliquez sur Getting Started (Premiers pas) et suivez les instructions pour configurer votre environnement de développement local avec la CLI Fn.
Créez un répertoire de fonction sur votre ordinateur local :
mkdir oci-audit-to-gcs cd oci-audit-to-gcsInitialisez une fonction Python :
fn init --runtime python oci-audit-to-gcs cd oci-audit-to-gcsRemplacez le contenu de
func.pypar le code suivant :import io import json import logging import os from fdk import response from google.cloud import storage from google.oauth2 import service_account from datetime import datetime # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger() # Environment variables GCS_BUCKET = os.environ.get('GCS_BUCKET') GCS_PREFIX = os.environ.get('GCS_PREFIX', 'oci-audit-logs') GCS_CREDENTIALS_JSON = os.environ.get('GCS_CREDENTIALS_JSON') def handler(ctx, data: io.BytesIO = None): """ OCI Function to forward Audit logs to GCS. Args: ctx: Function context data: Input data containing Audit log events """ if not all([GCS_BUCKET, GCS_CREDENTIALS_JSON]): logger.error('Missing required environment variables: GCS_BUCKET or GCS_CREDENTIALS_JSON') return response.Response( ctx, response_data=json.dumps({"error": "Missing configuration"}), headers={"Content-Type": "application/json"} ) try: # Parse input data body = json.loads(data.getvalue()) logger.info(f"Received event: {json.dumps(body)}") # Extract log entries log_entries = [] if isinstance(body, list): log_entries = body elif isinstance(body, dict): # Service Connector Hub sends data in specific format if 'data' in body: log_entries = [body['data']] if isinstance(body['data'], dict) else body['data'] else: log_entries = [body] if not log_entries: logger.info("No log entries to process") return response.Response( ctx, response_data=json.dumps({"status": "no_logs"}), headers={"Content-Type": "application/json"} ) # Initialize GCS client with service account credentials credentials_dict = json.loads(GCS_CREDENTIALS_JSON) credentials = service_account.Credentials.from_service_account_info(credentials_dict) storage_client = storage.Client(credentials=credentials, project=credentials_dict.get('project_id')) bucket = storage_client.bucket(GCS_BUCKET) # Write logs to GCS as NDJSON timestamp = datetime.utcnow().strftime('%Y%m%d_%H%M%S_%f') object_key = f"{GCS_PREFIX}/logs_{timestamp}.ndjson" blob = bucket.blob(object_key) ndjson = '\n'.join([json.dumps(entry, ensure_ascii=False) for entry in log_entries]) + '\n' blob.upload_from_string(ndjson, content_type='application/x-ndjson') logger.info(f"Wrote {len(log_entries)} records to gs://{GCS_BUCKET}/{object_key}") return response.Response( ctx, response_data=json.dumps({"status": "success", "records": len(log_entries)}), headers={"Content-Type": "application/json"} ) except Exception as e: logger.error(f'Error processing logs: {str(e)}') return response.Response( ctx, response_data=json.dumps({"error": str(e)}), headers={"Content-Type": "application/json"}, status_code=500 )Mettez à jour
requirements.txtavec les dépendances suivantes :fdk>=0.1.0 google-cloud-storage>=2.0.0 google-auth>=2.0.0Déployez la fonction sur OCI :
fn -v deploy --app audit-logs-to-gcs-appUne fois le déploiement terminé, notez l'OCID de la fonction. Vous l'utiliserez lors de la configuration du hub de connecteurs de service.
Configurer les variables d'environnement de la fonction
- Dans la console Oracle Cloud, accédez à Developer Services> Functions> Applications.
- Cliquez sur l'application (
audit-logs-to-gcs-app). - Cliquez sur le nom de la fonction (
oci-audit-to-gcs). - Cliquez sur Configuration
Ajoutez les variables de configuration suivantes :
Clé Valeur GCS_BUCKETLe nom de votre bucket Cloud Storage (par exemple, oci-audit-logs-gcs)GCS_PREFIXPréfixe des fichiers journaux (par exemple, oci-audit-logs)GCS_CREDENTIALS_JSONChaîne JSON de la clé de compte de service Google Cloud Cliquez sur Enregistrer les modifications.
Créer un compte de service Google Cloud pour la fonction Oracle Cloud Infrastructure
La fonction OCI a besoin d'un compte de service Google Cloud pour écrire dans le bucket Cloud Storage.
- Dans la console Google Cloud, accédez à IAM et administration > Comptes de service.
- Cliquez sur Créer un compte de service.
- Fournissez les informations de configuration suivantes :
- Nom du compte de service : saisissez
oci-function-gcs-writer. - Description du compte de service : saisissez
Service account for OCI Function to write Audit logs to GCS.
- Nom du compte de service : saisissez
- Cliquez sur Créer et continuer.
- Dans la section Autoriser ce compte de service à accéder au projet, ajoutez le rôle suivant :
- Cliquez sur Sélectionner un rôle.
- Recherchez et sélectionnez Administrateur des objets Storage.
- Cliquez sur Continuer.
- Cliquez sur OK.
- Cliquez sur l'adresse e-mail du compte de service que vous venez de créer.
- Accédez à l'onglet Clés.
- Cliquez sur Ajouter une clé> Créer une clé.
- Sélectionnez JSON comme type de clé.
- Cliquez sur Créer. Le fichier de clé JSON sera téléchargé sur votre ordinateur.
- Ouvrez le fichier de clé JSON et copiez l'intégralité de son contenu.
- Revenez à la configuration de la fonction dans la console Oracle Cloud.
Collez le contenu JSON dans la variable de configuration
GCS_CREDENTIALS_JSON.
Accorder des autorisations IAM sur le bucket Cloud Storage
Accordez au compte de service des autorisations d'écriture sur le bucket Cloud Storage comme suit :
- Accédez à Cloud Storage > Buckets.
- Cliquez sur le nom de votre bucket (
oci-audit-logs-gcs). - Accédez à l'onglet Autorisations.
- Cliquez sur Accorder l'accès.
- Fournissez les informations de configuration suivantes :
- Ajouter des comptes principaux : saisissez l'adresse e-mail du compte de service (
oci-function-gcs-writer@PROJECT_ID.iam.gserviceaccount.com). - Attribuer des rôles : sélectionnez Administrateur des objets Storage.
- Ajouter des comptes principaux : saisissez l'adresse e-mail du compte de service (
- Cliquez sur Enregistrer.
Créer un connecteur OCI Service Connector Hub
- Connectez-vous à la console Oracle Cloud.
- Ouvrez le menu de navigation, puis sélectionnez Analytics et IA. Sous Messagerie, sélectionnez Connector Hub.
- Sélectionnez le compartiment dans lequel vous souhaitez créer le connecteur de service.
- Cliquez sur Créer un connecteur.
Fournissez les informations de configuration suivantes :
Informations sur le connecteur :
Paramètre Valeur Nom du connecteur Saisissez audit-logs-to-gcs-connector.Description Saisissez Forward OCI Audit logs to Cloud Storage.Compartiment de ressources Sélectionnez le compartiment. Configurer la source :
Paramètre Valeur Source Sélectionnez Journalisation. Compartiment Sélectionnez le compartiment contenant les journaux d'audit. Groupe de journaux Sélectionnez _Audit (groupe de journaux par défaut pour les journaux d'audit).
Cliquez sur + Un autre journal.
Sélectionnez le journal d'audit de votre compartiment (par exemple,
_Audit_Include_Subcompartment).Configurez la cible :
Paramètre Valeur Cible Sélectionnez Fonctions. Compartiment de fonction Sélectionnez le compartiment contenant la fonction. Application de fonction Sélectionner audit-logs-to-gcs-appFonction Sélectionner oci-audit-to-gcs
Accédez à Configurer la tâche (facultatif) et conservez les paramètres par défaut.
Si vous êtes invité à créer une règle (requise pour créer ou mettre à jour un connecteur de service), sélectionnez Créer.
Cliquez sur Créer.
Créer une stratégie IAM pour Service Connector Hub
Le hub de connecteurs de service doit disposer des autorisations nécessaires pour appeler la fonction.
- Dans la console Oracle Cloud, accédez à Identity & Security> Policies (Identité et sécurité > Règles).
- Sélectionnez le compartiment dans lequel vous avez créé le connecteur Service Connector Hub.
- Cliquez sur Créer une règle.
- Fournissez les informations de configuration suivantes :
- Nom : saisissez
service-connector-functions-policy. - Description : saisissez
Allow Service Connector Hub to invoke Functions. - Compartiment : sélectionnez le compartiment.
- Nom : saisissez
- Dans la section Générateur de règles, activez l'option Afficher l'éditeur manuel.
Saisissez les instructions de stratégie suivantes :
Allow any-user to use fn-function in compartment <compartment-name> where all {request.principal.type='serviceconnector'} Allow any-user to use fn-invocation in compartment <compartment-name> where all {request.principal.type='serviceconnector'}Cliquez sur Créer.
Tester l'intégration
- Connectez-vous à la console Oracle Cloud.
- Effectuez des actions qui génèrent des journaux d'audit (par exemple, créer ou modifier une ressource).
- Attendez deux à cinq minutes que les journaux soient traités.
- Accédez à Cloud Storage > Buckets dans la console Google Cloud .
- Cliquez sur le nom de votre bucket (
oci-audit-logs-gcs). - Accédez au dossier du préfixe (
oci-audit-logs/). Vérifiez que de nouveaux fichiers
.ndjsonapparaissent dans le bucket.
Récupérer le compte de service Google SecOps
Google SecOps utilise un compte de service unique pour lire les données de votre bucket Cloud Storage. Vous devez accorder à ce compte de service l'accès à votre bucket.
Obtenir l'adresse e-mail du compte de service
- Accédez à Paramètres SIEM> Flux.
- Cliquez sur Ajouter un flux d'actualités.
- Cliquez sur Configurer un flux unique.
- Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple,
Oracle Cloud Audit Logs). - Sélectionnez Google Cloud Storage V2 comme Type de source.
- Sélectionnez Journaux d'audit Oracle Cloud Infrastructure comme Type de journal.
Cliquez sur Get Service Account (Obtenir un compte de service). Une adresse e-mail de compte de service unique s'affiche, par exemple :
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopiez cette adresse e-mail pour l'utiliser à l'étape suivante.
Accorder des autorisations IAM au compte de service Google SecOps
Le compte de service Google SecOps a besoin de deux rôles sur votre bucket Cloud Storage : un rôle "Lecteur des objets Storage" pour lire les objets de journal et un rôle au niveau du bucket pour lire les métadonnées du bucket.
- Accédez à Cloud Storage > Buckets.
- Cliquez sur le nom de votre bucket (
oci-audit-logs-gcs). - Accédez à l'onglet Autorisations.
- Cliquez sur Accorder l'accès.
- Fournissez les informations de configuration suivantes :
- Ajouter des comptes principaux : collez l'adresse e-mail du compte de service Google SecOps.
- Attribuer des rôles : sélectionnez les deux rôles suivants :
- Lecteur des objets de l'espace de stockage : lit les objets de journal.
- Lecteur des anciens buckets Storage : lit les métadonnées du bucket. Si vous avez sélectionné l'option de suppression Supprimer les fichiers transférés et les répertoires vides, sélectionnez plutôt Rédacteur d'ancien bucket Storage, qui accorde également l'autorisation de suppression.
Cliquez sur Enregistrer.
Configurer un flux dans Google SecOps pour ingérer les journaux d'audit Oracle Cloud Infrastructure
- Accédez à Paramètres SIEM> Flux.
- Cliquez sur Ajouter un flux d'actualités.
- Cliquez sur Configurer un flux unique.
- Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple,
Oracle Cloud Audit Logs). - Sélectionnez Google Cloud Storage V2 comme Type de source.
- Sélectionnez Journaux d'audit Oracle Cloud Infrastructure comme Type de journal.
- Cliquez sur Suivant.
Spécifiez les valeurs des paramètres d'entrée suivants :
URL du bucket de stockage : saisissez l'URI du bucket Cloud Storage avec le chemin d'accès du préfixe :
gs://oci-audit-logs-gcs/oci-audit-logs/Remplacez :
oci-audit-logs-gcs: nom de votre bucket Cloud Storage.oci-audit-logs: préfixe ou chemin d'accès facultatif où les journaux sont stockés (laissez vide pour la racine).
Exemples :
- Bucket racine :
gs://company-logs/ - Avec le préfixe :
gs://company-logs/oci-audit-logs/ - Avec le sous-dossier :
gs://company-logs/oracle/audit/
Option de suppression de la source : sélectionnez l'option de suppression de votre choix :
- Ne jamais supprimer les fichiers : ne supprime jamais les fichiers après les transferts (recommandé pour les tests).
- Supprimer les fichiers transférés et les répertoires vides : supprime les fichiers et les répertoires vides après un transfert réussi.
Âge maximal du fichier (jours) : incluez les fichiers modifiés au cours des derniers jours. La valeur par défaut est de 180 jours.
Espace de noms de l'élément : espace de noms de l'élément.
Étiquettes d'ingestion : étiquette à appliquer aux événements de ce flux.
Cliquez sur Suivant.
Vérifiez la configuration de votre nouveau flux d'actualités sur l'écran Finaliser, puis cliquez sur Envoyer.
Méthode 2 : Webhook
Avec cette méthode, Connector Hub envoie des lots d'entrées de journal d'audit à une fonction OCI, qui les envoie à un flux de webhook Google SecOps via HTTPS. Aucun bucket Cloud Storage n'est impliqué.
Créer un flux de webhook dans Google SecOps
Créer le flux
- Accédez à Paramètres SIEM> Flux.
- Cliquez sur Ajouter un flux d'actualités.
- Sur la page suivante, cliquez sur Configurer un seul flux.
- Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple,
OCI Audit Logs Webhook). - Sélectionnez Webhook comme type de source.
- Sélectionnez Journaux d'audit Oracle Cloud Infrastructure comme Type de journal.
- Cliquez sur Suivant.
- Spécifiez les valeurs des paramètres d'entrée suivants :
- Séparateur de division : saisissez
\n. La fonction envoie chaque entrée de journal sur sa propre ligne. - Espace de noms de l'élément : espace de noms de l'élément.
- Étiquettes d'ingestion : étiquette à appliquer aux événements de ce flux.
- Séparateur de division : saisissez
- Cliquez sur Suivant.
- Vérifiez la configuration de votre nouveau flux d'actualités sur l'écran Finaliser, puis cliquez sur Envoyer.
Générer et enregistrer la clé secrète
- Sur la page d'informations du flux, cliquez sur Générer une clé secrète.
Copiez et enregistrez la clé secrète de manière sécurisée.
Obtenir l'URL du point de terminaison du flux
- Accédez à l'onglet Détails du flux.
Dans la section Informations sur le point de terminaison, copiez l'URL du point de terminaison du flux. L'URL est au format suivant :
https://<REGION>-chronicle.googleapis.com/v1alpha/projects/<PROJECT_NUMBER>/locations/<REGION>/instances/<INSTANCE_ID>/feeds/<FEED_ID>:importPushLogsCliquez sur OK.
Créer une clé API Google Cloud
- Accédez à la page Identifiants de la consoleGoogle Cloud .
- Sélectionnez le projet associé à votre instance Google SecOps.
- Cliquez sur Créer des identifiants> Clé API.
- Cliquez sur Modifier la clé API pour restreindre la clé.
- Dans le champ Nom, saisissez un nom descriptif (par exemple,
oci-audit-webhook). - Sous Restrictions relatives aux API, sélectionnez Restreindre la clé, puis API Chronicle dans la liste Sélectionner des API.
- Cliquez sur Enregistrer.
- Copiez la valeur de la clé API et enregistrez-la de manière sécurisée.
Créer une fonction OCI pour transférer les journaux vers le webhook
Créer l'application
- Connectez-vous à la console Oracle Cloud.
- Ouvrez le menu de navigation, puis sélectionnez Developer Services> Functions> Applications.
- Sélectionnez le compartiment dans lequel vous souhaitez créer l'application de fonction.
- Cliquez sur Créer une application.
- Fournissez les informations de configuration suivantes :
- Nom : saisissez
audit-logs-to-secops-app. - VCN : sélectionnez un réseau cloud virtuel.
- Sous-réseaux : sélectionnez un sous-réseau avec accès à Internet : un sous-réseau public avec une passerelle Internet ou un sous-réseau privé avec une passerelle NAT. La fonction doit atteindre le point de terminaison Google SecOps via HTTPS (port 443).
- Nom : saisissez
- Cliquez sur Créer.
Créer et déployer la fonction
- Une fois l'application créée, cliquez sur Getting Started (Premiers pas) et suivez les instructions pour configurer OCI Cloud Shell ou votre environnement de développement local avec la CLI Fn.
Initialisez une fonction Python :
fn init --runtime python oci-audit-to-secops cd oci-audit-to-secopsRemplacez le contenu de
func.pypar le code suivant :import io import json import logging import os import random import time from email.utils import parsedate_to_datetime import requests from fdk import response logging.basicConfig(level=logging.INFO) logger = logging.getLogger() # The webhook accepts at most 4 MB per request and 1 MB per log line. # Connector Hub delivers batches of up to 6 MB, so a batch is sent as several # requests, each made of whole log entries. MAX_REQUEST_BYTES = 3 * 1024 * 1024 MAX_LINE_BYTES = 1024 * 1024 MAX_ATTEMPTS = 5 RETRYABLE_STATUS = {429, 500, 502, 503, 504} # OCI stops the function at its configured timeout (300 seconds). Stop retrying # early enough to fail cleanly so that Connector Hub retries the whole batch. DEADLINE_SECONDS = 240 def to_lines(body): """Serialize each log entry from the Connector Hub batch as one JSON line.""" entries = body if isinstance(body, list) else [body] lines = [] for entry in entries: line = json.dumps(entry, ensure_ascii=False, separators=(',', ':')).encode('utf-8') if len(line) > MAX_LINE_BYTES: entry_id = entry.get('id') if isinstance(entry, dict) else None logger.error(f'Skipping log entry {entry_id}: {len(line)} bytes exceeds the 1 MB line limit') continue lines.append(line) return lines def to_requests(lines): """Group whole lines into newline-delimited request bodies below MAX_REQUEST_BYTES.""" chunk, size = [], 0 for line in lines: if chunk and size + len(line) + 1 > MAX_REQUEST_BYTES: yield b'\n'.join(chunk), len(chunk) chunk, size = [], 0 chunk.append(line) size += len(line) + 1 if chunk: yield b'\n'.join(chunk), len(chunk) def retry_after_seconds(value): """Parse a Retry-After header given either in seconds or as an HTTP date.""" if not value: return None try: return max(0.0, float(value)) except ValueError: pass try: return max(0.0, parsedate_to_datetime(value).timestamp() - time.time()) except (TypeError, ValueError, IndexError, OverflowError): return None def post(session, url, headers, payload, deadline): """Send one request, retrying throttling and server errors until the deadline.""" status, detail = None, '' for attempt in range(1, MAX_ATTEMPTS + 1): remaining = deadline - time.monotonic() if remaining < 5: break wait = None try: resp = session.post(url, data=payload, headers=headers, timeout=(10, min(60, remaining))) except requests.RequestException as e: status, detail = None, str(e) else: if 200 <= resp.status_code < 300: return status, detail = resp.status_code, resp.text[:500] if status not in RETRYABLE_STATUS: raise RuntimeError(f'Webhook rejected the request with HTTP {status}: {detail}') wait = retry_after_seconds(resp.headers.get('Retry-After')) if wait is None: wait = min(30, 2 ** attempt) + random.uniform(0, 1) if attempt == MAX_ATTEMPTS or time.monotonic() + wait >= deadline: break logger.warning(f'Attempt {attempt} failed (HTTP {status}): {detail}. Retrying in {wait:.1f} seconds') time.sleep(wait) raise RuntimeError(f'Webhook request failed (HTTP {status}): {detail}') def handler(ctx, data: io.BytesIO = None): """Forward a Connector Hub batch of OCI Audit log entries to the webhook feed. Any exception fails the invocation, and Connector Hub then retries the batch. """ deadline = time.monotonic() + DEADLINE_SECONDS url = os.environ.get('SECOPS_WEBHOOK_URL') api_key = os.environ.get('SECOPS_API_KEY') secret_key = os.environ.get('SECOPS_SECRET_KEY') if not all([url, api_key, secret_key]): raise RuntimeError('Missing configuration: SECOPS_WEBHOOK_URL, SECOPS_API_KEY and SECOPS_SECRET_KEY are required') raw = data.getvalue() if data else b'' if not raw.strip(): logger.info('Received an empty batch') return response.Response( ctx, response_data=json.dumps({'records': 0}), headers={'Content-Type': 'application/json'} ) lines = to_lines(json.loads(raw)) headers = { 'Content-Type': 'application/json', 'X-goog-api-key': api_key, 'X-Webhook-Access-Key': secret_key, } sent = 0 with requests.Session() as session: for payload, count in to_requests(lines): post(session, url, headers, payload, deadline) sent += count logger.info(f'Forwarded {sent} log entries') return response.Response( ctx, response_data=json.dumps({'records': sent}), headers={'Content-Type': 'application/json'} )Remplacez le contenu de
requirements.txtpar les dépendances suivantes :fdk>=0.1.0 requests>=2.32.0Ouvrez
func.yamlet ajoutez la ligne suivante pour augmenter le délai avant expiration de la fonction, qui passe de 30 secondes par défaut à 300 secondes au maximum :timeout: 300Déployez la fonction sur OCI :
fn -v deploy --app audit-logs-to-secops-app
Configurer les variables d'environnement de la fonction
- Dans la console Oracle Cloud, accédez à Developer Services> Functions> Applications.
- Cliquez sur l'application (
audit-logs-to-secops-app). - Cliquez sur le nom de la fonction (
oci-audit-to-secops). - Cliquez sur Configuration
Ajoutez les variables de configuration suivantes :
Clé Valeur SECOPS_WEBHOOK_URLURL du point de terminaison du flux SECOPS_API_KEYLa clé API Google Cloud SECOPS_SECRET_KEYClé secrète du flux Cliquez sur Enregistrer les modifications.
Activer les journaux de fonction
- Sur la page de la liste Applications, sélectionnez
audit-logs-to-secops-app. - Sélectionnez l'onglet Surveillance, puis accédez à la section Journaux.
- Dans le menu Actions (trois points) de la catégorie Journaux d'appel de fonction, sélectionnez Activer le journal.
- Conservez le compartiment, le groupe de journaux et le nom de journal par défaut, ou modifiez-les si nécessaire.
- Sélectionnez Activer le journal.
Créer un connecteur OCI Connector Hub
- Ouvrez le menu de navigation, puis sélectionnez Analytics et IA. Sous Messagerie, sélectionnez Connector Hub.
- Sélectionnez le compartiment dans lequel vous souhaitez créer le connecteur.
- Cliquez sur Créer un connecteur.
Fournissez les informations de configuration suivantes :
Informations sur le connecteur :
Paramètre Valeur Nom du connecteur Saisissez audit-logs-to-secops-connector.Description Saisissez Forward OCI Audit logs to a webhook feed.Compartiment de ressources Sélectionnez le compartiment. Configurer la source :
Paramètre Valeur Source Sélectionnez Journalisation. Compartiment Sélectionnez le compartiment contenant les journaux d'audit. Groupe de journaux Sélectionnez _Audit (groupe de journaux par défaut pour les journaux d'audit).
Cliquez sur + Un autre journal.
Sélectionnez le journal d'audit de votre compartiment (par exemple,
_Audit_Include_Subcompartment).Configurez la cible :
Paramètre Valeur Cible Sélectionnez Fonctions. Compartiment de fonction Sélectionnez le compartiment contenant la fonction. Application de fonction Sélectionner audit-logs-to-secops-appFonction Sélectionner oci-audit-to-secops
Accédez à Configurer la tâche (facultatif) et conservez les paramètres par défaut.
Si vous êtes invité à créer une règle (requise pour créer ou mettre à jour un connecteur de service), sélectionnez Créer.
Cliquez sur Créer.
Créer une stratégie IAM pour le hub de connecteurs
Connector Hub doit disposer des autorisations nécessaires pour appeler la fonction.
- Dans la console Oracle Cloud, accédez à Identity & Security> Policies (Identité et sécurité > Règles).
- Sélectionnez le compartiment dans lequel vous avez créé le connecteur.
- Cliquez sur Créer une règle.
- Fournissez les informations de configuration suivantes :
- Nom : saisissez
connector-hub-secops-function-policy. - Description : saisissez
Allow Connector Hub to invoke the webhook forwarding function. - Compartiment : sélectionnez le compartiment.
- Nom : saisissez
- Dans la section Générateur de règles, activez l'option Afficher l'éditeur manuel.
Saisissez les instructions de stratégie suivantes :
Allow any-user to use fn-function in compartment <compartment-name> where all {request.principal.type='serviceconnector'} Allow any-user to use fn-invocation in compartment <compartment-name> where all {request.principal.type='serviceconnector'}Cliquez sur Créer.
Comment la fonction fournit les journaux
- Taille de lot : Connector Hub envoie à la fonction des lots d'une taille maximale de 6 Mo, et le webhook accepte jusqu'à 4 Mo par requête. La fonction divise chaque lot en requêtes d'une taille maximale de 3 Mo. Il ne fractionne que les entrées de journal, jamais l'intérieur d'une entrée, et chaque entrée arrive dans Google SecOps sous la forme d'un événement.
- Nouvelles tentatives : la fonction effectue de nouvelles tentatives pour les réponses HTTP 429 et 5xx avec un intervalle exponentiel entre les tentatives, et respecte l'en-tête
Retry-After. Toute autre erreur, ou une requête qui échoue toujours après cinq tentatives, entraîne l'échec de l'appel. Connector Hub relance ensuite l'ensemble du lot et ne déplace pas les lots suivants tant qu'il n'a pas réussi. - Conservation : la source Logging de Connector Hub conserve les données non distribuées pendant 24 heures. Si la distribution continue d'échouer pendant plus longtemps, les journaux non distribués les plus anciens sont perdus. Corrigez donc rapidement les erreurs signalées dans le journal de la fonction.
- Doublons : Connector Hub distribue chaque lot au moins une fois. Lorsqu'un lot est relancé après qu'une partie a déjà été envoyée, Google SecOps peut recevoir ces entrées deux fois.
- Entrées surdimensionnées : une entrée de journal de plus de 1 Mo dépasse la limite de ligne du webhook. La fonction l'ignore et écrit son ID dans le journal de la fonction.
Vérifier l'intégration
Pour vérifier l'intégration, procédez comme suit :
- Effectuez des actions dans la console Oracle Cloud qui génèrent des journaux d'audit (par exemple, créer ou modifier une ressource).
- Attendez deux à cinq minutes que Connector Hub transmette les journaux.
- Ouvrez le journal d'appel de fonction que vous avez activé et vérifiez qu'il contient des messages
Forwarded N log entries. Un message d'erreur inclut l'état HTTP renvoyé par Google SecOps. Dans Google SecOps, effectuez une recherche de journaux bruts pour le type de journal
OCI_AUDITet vérifiez que les événements d'audit arrivent.
Table de mappage UDM
| Champ du journal | Mappage UDM | Logique |
|---|---|---|
accept_encoding_field |
additional.fields |
Fusionné |
accept_field |
additional.fields |
Fusionné |
additional_app |
additional.fields |
Fusionné |
additional_content_type |
additional.fields |
Fusionné |
additional_sort_by |
additional.fields |
Fusionné |
additionaldetails_data |
additional.fields |
Fusionné |
allow_methods_field |
additional.fields |
Fusionné |
auth_type_label |
additional.fields |
Fusionné |
authorization_field |
additional.fields |
Fusionné |
backend_connect_time_field |
additional.fields |
Fusionné |
backend_processing_time_field |
additional.fields |
Fusionné |
caller_id_label |
additional.fields |
Fusionné |
caller_name_label |
additional.fields |
Fusionné |
cloud_event_versiom_field |
additional.fields |
Fusionné |
compartment_id_field |
additional.fields |
Fusionné |
compartment_name_field |
additional.fields |
Fusionné |
connection_field |
additional.fields |
Fusionné |
content_length_field |
additional.fields |
Fusionné |
content_type_field |
additional.fields |
Fusionné |
event_grouping_id_field |
additional.fields |
Fusionné |
event_name_label |
additional.fields |
Fusionné |
event_resource_label |
additional.fields |
Fusionné |
event_source_label |
additional.fields |
Fusionné |
event_type_label |
additional.fields |
Fusionné |
event_type_versiom_field |
additional.fields |
Fusionné |
has_compariment_id |
additional.fields |
Mappé : true → additional_app |
has_sort_by |
additional.fields |
Mappé : true → additional_sort_by |
listener_name_field |
additional.fields |
Fusionné |
log_group_id_field |
additional.fields |
Fusionné |
log_id_field |
additional.fields |
Fusionné |
message |
additional.fields |
Valeurs mappées (41 au total, par exemple \/ → tenant_id_label, \/ → auth_type_label, \/ → `ca... |
opc_request_id_field |
additional.fields |
Fusionné |
origin_field |
additional.fields |
Fusionné |
param0_field |
additional.fields |
Fusionné |
param1_field |
additional.fields |
Fusionné |
referer_field |
additional.fields |
Fusionné |
request_processing_time_field |
additional.fields |
Fusionné |
resource_id_field |
additional.fields |
Fusionné |
routing_rules_engine_errors_field |
additional.fields |
Fusionné |
routing_rules_matched_rule_field |
additional.fields |
Fusionné |
routing_rules_rule_hits_field |
additional.fields |
Fusionné |
routing_rules_rule_misses_field |
additional.fields |
Fusionné |
source_field |
additional.fields |
Fusionné |
tenant_id_label |
additional.fields |
Fusionné |
column3 |
extensions.auth.type |
Mappé : login successful → AUTHTYPE_UNSPECIFIED |
message |
extensions.auth.type |
Mappé : \/ → AUTHTYPE_UNSPECIFIED |
column3 |
metadata.description |
Mappage direct |
data.message |
metadata.description |
Mappage direct |
column1 |
metadata.event_timestamp |
Analysé en tant que yyyy-MM-dd HH:mm:ss |
data_event_time |
metadata.event_timestamp |
Analysé en tant que yyyy-MM-ddTHH:mm:ss.SSSSSSZ |
time |
metadata.event_timestamp |
Analysé en tant que ISO8601 |
metadata_event_type |
metadata.event_type |
Mappage direct |
type |
metadata.product_event_type |
Mappage direct |
data_event_id |
metadata.product_log_id |
Mappage direct |
id |
metadata.product_log_id |
Mappage direct |
message |
metadata.product_name |
Mappé : \/ → OCI_AUDIT |
specversion |
metadata.product_version |
Mappage direct |
message |
metadata.vendor_name |
Mappé : \/ → Oracle |
message |
network.application_protocol |
Mapped: \/ → HTTPS, \/ → HTTP |
protocol |
network.application_protocol |
Mapped: (?i)HTTPS → HTTPS, (?i)HTTP → HTTP |
version |
network.application_protocol_version |
Mappage direct |
data_request_action |
network.http.method |
Mappage direct |
method |
network.http.method |
Mappage direct |
data_identity_userAgent |
network.http.parsed_user_agent |
Renommé/Mappé |
data_request_agent |
network.http.parsed_user_agent |
Renommé/Mappé |
url |
network.http.referral_url |
Mappage direct |
data.backendStatusCode |
network.http.response_code |
Mappage direct |
data_response_status |
network.http.response_code |
Renommé/Mappé |
data.userAgent |
network.http.user_agent |
Mappage direct |
data_identity_userAgent |
network.http.user_agent |
Mappage direct |
data_request_agent |
network.http.user_agent |
Mappage direct |
data.receivedBytes |
network.received_bytes |
Mappage direct |
message |
network.received_bytes |
Mappé : \/ → uinteger |
data.sentBytes |
network.sent_bytes |
Mappage direct |
message |
network.sent_bytes |
Mappé : \/ → uinteger |
data_identity_consoleSessionId |
network.session_id |
Renommé/Mappé |
data.sslCipher |
network.tls.cipher |
Mappage direct |
data.sslProtocol |
network.tls.version |
Mappage direct |
data.host |
principal.asset.hostname |
Mappage direct |
hostname |
principal.asset.hostname |
Mappage direct |
column6 |
principal.asset.ip |
Fusionné |
data.forwardedForAddr |
principal.asset.ip |
Fusionné |
data_identity_ipAddress |
principal.asset.ip |
Mappé : ^(?:[0-9]{1,3}[.]){3}[0-9]{1,3}$ → data_identity_ipAddress |
data_request_origin |
principal.asset.ip |
Fusionné |
ip1 |
principal.asset.ip |
Fusionné |
ip2 |
principal.asset.ip |
Fusionné |
message |
principal.asset.ip |
Valeurs mappées (7 au total, par exemple \/ → column6, \/ → data_request_origin, \/ → ip2) |
src_ip |
principal.asset.ip |
Fusionné |
data.host |
principal.hostname |
Mappage direct |
hostname |
principal.hostname |
Mappage direct |
column6 |
principal.ip |
Fusionné |
data.forwardedForAddr |
principal.ip |
Fusionné |
data_identity_ipAddress |
principal.ip |
Mappé : ^(?:[0-9]{1,3}[.]){3}[0-9]{1,3}$ → data_identity_ipAddress |
data_request_origin |
principal.ip |
Fusionné |
ip1 |
principal.ip |
Fusionné |
ip2 |
principal.ip |
Fusionné |
message |
principal.ip |
Valeurs mappées (7 au total, par exemple \/ → column6, \/ → data_request_origin, \/ → ip2) |
src_ip |
principal.ip |
Fusionné |
data_request_headers_sec-ch-ua-platform_0 |
principal.platform |
Mappé : (?i)Linux → LINUX, (?i)windows → WINDOWS, (?i)mac/ios → MAC |
message |
principal.platform |
Mappé : \/ → LINUX, \/ → WINDOWS, \/ → MAC |
originalConnection.sourcePort |
principal.port |
Mappage direct |
src_port |
principal.port |
Mappage direct |
data_request_headers_oci-original-url_0 |
principal.url |
Mappage direct |
credentials_label |
principal.user.attribute.labels |
Fusionné |
message |
principal.user.attribute.labels |
Mappé : \/ → credentials_label |
data.identity.principalName |
principal.user.user_display_name |
Mappage direct |
data.username |
principal.user.user_display_name |
Mappage direct |
data.identity.principalId |
principal.user.userid |
Mappage direct |
data.principalId |
principal.user.userid |
Mappage direct |
column3 |
security_result |
Mappé : login successful → security_result |
message |
security_result |
Mappé : \/ → security_result |
allow_action |
security_result.action |
Fusionné |
column3 |
security_result.action |
Mappé : login successful → allow_action |
message |
security_result.action |
Mappé : \/ → allow_action |
credential_type_field |
security_result.detection_fields |
Fusionné |
message |
security_result.detection_fields |
Mappé : \/ → credential_type_field |
data.response.message |
security_result.summary |
Mappage direct |
message |
target.asset.ip |
Mapped: \/ → originalConnection.destinationIp, \/ → tar_ip |
originalConnection.destinationIp |
target.asset.ip |
Fusionné |
tar_ip |
target.asset.ip |
Fusionné |
message |
target.ip |
Mapped: \/ → originalConnection.destinationIp, \/ → tar_ip |
originalConnection.destinationIp |
target.ip |
Fusionné |
tar_ip |
target.ip |
Fusionné |
originalConnection.destinationPort |
target.port |
Mappage direct |
tar_port |
target.port |
Mappage direct |
message |
target.resource.attribute.labels |
Mappé : \/ → namespace_label |
namespace_label |
target.resource.attribute.labels |
Fusionné |
type |
target.resource.attribute.labels |
Mappé : listretentionrules → namespace_label |
data.resourceId |
target.resource.name |
Mappage direct |
data.resourceName |
target.resource.name |
Mappage direct |
bucketId |
target.resource.product_object_id |
Mappage direct |
data.resourceId |
target.resource.product_object_id |
Mappage direct |
data_request_id |
target.resource.product_object_id |
Mappage direct |
message |
target.resource.resource_type |
Mappé : \/ → STORAGE_BUCKET |
type |
target.resource.resource_type |
Mappé : listretentionrules → STORAGE_BUCKET |
data_request_path |
target.url |
Mappage direct |
column2 |
target.user.email_addresses |
Fusionné |
message |
target.user.email_addresses |
Mappé : \/ → column2 |
| N/A | extensions.auth.type |
Constante : AUTHTYPE_UNSPECIFIED |
| N/A | metadata.product_name |
Constante : OCI_AUDIT |
| N/A | metadata.vendor_name |
Constante : Oracle |
| N/A | network.application_protocol |
Constante : HTTPS |
| N/A | principal.platform |
Constante : LINUX |
| N/A | target.resource.resource_type |
Constante : STORAGE_BUCKET |
Journal des modifications
Afficher le journal des modifications de cet analyseur
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.