Raccogliere i log di Proofpoint Secure Email Relay
Questo documento spiega come importare i log di Proofpoint Secure Email Relay in Google Security Operations utilizzando Cloud Storage V2.
Proofpoint Secure Email Relay (SER) è un relè gestito per la posta generata dalle applicazioni, ad esempio messaggi transazionali e di notifica. SER genera report su questo traffico tramite la relativa API Reporting, una delle API di configurazione SER. L'API restituisce cifre di utilizzo aggregate: la posizione del throughput con licenza, il volume giornaliero e i conteggi dei messaggi, nonché i contatori per ogni utente di inoltro. Il parser mappa queste cifre nel modello Unified Data Model (UDM), registrandole come etichette insieme all'identità dell'utente di inoltro.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps
- Un progetto Google Cloud con l'API Storage di Cloud abilitata
- Autorizzazioni per creare e gestire bucket Cloud Storage
- Autorizzazioni per gestire i criteri IAM (Identity and Access Management) nei bucket Cloud Storage
- Autorizzazioni per creare servizi Cloud Run, argomenti Pub/Sub e job Cloud Scheduler
- Accesso amministratore al portale Proofpoint Secure Email Relay, inclusa l'autorizzazione per creare chiavi API
Crea un bucket Cloud Storage
- Vai alla consoleGoogle Cloud .
- Seleziona il tuo progetto o creane uno nuovo.
- Nel menu di navigazione, vai a Cloud Storage > Bucket.
- Fai clic su Crea bucket.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Assegna un nome al bucket Inserisci un nome univoco globale (ad esempio proofpoint-ser-logs).Tipo di località Scegli in base alle tue esigenze (regione singola, a due regioni, multiregionale) Località Seleziona la posizione (ad esempio, us-central1)Classe di archiviazione Standard (consigliato per i log a cui si accede di frequente) Controllo degli accessi Uniforme (consigliato) Strumenti di protezione (Facoltativo) Attiva il controllo delle versioni degli oggetti o la policy di conservazione Fai clic su Crea.
Raccogli le credenziali API Proofpoint SER
L'accesso all'API Reporting viene concesso da una chiave API emessa dal servizio Key Management Service di Proofpoint. La chiave non viene creata all'interno della console SER, motivo per cui non viene visualizzata in nessuna delle voci di navigazione SER.
crea una chiave API
- Accedi al portale Proofpoint Secure Email Relay con le credenziali di amministratore.
- Apri il selettore di app nell'angolo in alto a sinistra.
- Vai a Servizi > Gestione delle chiavi API.
- Fai clic su Crea chiave.
- Seleziona Secure Email Relay come prodotto.
Copia e memorizza in modo sicuro i seguenti valori:
- Chiave: utilizzata come
client_id - Secret: utilizzato come
client_secret
- Chiave: utilizzata come
Verifica le autorizzazioni
Il servizio Gestione chiavi API è condiviso tra più prodotti Proofpoint, motivo per cui vi accedi tramite il selettore di app anziché tramite il menu di navigazione SER. Per accedere alle API di configurazione SER, inclusa l'API Reporting, devi selezionare Secure Email Relay come prodotto durante la creazione della chiave.
Se Gestione chiavi API non viene visualizzata nel selettore di app, il tuo account non dispone dell'autorizzazione di gestione delle API. Contatta l'amministratore o il team dedicato all'account Proofpoint per ottenere l'autorizzazione.
Testare l'accesso API
L'API Reporting utilizza la concessione delle credenziali client OAuth 2.0. Scambia la chiave e il secret con un token di autenticazione, quindi chiama l'API con quel token.
# Replace with the values you copied CLIENT_ID="<your-key>" CLIENT_SECRET="<your-secret>" # 1. Exchange the key and secret for an access token ACCESS_TOKEN=$(curl -s -X POST "https://auth.proofpoint.com/v1/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=${CLIENT_ID}" \ -d "client_secret=${CLIENT_SECRET}" \ | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])") # 2. Call the Reporting API with the token curl -v -H "Authorization: Bearer ${ACCESS_TOKEN}" \ "https://reporting.ser.proofpoint.com/v1/usage/overview"
Una chiamata riuscita restituisce un oggetto JSON il cui membro data contiene throughputLimit, licenseStartDate, licenseEndDate e le medie di velocità effettiva.
Crea un account di servizio per la funzione Cloud Run
La funzione Cloud Run richiede un account di servizio con autorizzazioni per scrivere in un bucket Cloud Storage e per essere richiamato da Pub/Sub.
Crea il account di servizio
- Nella console Google Cloud, vai a IAM e amministrazione > Service account.
- Fai clic su Crea account di servizio.
- Fornisci i seguenti dettagli di configurazione:
- Nome del service account: inserisci
proofpoint-ser-collector-sa - Descrizione service account: inserisci
Service account for Cloud Run function to collect Proofpoint Secure Email Relay logs
- Nome del service account: inserisci
- Fai clic su Crea e continua.
- Nella sezione Concedi a questo account di servizio l'accesso al progetto, aggiungi i seguenti ruoli:
- Fai clic su Seleziona un ruolo.
- Cerca e seleziona Storage Object Admin.
- Fai clic su + Aggiungi un altro ruolo.
- Cerca e seleziona Cloud Run Invoker.
- Fai clic su + Aggiungi un altro ruolo.
- Cerca e seleziona Invoker di Cloud Functions.
- Fai clic su Continua.
- Fai clic su Fine.
Questi ruoli sono necessari per:
- Storage Object Admin: scrive i log in un bucket Cloud Storage e gestisce i file di stato
- Cloud Run Invoker: consente a Pub/Sub di richiamare la funzione
- Cloud Functions Invoker: consente la chiamata di funzioni
Concedere le autorizzazioni IAM sul bucket Cloud Storage
Concedi all'account di servizio le autorizzazioni di scrittura sul bucket Cloud Storage:
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (ad esempio
proofpoint-ser-logs). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: inserisci l'email del account di servizio (ad esempio,
proofpoint-ser-collector-sa@PROJECT_ID.iam.gserviceaccount.com). - Assegna i ruoli: seleziona Storage Object Admin.
- Aggiungi entità: inserisci l'email del account di servizio (ad esempio,
- Fai clic su Salva.
Crea un argomento Pub/Sub
Crea un argomento Pub/Sub a cui Cloud Scheduler pubblicherà e a cui la funzione Cloud Run si iscriverà.
- Nella console GCP, vai a Pub/Sub > Argomenti.
- Fai clic su Crea argomento.
- Fornisci i seguenti dettagli di configurazione:
- ID argomento: inserisci
proofpoint-ser-trigger - Lascia invariate le altre impostazioni predefinite.
- ID argomento: inserisci
- Fai clic su Crea.
Crea una funzione Cloud Run per raccogliere i log
La funzione Cloud Run verrà attivata dai messaggi Pub/Sub di Cloud Scheduler per recuperare i report sull'utilizzo dall'API SER Reporting e scriverli in Cloud Storage.
- Nella console GCP, vai a Cloud Run.
- Fai clic su Crea servizio.
- Seleziona Funzione (usa un editor in linea per creare una funzione).
Nella sezione Configura, fornisci i seguenti dettagli di configurazione:
Impostazione Valore Nome servizio proofpoint-ser-collectorRegione Seleziona la regione corrispondente al bucket Cloud Storage (ad esempio, us-central1)Tempo di esecuzione Seleziona Python 3.12 o versioni successive Nella sezione Trigger (facoltativo):
- Fai clic su + Aggiungi trigger.
- Seleziona Cloud Pub/Sub.
- In Seleziona un argomento Cloud Pub/Sub, scegli l'argomento Pub/Sub (
proofpoint-ser-trigger). - Fai clic su Salva.
Nella sezione Autenticazione:
- Seleziona Richiedi autenticazione.
- Controlla Identity and Access Management (IAM).
Vai a Container, networking, sicurezza ed espandilo.
Vai alla scheda Sicurezza:
- Service account: seleziona il account di servizio (
proofpoint-ser-collector-sa).
- Service account: seleziona il account di servizio (
Vai alla scheda Container:
- Fai clic su Variabili e secret.
- Fai clic su + Aggiungi variabile per ogni variabile di ambiente:
Nome variabile Valore di esempio Descrizione GCS_BUCKETproofpoint-ser-logsNome del bucket Cloud Storage GCS_PREFIXser-logsPrefisso per i file di log STATE_KEYser-logs-state.jsonPercorso dello stato, al di fuori del prefisso del log TOKEN_URLhttps://auth.proofpoint.com/v1/tokenEndpoint del token OAuth 2.0 API_BASEhttps://reporting.ser.proofpoint.comURL di base dell'API SER Reporting CLIENT_IDyour-keyLa chiave della gestione delle chiavi API CLIENT_SECRETyour-secretIl secret di Gestione chiavi API PAGE_SIZE50Utenti con disabilità uditive richiesti per pagina MAX_PAGES200Limite di pagine per la paginazione degli utenti di inoltro REPORT_DAY_OFFSET1Report sul giorno di questo numero di giorni fa MAX_BACKFILL_DAYS7La maggior parte dei giorni un'unica esecuzione eseguirà il backfill SEEN_RETENTION_DAYS7Giorni di chiavi di deduplicazione mantenute nello stato Nella sezione Variabili e secret, vai a Richieste:
- Timeout richiesta: inserisci
600secondi (10 minuti)
- Timeout richiesta: inserisci
Vai alla scheda Impostazioni:
- Nella sezione Risorse:
- Memoria: seleziona 512 MiB o un valore superiore.
- CPU: seleziona 1
- Nella sezione Risorse:
Nella sezione Scalabilità della revisione:
- Numero minimo di istanze: inserisci
0 - Numero massimo di istanze: inserisci
100(o modifica in base al carico previsto)
- Numero minimo di istanze: inserisci
Fai clic su Crea.
Attendi la creazione del servizio (1-2 minuti).
Dopo aver creato il servizio, si aprirà automaticamente l'editor di codice incorporato.
Aggiungi il codice per la funzione
- Inserisci main nel campo Entry point (Punto di ingresso).
- Nell'editor di codice incorporato, crea due file:
Primo file - main.py:
import functions_framework from google.cloud import storage from google.cloud.exceptions import NotFound import hashlib import json import os import time import urllib.parse import urllib3 from datetime import date, datetime, timezone, timedelta # Initialize HTTP client with timeouts http = urllib3.PoolManager( timeout=urllib3.Timeout(connect=5.0, read=30.0), retries=False, ) # Initialize Storage client storage_client = storage.Client() # Environment variables GCS_BUCKET = os.environ.get('GCS_BUCKET') GCS_PREFIX = os.environ.get('GCS_PREFIX', 'ser-logs') # STATE_KEY must stay OUTSIDE GCS_PREFIX. The feed ingests every object under # its bucket URI and, with a deletion option selected, deletes what it # transferred. A state file inside the prefix would be ingested as log data and # then deleted, resetting collection and re-ingesting duplicates. STATE_KEY = os.environ.get('STATE_KEY', 'ser-logs-state.json') TOKEN_URL = os.environ.get('TOKEN_URL', 'https://auth.proofpoint.com/v1/token') API_BASE = os.environ.get('API_BASE', 'https://reporting.ser.proofpoint.com') CLIENT_ID = os.environ.get('CLIENT_ID') CLIENT_SECRET = os.environ.get('CLIENT_SECRET') PAGE_SIZE = int(os.environ.get('PAGE_SIZE', '50')) MAX_PAGES = int(os.environ.get('MAX_PAGES', '200')) # The Reporting API filters on whole calendar days, so the collector reports on # a day that has already finished rather than on a partial one. REPORT_DAY_OFFSET = int(os.environ.get('REPORT_DAY_OFFSET', '1')) MAX_BACKFILL_DAYS = int(os.environ.get('MAX_BACKFILL_DAYS', '7')) SEEN_RETENTION_DAYS = int(os.environ.get('SEEN_RETENTION_DAYS', '7')) MAX_RATE_LIMIT_RETRIES = 5 class FetchError(Exception): """Raised when a Proofpoint SER API call fails. Collection must fail loudly. Returning an empty result on an API error is indistinguishable from a day with no traffic, and would let the run record a day it never actually read. """ def get_access_token(): """Exchange the API key and secret for an OAuth 2.0 bearer token. The SER configuration APIs use the client credentials grant with the credentials in the form body. The returned token is sent to each API host as an Authorization: Bearer header. """ body = urllib.parse.urlencode({ 'grant_type': 'client_credentials', 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, }) headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json', } try: response = http.request('POST', TOKEN_URL, body=body, headers=headers) except Exception as e: raise FetchError(f'Token request to {TOKEN_URL} failed: {e}') from e if response.status != 200: raise FetchError(f'HTTP {response.status} from {TOKEN_URL}: {response.data.decode("utf-8")}') try: token = json.loads(response.data.decode('utf-8')).get('access_token') except json.JSONDecodeError as e: raise FetchError(f'Malformed token response from {TOKEN_URL}: {e}') from e if not token: raise FetchError('Token response did not contain an access_token') return token def call_api(token, method, path, body=None): """Call one Reporting API endpoint and return the decoded JSON body. Every failure raises. A caller that mistook an error for an empty report would record the day as collected and never come back to it. """ url = f'{API_BASE}{path}' headers = { 'Authorization': f'Bearer {token}', 'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'GoogleSecOps-ProofpointSERCollector/1.0', } payload = json.dumps(body) if body is not None else None backoff = 1.0 retries = 0 while True: try: response = http.request(method, url, body=payload, headers=headers) except Exception as e: raise FetchError(f'Request to {url} failed: {e}') from e if response.status == 429: retries += 1 if retries > MAX_RATE_LIMIT_RETRIES: raise FetchError(f'Rate limited repeatedly by {url}; giving up without recording the day') raw_retry_after = response.headers.get('Retry-After') try: # Retry-After may also be an HTTP date, which int() cannot parse. delay = int(raw_retry_after) if raw_retry_after else int(backoff) except (TypeError, ValueError): delay = int(backoff) print(f'Rate limited (429) on {path}. Retrying after {delay}s...') time.sleep(delay) backoff = min(backoff * 2, 30.0) continue if response.status != 200: raise FetchError(f'HTTP {response.status} from {url}: {response.data.decode("utf-8")}') try: return json.loads(response.data.decode('utf-8')) except json.JSONDecodeError as e: raise FetchError(f'Malformed JSON response from {url}: {e}') from e def as_list(value): """Return a response data member as a list. The Reporting API returns data as an object on some endpoints and as an array on others, and the published schema declares neither. """ if value is None: return [] if isinstance(value, list): return value return [value] def collect_day(token, day, include_overview): """Collect one reporting day and return the records to write. The nesting of each record is chosen to match what the parser expects. Rows carrying acceptedMessages are emitted bare, because the parser nests those under data itself. The other two responses are emitted whole, so that their data and metadata envelope survives to the parser. """ records = [] # Licensed throughput position. This endpoint takes no date and reports # the tenant's standing right now, so it is collected once per run rather # than once per day: a backfill would otherwise write the same snapshot # against every day it catches up on. if include_overview: records.append(call_api(token, 'GET', '/v1/usage/overview')) # Volume in bytes for the day. One envelope per row, so that the # totalThroughput in metadata stays attached to the row it describes. data_trend = call_api(token, 'POST', '/v1/usage/data-trend', { 'dates': day, 'interval': 'day', }) for element in as_list(data_trend.get('data')): records.append({'data': [element], 'metadata': data_trend.get('metadata', {})}) # Message counters for the day. message_trend = call_api(token, 'POST', '/v1/usage/message-trend', { 'dates': day, 'interval': 'day', }) records.extend(as_list(message_trend.get('data'))) # Per relay user counters, paginated. page = 1 while True: if page > MAX_PAGES: raise FetchError(f'Relay user pagination for {day} exceeded MAX_PAGES ({MAX_PAGES})') payload = call_api(token, 'POST', '/v1/usage/relay-users', { 'dates': day, 'pageNum': page, 'pageSize': PAGE_SIZE, }) elements = as_list(payload.get('data')) if not elements: break records.extend(elements) pagination = (payload.get('metadata') or {}).get('pagination') or {} total_pages = pagination.get('totalPages') if not total_pages or page >= total_pages: break page += 1 return records def record_key(record): """Return the deduplication identity of one record. Reporting rows are aggregates and carry no identifier of their own, so identity is the content hash. Keys are held per reporting day, which makes a repeated run of the same day a no-op without ever suppressing a new day whose figures happen to be identical. """ return 'sha256:' + hashlib.sha256( json.dumps(record, sort_keys=True, ensure_ascii=False).encode('utf-8') ).hexdigest() def pending_days(last_report_date, target): """Return the reporting days still to collect, oldest first.""" if not last_report_date: start = target else: start = date.fromisoformat(last_report_date) + timedelta(days=1) if start > target: return [] if (target - start).days >= MAX_BACKFILL_DAYS: start = target - timedelta(days=MAX_BACKFILL_DAYS - 1) print(f'Backfill capped at {MAX_BACKFILL_DAYS} days. Days before {start.isoformat()} are not collected.') return [start + timedelta(days=offset) for offset in range((target - start).days + 1)] def prune_seen(seen, target): """Drop deduplication keys for days outside the retention window.""" cutoff = target - timedelta(days=SEEN_RETENTION_DAYS) return {day: keys for day, keys in seen.items() if date.fromisoformat(day) >= cutoff} @functions_framework.cloud_event def main(cloud_event): """Fetch Proofpoint SER usage reports and write them to Cloud Storage. Args: cloud_event: CloudEvent object containing the Pub/Sub message. """ if not all([GCS_BUCKET, CLIENT_ID, CLIENT_SECRET]): # Raise rather than return: a bare return acks the Pub/Sub message and # reports the run as successful, silently discarding the schedule tick. raise RuntimeError('Missing required environment variables') bucket = storage_client.bucket(GCS_BUCKET) state = load_state(bucket, STATE_KEY) seen = state.get('seen') or {} now = datetime.now(timezone.utc) target = (now - timedelta(days=REPORT_DAY_OFFSET)).date() days = pending_days(state.get('last_report_date'), target) if not days: print(f'Nothing to collect. {target.isoformat()} is already recorded.') return token = get_access_token() for day in days: key = day.isoformat() print(f'Collecting reporting day {key}') # A FetchError here propagates: the run fails, the state is left at the # last day that was fully written, and the next run retries this day. records = collect_day(token, key, include_overview=(day == days[-1])) day_seen = set(seen.get(key, [])) fresh = [] for record in records: digest = record_key(record) if digest in day_seen: continue day_seen.add(digest) fresh.append(record) print(f'{key}: fetched {len(records)} records, {len(fresh)} new after deduplication') if fresh: timestamp = now.strftime('%Y%m%dT%H%M%SZ') object_key = f'{GCS_PREFIX}/usage_{key}_{timestamp}.ndjson' blob = bucket.blob(object_key) ndjson = '\n'.join(json.dumps(record, ensure_ascii=False) for record in fresh) + '\n' blob.upload_from_string(ndjson, content_type='application/x-ndjson') print(f'Wrote {len(fresh)} records to gs://{GCS_BUCKET}/{object_key}') # Record the day only after its data is durably written. seen[key] = sorted(day_seen) state['last_report_date'] = key state['seen'] = prune_seen(seen, target) save_state(bucket, STATE_KEY, state) print(f'Successfully processed {len(days)} reporting day(s)') def load_state(bucket, key): """Read the collector state from Cloud Storage. Only a missing object is treated as a cold start. Any other error is raised: swallowing it would silently restart collection and re-ingest the whole backfill window. """ blob = bucket.blob(key) try: return json.loads(blob.download_as_text()) except NotFound: print('No state file found. Starting from the most recent completed day.') return {} def save_state(bucket, key, state): """Write the collector state to Cloud Storage. Failures are raised, not logged. If the state write fails after the data was uploaded, the next run repeats the same day and duplicates it. """ blob = bucket.blob(key) blob.upload_from_string( json.dumps(state, indent=2), content_type='application/json', ) print(f'Saved state: last_report_date={state.get("last_report_date")}')Secondo file:requirements.txt:
functions-framework==3.* google-cloud-storage==2.* urllib3>=2.0.0
- Fai clic su Esegui il deployment per salvare la funzione ed eseguirne il deployment.
Attendi il completamento del deployment (2-3 minuti).
Crea un job Cloud Scheduler
Cloud Scheduler pubblicherà messaggi nell'argomento Pub/Sub a intervalli regolari, attivando la funzione Cloud Run.
- Nella console GCP, vai a Cloud Scheduler.
- Fai clic su Crea job.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Nome proofpoint-ser-collector-dailyRegione Seleziona la stessa regione della funzione Cloud Run Frequenza 0 2 * * *(ogni giorno alle ore 02:00)Fuso orario Seleziona il fuso orario (UTC consigliato) Tipo di target Pub/Sub Argomento Seleziona l'argomento Pub/Sub ( proofpoint-ser-trigger).Corpo del messaggio {}(oggetto JSON vuoto)Fai clic su Crea.
Opzioni di frequenza di pianificazione
L'API Reporting esegue l'aggregazione per giorno di calendario, quindi un giorno completato viene raccolto una sola volta. Esegui il job ogni giorno, dopo la chiusura del giorno del report nel fuso orario del tenant:
| Frequenza | Espressione cron | Caso d'uso |
|---|---|---|
| Ogni giorno alle 02:00 | 0 2 * * * |
Standard (consigliato) |
| Ogni giorno alle 06:00 | 0 6 * * * |
Inquilini il cui report viene saldato in un secondo momento |
| Due volte al giorno | 0 2,14 * * * |
Aggiunge un nuovo tentativo nello stesso giorno se la prima esecuzione non è riuscita |
Un'esecuzione che rileva che il giorno è già stato registrato termina senza scrivere nulla, quindi un'esecuzione aggiuntiva costa una chiamata API e non duplica mai i dati.
Testare l'integrazione
- Nella console Cloud Scheduler, trova il tuo job.
- Fai clic su Forza esecuzione per attivare il job manualmente.
- Attendi qualche secondo.
- Vai a Cloud Run > Servizi.
- Fai clic sul nome della funzione (
proofpoint-ser-collector). - Fai clic sulla scheda Log.
Verifica che la funzione sia stata eseguita correttamente. Cerca:
Collecting reporting day YYYY-MM-DD YYYY-MM-DD: fetched X records, X new after deduplication Wrote X records to gs://proofpoint-ser-logs/ser-logs/usage_YYYY-MM-DD_YYYYMMDDTHHMMSSZ.ndjson Saved state: last_report_date=YYYY-MM-DD Successfully processed 1 reporting day(s)Vai a Cloud Storage > Bucket.
Fai clic sul nome del bucket (
proofpoint-ser-logs).Vai alla cartella del prefisso (
ser-logs/).Verifica che sia stato creato un nuovo file
.ndjsoncon il timestamp corrente.
Se visualizzi errori nei log:
- HTTP 400 dall'endpoint token: la chiave o il segreto non sono corretti oppure la chiave è scaduta.
invalid_clientsignifica che la coppia è stata rifiutata; crea una chiave sostitutiva. - HTTP 401 dall'API Reporting: il token di autenticazione non è stato inviato o non è più valido.
- HTTP 429: limitazione della frequenza. La funzione esegue nuovi tentativi con backoff e l'esecuzione non va a buon fine se il limite persiste, lasciando il giorno all'esecuzione successiva.
- Variabili di ambiente mancanti: controlla che tutte le variabili richieste siano impostate.
Recuperare il account di servizio Google SecOps
Google SecOps utilizza un account di servizio univoco per leggere i dati dal tuo bucket Cloud Storage. Devi concedere a questo account di servizio l'accesso al tuo bucket.
Recupera l'email del account di servizio
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo feed.
- Fai clic su Configura un singolo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio,
Proofpoint SER Logs). - Seleziona Google Cloud Storage V2 come Tipo di origine.
- Seleziona ProofPoint Secure Email Relay come Tipo di log.
- Fai clic su Ottieni service account.
Verrà visualizzata un'email del account di servizio univoca, ad esempio:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopia questo indirizzo email per utilizzarlo nel passaggio successivo.
Fai clic su Avanti.
Specifica i valori per i seguenti parametri di input:
URL del bucket di archiviazione: inserisci l'URI del bucket Cloud Storage con il percorso del prefisso:
gs://proofpoint-ser-logs/ser-logs/- Sostituisci:
proofpoint-ser-logs: il nome del bucket Cloud Storage.ser-logs: (Facoltativo) prefisso o percorso della cartella in cui sono archiviati i log (lascia vuoto per la radice).
- Sostituisci:
Opzione di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze:
- Non eliminare mai i file: non eliminare mai i file dall'origine (opzione consigliata per i test).
- Elimina file trasferiti e directory vuote: elimina i file e le directory vuote dall'origine al termine di un recupero riuscito.
Età massima file: includi i file modificati nell'ultimo numero di giorni (il valore predefinito è 180 giorni)
Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset
Etichette di importazione: l'etichetta da applicare agli eventi di questo feed
Fai clic su Avanti.
Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.
Concedi le autorizzazioni IAM al account di servizio Google SecOps
Il account di servizio Google SecOps ha bisogno di due ruoli nel tuo bucket Cloud Storage: Visualizzatore oggetti Storage per leggere gli oggetti log e un ruolo a livello di bucket per leggere i metadati del bucket.
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (ad esempio
proofpoint-ser-logs). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: incolla l'email del account di servizio Google SecOps
- Assegna ruoli: seleziona entrambi i seguenti ruoli:
- Visualizzatore oggetti Storage: legge gli oggetti log.
- Storage Legacy Bucket Reader: legge i metadati del bucket. Se hai selezionato l'opzione di eliminazione Elimina file trasferiti e directory vuote, seleziona Storage Legacy Bucket Writer, che concede anche l'autorizzazione di eliminazione.
Fai clic su Salva.
Tabella di mappatura UDM
| Campo log | Mappatura UDM | Logica |
|---|---|---|
acceptedMessages_label |
additional.fields |
Unita |
acceptedThroughput_label |
additional.fields |
Unita |
average30DayThroughput_label |
additional.fields |
Unita |
average7DayThroughput_label |
additional.fields |
Unita |
averageDailyThroughput_label |
additional.fields |
Unita |
avgAcceptedMessageSize_label |
additional.fields |
Unita |
blockedMessages_label |
additional.fields |
Unita |
data_totalThroughput_label |
additional.fields |
Unita |
deliveredMessages_label |
additional.fields |
Unita |
licenseEndDate_label |
additional.fields |
Unita |
licenseStartDate_label |
additional.fields |
Unita |
map_label |
additional.fields |
Unita |
metadata_totalThroughput_label |
additional.fields |
Unita |
quarantinedMessages_label |
additional.fields |
Unita |
rejectedMessages_label |
additional.fields |
Unita |
remainingThroughput_label |
additional.fields |
Unita |
requestedMessages_label |
additional.fields |
Unita |
requestedThroughput_label |
additional.fields |
Unita |
sentMessages_label |
additional.fields |
Unita |
throughputForecast_label |
additional.fields |
Unita |
throughputLimit_label |
additional.fields |
Unita |
throughput_label |
additional.fields |
Unita |
totalMessages_label |
additional.fields |
Unita |
undeliveredMessages_label |
additional.fields |
Unita |
data.name |
metadata.description |
Mappato direttamente |
desc |
metadata.description |
Mappato direttamente |
data.date |
metadata.event_timestamp |
Analizzato come yyyy-MM-dd |
event_type |
metadata.event_type |
Mappato direttamente |
fromEnvelope |
network.email.bounce_address |
Mappato direttamente |
fromHeader |
network.email.from |
Mappato direttamente |
applicationName |
principal.administrative_domain |
Mappato direttamente |
principal_host |
principal.asset.hostname |
Mappato direttamente |
principal_host |
principal.hostname |
Mappato direttamente |
principal_port |
principal.port |
Mappato direttamente |
data.relayUserId |
principal.user.product_object_id |
Mappato direttamente |
userId |
principal.user.product_object_id |
Mappato direttamente |
applicationUserName |
principal.user.user_display_name |
Mappato direttamente |
senderName |
target.administrative_domain |
Mappato direttamente |
senderId |
target.user.product_object_id |
Mappato direttamente |
| N/D | metadata.product_name |
Costante: PROOFPOINT SER |
| N/D | metadata.vendor_name |
Costante: PROOFPOINT |
Log delle modifiche
Visualizza il log delle modifiche per questo parser
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.