Raccogliere i log di Atlassian Confluence
Questo documento spiega come importare i log di Atlassian Confluence in Google Security Operations. Il parser tenta innanzitutto di estrarre i campi dal messaggio di log non elaborato utilizzando espressioni regolari (pattern grok) progettate per i log di Atlassian Confluence. Se l'analisi grok non va a buon fine o il log è in formato JSON, il codice tenta di analizzare il messaggio come JSON. Infine, i campi estratti vengono mappati allo schema UDM di Google SecOps e arricchiti con un contesto aggiuntivo.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps
- Account Atlassian Confluence Cloud con accesso ai log di controllo OPPURE Confluence Data Center/Server con accesso amministrativo
- Per i metodi basati su AWS: accesso con privilegi ad AWS (S3, IAM, Lambda, EventBridge)
- Per il metodo Bindplane: host Windows 2016 o versioni successive o Linux con
systemd
Panoramica delle opzioni di integrazione
Questa guida fornisce due percorsi di integrazione:
- Opzione 1: Confluence Data Center/Server tramite BindPlane + Syslog
- Opzione 2: Audit log di Confluence Cloud tramite AWS Lambda + S3 (formato JSON)
Scegli l'opzione più adatta al tipo di deployment e all'infrastruttura di Confluence.
Opzione 1: Confluence Data Center/Server tramite Bindplane + Syslog
Questa opzione configura Confluence Data Center o Server per inviare i log tramite syslog a un agente Bindplane, che poi li inoltra a Google SecOps.
Recuperare il file di autenticazione importazione di Google SecOps
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Agenti di raccolta.
- Scarica il file di autenticazione importazione. Salva il file in modo sicuro sul sistema in cui verrà installato Bindplane.
Recuperare l'ID cliente Google SecOps
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Profilo.
- Copia e salva l'ID cliente dalla sezione Dettagli dell'organizzazione.
Installa l'agente Bindplane
Installa l'agente Bindplane sul sistema operativo Windows o Linux seguendo le istruzioni riportate di seguito.
Installazione di Windows
- Apri il prompt dei comandi o PowerShell come amministratore.
Esegui questo comando:
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
Installazione di Linux
- Apri un terminale con privilegi root o sudo.
Esegui questo comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Risorse aggiuntive per l'installazione
- Per ulteriori opzioni di installazione, consulta questa guida all'installazione.
Configura l'agente Bindplane per importare Syslog e inviarlo a Google SecOps
Accedi al file di configurazione:
- Individua il file
config.yaml. In genere si trova nella directory/etc/bindplane-agent/su Linux o nella directory di installazione su Windows. - Apri il file utilizzando un editor di testo (ad esempio
nano,vio Blocco note).
- Individua il file
Modifica il file
config.yamlcome segue:receivers: udplog: # Replace the port and IP address as required listen_address: "0.0.0.0:514" exporters: chronicle/chronicle_w_labels: compression: gzip # Adjust the path to the credentials file you downloaded creds_file_path: '/path/to/ingestion-authentication-file.json' # Replace with your actual customer ID customer_id: YOUR_CUSTOMER_ID endpoint: malachiteingestion-pa.googleapis.com log_type: 'ATLASSIAN_CONFLUENCE' raw_log_field: body ingestion_labels: service: pipelines: logs/confluence: receivers: - udplog exporters: - chronicle/chronicle_w_labels- Sostituisci la porta e l'indirizzo IP in base alle esigenze della tua infrastruttura.
- Sostituisci
<YOUR_CUSTOMER_ID_HERE>con l'ID cliente effettivo. - Aggiorna
/path/to/ingestion-authentication-file.jsonal percorso in cui è stato salvato il file di autenticazione nella sezione Recupera il file di autenticazione per l'importazione di Google SecOps.
Riavvia l'agente Bindplane per applicare le modifiche
Per riavviare l'agente Bindplane in Linux, esegui questo comando:
sudo systemctl restart bindplane-agentPer riavviare l'agente Bindplane in Windows, puoi utilizzare la console Servizi o inserire il seguente comando:
net stop BindPlaneAgent && net start BindPlaneAgent
Configurare l'inoltro di Syslog su Confluence Data Center/Server
Opzione A: configura Log4j SyslogAppender (consigliata)
- Accedi al tuo server Confluence tramite SSH o RDP.
- Individua il file di configurazione Log4j:
- Per Log4j2:
<confluence-install>/confluence/WEB-INF/classes/log4j2.xml
- Per Log4j2:
Modifica il file di configurazione per aggiungere un SyslogAppender:
<Configuration> <Appenders> <!-- Existing appenders --> <Syslog name="SyslogAppender" host="BINDPLANE_AGENT_IP" port="514" protocol="UDP" facility="LOCAL0" format="RFC5424"> <PatternLayout pattern="%d{ISO8601} %p [%t] [%c{1}] %m%n"/> </Syslog> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="SyslogAppender"/> <!-- Other appender refs --> </Root> <!-- Audit logger --> <Logger name="com.atlassian.confluence.event.events.security.AuditEvent" level="info" additivity="false"> <AppenderRef ref="SyslogAppender"/> </Logger> </Loggers> </Configuration>- Sostituisci
BINDPLANE_AGENT_IPcon l'indirizzo IP dell'agente BindPlane.
- Sostituisci
Riavvia Confluence per applicare le modifiche:
sudo systemctl restart confluence
Opzione B: configura rsyslog per inoltrare i file di log locali
- Configura Confluence per scrivere i log nei file (comportamento predefinito).
Installa rsyslog se non è presente:
sudo apt-get install rsyslog # Debian/Ubuntu sudo yum install rsyslog # RHEL/CentOSCrea il file di configurazione rsyslog
/etc/rsyslog.d/confluence.conf:# Forward Confluence logs to BindPlane $ModLoad imfile # Application logs $InputFileName /opt/atlassian/confluence/logs/atlassian-confluence.log $InputFileTag confluence-app: $InputFileStateFile stat-confluence-app $InputFileSeverity info $InputFileFacility local0 $InputRunFileMonitor # Audit logs (JSON format in DC/Server) $InputFileName /var/atlassian/application-data/confluence/log/audit/*.json $InputFileTag confluence-audit: $InputFileStateFile stat-confluence-audit $InputFileSeverity info $InputFileFacility local1 $InputRunFileMonitor # Forward to BindPlane agent *.* @@BINDPLANE_AGENT_IP:514- Sostituisci
BINDPLANE_AGENT_IPcon l'indirizzo IP dell'agente Bindplane. - Modifica i percorsi dei file di log in base all'installazione di Confluence:
- I log delle applicazioni in genere:
<confluence-install>/logs/o<local-home>/logs/ - Log di controllo:
<confluence-home>/log/audit/*.json
- I log delle applicazioni in genere:
- Sostituisci
Riavvia rsyslog:
sudo systemctl restart rsyslog
Opzione 2: log di controllo di Confluence Cloud tramite AWS Lambda + S3
Raccogli le credenziali API Confluence Cloud
- Accedi al tuo account Atlassian.
- Vai alla pagina https://id.atlassian.com/manage-profile/security/api-tokens.
- Fai clic su Genera token API.
- Inserisci un'etichetta per il token (ad esempio,
Google Security Operations Integration). - Fai clic su Crea.
- Copia e salva il token API in modo sicuro.
- Prendi nota dell'URL del tuo sito Confluence Cloud (ad esempio,
https://yoursite.atlassian.net). - Prendi nota dell'indirizzo email del tuo account Atlassian (utilizzato per l'autenticazione).
Configura il bucket AWS S3 e IAM per Google SecOps
- Crea un bucket Amazon S3 seguendo questa guida utente: Creazione di un bucket
- Salva il nome e la regione del bucket per riferimento futuro (ad esempio,
confluence-audit-logs). - Crea un utente seguendo questa guida utente: Creazione di un utente IAM.
- Seleziona l'utente creato.
- Seleziona la scheda Credenziali di sicurezza.
- Fai clic su Crea chiave di accesso nella sezione Chiavi di accesso.
- Seleziona Servizio di terze parti come Caso d'uso.
- Fai clic su Avanti.
- (Facoltativo) Aggiungi un tag di descrizione.
- Fai clic su Crea chiave di accesso.
- Fai clic su Scarica file CSV per salvare la chiave di accesso e la chiave di accesso segreta per riferimento futuro.
- Fai clic su Fine.
- Seleziona la scheda Autorizzazioni.
- Fai clic su Aggiungi autorizzazioni nella sezione Norme relative alle autorizzazioni.
- Seleziona Aggiungi autorizzazioni.
- Seleziona Collega direttamente i criteri.
- Cerca i criteri AmazonS3FullAccess.
- Seleziona la policy.
- Fai clic su Avanti.
- Fai clic su Aggiungi autorizzazioni.
Configura il ruolo e il criterio IAM per i caricamenti S3
- Nella console AWS, vai a IAM > Policy > Crea policy > scheda JSON.
Inserisci la seguente policy:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::confluence-audit-logs/*" }, { "Sid": "AllowGetStateObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::confluence-audit-logs/confluence-audit/state.json" } ] }- Sostituisci
confluence-audit-logsse hai inserito un nome bucket diverso.
- Sostituisci
Fai clic su Avanti > Crea policy.
Assegna al criterio il nome
ConfluenceAuditToS3Policy.Vai a IAM > Ruoli > Crea ruolo > Servizio AWS > Lambda.
Allega il criterio appena creato
ConfluenceAuditToS3Policy.Assegna al ruolo il nome
ConfluenceAuditLambdaRolee fai clic su Crea ruolo.
Crea la funzione Lambda
- Nella console AWS, vai a Lambda > Funzioni.
- Fai clic su Crea funzione > Crea da zero.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Nome ConfluenceAuditToS3Tempo di esecuzione Python 3.13 Architettura x86_64 Ruolo di esecuzione ConfluenceAuditLambdaRoleDopo aver creato la funzione, apri la scheda Codice, elimina lo stub e inserisci il seguente codice:
import json import os import boto3 from datetime import datetime, timezone, timedelta from urllib import request, parse, error from base64 import b64encode # Environment variables S3_BUCKET = os.environ['S3_BUCKET'] S3_PREFIX = os.environ.get('S3_PREFIX', 'confluence-audit/') STATE_KEY = os.environ.get('STATE_KEY', 'confluence-audit/state.json') CONFLUENCE_URL = os.environ['CONFLUENCE_URL'] # e.g., https://yoursite.atlassian.net CONFLUENCE_EMAIL = os.environ['CONFLUENCE_EMAIL'] CONFLUENCE_API_TOKEN = os.environ['CONFLUENCE_API_TOKEN'] MAX_RECORDS = int(os.environ.get('MAX_RECORDS', '1000')) s3_client = boto3.client('s3') def lambda_handler(event, context): """Fetch Confluence Cloud audit logs and write to S3.""" # Read last execution state start_date = get_last_execution_time() end_date = datetime.now(timezone.utc) print(f"Fetching audit logs from {start_date} to {end_date}") # Fetch audit records records = fetch_audit_logs(start_date, end_date) if not records: print("No new audit records found.") save_state(end_date) return {'statusCode': 200, 'body': 'No new records'} # Write to S3 timestamp = end_date.strftime('%Y%m%d_%H%M%S') object_key = f"{S3_PREFIX}audit_{timestamp}.json" s3_client.put_object( Bucket=S3_BUCKET, Key=object_key, Body='\n'.join(json.dumps(record) for record in records), ContentType='application/json' ) print(f"Wrote {len(records)} records to s3://{S3_BUCKET}/{object_key}") # Update state save_state(end_date) return { 'statusCode': 200, 'body': f"Processed {len(records)} records" } def get_last_execution_time(): """Retrieve the last execution timestamp from S3 state file.""" try: response = s3_client.get_object(Bucket=S3_BUCKET, Key=STATE_KEY) state = json.loads(response['Body'].read()) return datetime.fromisoformat(state['last_execution']) except s3_client.exceptions.NoSuchKey: # First run: fetch logs from last 24 hours return datetime.now(timezone.utc) - timedelta(hours=24) except Exception as e: print(f"Error reading state: {e}") return datetime.now(timezone.utc) - timedelta(hours=24) def save_state(execution_time): """Save the execution timestamp to S3 state file.""" state = {'last_execution': execution_time.isoformat()} s3_client.put_object( Bucket=S3_BUCKET, Key=STATE_KEY, Body=json.dumps(state), ContentType='application/json' ) def fetch_audit_logs(start_date, end_date): """Fetch audit logs from Confluence Cloud REST API.""" records = [] start_param = int(start_date.timestamp() * 1000) # milliseconds end_param = int(end_date.timestamp() * 1000) # Build authentication header auth_string = f"{CONFLUENCE_EMAIL}:{CONFLUENCE_API_TOKEN}" auth_bytes = auth_string.encode('ascii') auth_b64 = b64encode(auth_bytes).decode('ascii') headers = { 'Authorization': f'Basic {auth_b64}', 'Accept': 'application/json' } # Confluence Cloud Audit API endpoint url = f"{CONFLUENCE_URL}/wiki/rest/api/audit?startDate={start_param}&endDate={end_param}&limit=1000" try: req = request.Request(url, headers=headers) with request.urlopen(req) as response: data = json.loads(response.read()) records = data.get('results', []) print(f"Retrieved {len(records)} audit records") except error.HTTPError as e: print(f"HTTP Error: {e.code} - {e.reason}") print(e.read().decode()) except Exception as e: print(f"Error fetching audit logs: {e}") return records[:MAX_RECORDS]Vai a Configurazione > Variabili di ambiente.
Fai clic su Modifica > Aggiungi nuova variabile di ambiente.
Inserisci le seguenti variabili di ambiente, sostituendole con i tuoi valori.
Chiave Valore di esempio S3_BUCKETconfluence-audit-logsS3_PREFIXconfluence-audit/STATE_KEYconfluence-audit/state.jsonCONFLUENCE_URLhttps://yoursite.atlassian.netCONFLUENCE_EMAILyour-email@example.comCONFLUENCE_API_TOKENyour-api-token-hereMAX_RECORDS1000Seleziona la scheda Configurazione.
Nel riquadro Configurazione generale, fai clic su Modifica.
Modifica Timeout in 5 minuti (300 secondi) e fai clic su Salva.
Creare una pianificazione EventBridge
- Vai a Amazon EventBridge > Scheduler > Crea pianificazione.
- Fornisci i seguenti dettagli di configurazione:
- Programma ricorrente: Tariffa (
1 hour). - Target: la tua funzione Lambda
ConfluenceAuditToS3. - Nome:
ConfluenceAuditToS3-1h
- Programma ricorrente: Tariffa (
- Fai clic su Crea pianificazione.
(Facoltativo) Crea chiavi e utente IAM di sola lettura per Google SecOps
- Vai alla console AWS > IAM > Utenti.
- Fai clic su Add users (Aggiungi utenti).
- Fornisci i seguenti dettagli di configurazione:
- Utente: inserisci
secops-confluence-reader. - Tipo di accesso: seleziona Chiave di accesso - Accesso programmatico.
- Utente: inserisci
- Fai clic su Avanti.
- Fai clic su Collega policy direttamente > Crea policy.
Nell'editor JSON, inserisci la seguente policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::confluence-audit-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::confluence-audit-logs" } ] }Imposta il nome su
secops-reader-policy.Vai a Crea criterio > cerca/seleziona > Avanti > Aggiungi autorizzazioni.
Vai a Credenziali di sicurezza > Chiavi di accesso > Crea chiave di accesso.
Scarica il file CSV (questi valori vengono inseriti nel feed).
Configura un feed in Google SecOps per importare i log di Confluence
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio,
Confluence Cloud Audit Logs). - Seleziona Amazon S3 V2 come Tipo di origine.
- Seleziona Atlassian Confluence come Tipo di log.
- Fai clic su Avanti.
- Specifica i valori per i seguenti parametri di input:
- URI S3:
s3://confluence-audit-logs/confluence-audit/ - Opzioni di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze.
- Età massima del file: includi i file modificati nell'ultimo numero di giorni. Il valore predefinito è 180 giorni.
- ID chiave di accesso: chiave di accesso utente con accesso al bucket S3.
- Chiave di accesso segreta: chiave segreta dell'utente con accesso al bucket S3.
- Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset.
- Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
- URI S3:
- Fai clic su Avanti.
- Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.
Tabella di mappatura UDM
| Campo log | Mappatura UDM | Logic |
|---|---|---|
| agente | read_only_udm.network.http.user_agent | Valore tratto dal campo "agente". |
| app_protocol | read_only_udm.network.application_protocol | Derivato dal campo "app_protocol". Se "app_protocol" contiene "HTTPS", "HTTP", "SSH" o "RDP", viene utilizzato il protocollo corrispondente. In caso contrario, il valore predefinito è "UNKNOWN_APPLICATION_PROTOCOL". |
| app_protocol | read_only_udm.network.application_protocol_version | Valore estratto dal campo "app_protocol". |
| auditType.action | read_only_udm.security_result.action | Derivato dal campo "auditType.action". Se "auditType.action" contiene "successful", il valore è impostato su "ALLOW". Se contiene "restricted", il valore è impostato su "BLOCK". |
| auditType.action | read_only_udm.security_result.summary | Valore estratto dal campo "auditType.action" quando "auditType" non è vuoto e "auditType_area" è "SECURITY". |
| auditType.actionI18nKey | read_only_udm.metadata.product_event_type | Valore estratto dal campo "auditType.actionI18nKey" quando "auditType" non è vuoto. |
| auditType.area | read_only_udm.security_result.detection_fields.value | Valore estratto dal campo "auditType.area" e assegnato al campo "value" di un campo di rilevamento con il campo "key" impostato su "auditType area". Questa mappatura viene eseguita quando "auditType" non è vuoto. |
| auditType.category | read_only_udm.security_result.category_details | Valore estratto dal campo "auditType.category" quando "auditType" non è vuoto. |
| auditType.categoryI18nKey | read_only_udm.security_result.detection_fields.value | Valore estratto dal campo "auditType.categoryI18nKey" e assegnato al campo "value" di un campo di rilevamento con il campo "key" impostato su "auditType categoryI18nKey". Questa mappatura viene eseguita quando "auditType" non è vuoto. |
| auditType.level | read_only_udm.security_result.detection_fields.value | Valore estratto dal campo "auditType.level" e assegnato al campo "value" di un campo di rilevamento con il campo "key" impostato su "auditType level". Questa mappatura viene eseguita quando "auditType" non è vuoto. |
| author.displayName | read_only_udm.principal.user.user_display_name | Valore tratto dal campo "author.displayName". |
| author.externalCollaborator | read_only_udm.security_result.about.resource.attribute.labels.value | Valore estratto dal campo "author.externalCollaborator" e assegnato al campo "value" di un'etichetta con il campo "key" impostato su "externalCollaborator". |
| author.id | read_only_udm.principal.user.userid | Valore estratto dal campo "author.id" quando "author.type" è "user" e "principal_user_present" è "false". |
| author.isExternalCollaborator | read_only_udm.security_result.about.resource.attribute.labels.value | Valore estratto dal campo "author.isExternalCollaborator" e assegnato al campo "value" di un'etichetta con il campo "key" impostato su "isExternalCollaborator". |
| author.name | read_only_udm.principal.user.user_display_name | Valore tratto dal campo "author.name" quando "author.type" è "user" e "principal_user_present" è "false". |
| bytes_in | read_only_udm.network.received_bytes | Valore estratto dal campo "bytes_in" se contiene cifre. In caso contrario, il valore predefinito è 0. |
| categoria | read_only_udm.security_result.category_details | Valore tratto dal campo "categoria". |
| changedValues | read_only_udm.principal.resource.attribute.labels | Itera ogni elemento di "changedValues" e crea etichette con chiavi come "changedValue[index][key]" e valori corrispondenti nell'array "changedValues". |
| creationDate | read_only_udm.metadata.event_timestamp | Valore estratto dal campo "creationDate", analizzato come timestamp UNIX o UNIX_MS. |
| extraAttributes | read_only_udm.principal.resource.attribute.labels | Itera ogni elemento in "extraAttributes" e crea etichette con chiavi basate sui campi "name" e "nameI18nKey" e sui valori del campo "value" corrispondente. |
| http_verb | read_only_udm.network.http.method | Valore estratto dal campo "http_verb". |
| ip | read_only_udm.target.ip | Valore tratto dal campo "ip". |
| principal_host | read_only_udm.principal.hostname | Valore estratto dal campo "principal_host". |
| referral_url | read_only_udm.network.http.referral_url | Valore tratto dal campo "referral_url". |
| remoteAddress | read_only_udm.principal.ip | Valore estratto dal campo "remoteAddress", analizzato come indirizzo IP. |
| response_code | read_only_udm.network.http.response_code | Valore estratto dal campo "response_code". |
| session_duration | read_only_udm.additional.fields.value.string_value | Valore estratto dal campo "session_duration" e assegnato al campo "string_value" di un'etichetta con il campo "key" impostato su "Session Duration" (Durata sessione). |
| origine | read_only_udm.principal.ip | Valore estratto dal campo "origine", analizzato come indirizzo IP. |
| src_ip | read_only_udm.principal.ip | Valore tratto dal campo "src_ip" se "remoteAddress" è vuoto. |
| riepilogo | read_only_udm.security_result.summary | Valore tratto dal campo "Riepilogo". |
| sysAdmin | read_only_udm.security_result.about.resource.attribute.labels.value | Valore estratto dal campo "sysAdmin" e assegnato al campo "value" di un'etichetta con il campo "key" impostato su "sysAdmin". |
| superAdmin | read_only_udm.security_result.about.resource.attribute.labels.value | Valore tratto dal campo "superAdmin" e assegnato al campo "value" di un'etichetta con il campo "key" impostato su "superAdmin". |
| target_url | read_only_udm.target.url | Valore tratto dal campo "target_url". |
| timestamp | read_only_udm.metadata.event_timestamp | Valore estratto dal campo "timestamp", analizzato come stringa di data e ora. |
| user_id | read_only_udm.principal.user.userid | Valore tratto dal campo "user_id". |
| read_only_udm.metadata.event_type | Il valore di questo campo è determinato da una serie di controlli e il valore predefinito è "GENERIC_EVENT". È impostato su valori specifici come "NETWORK_HTTP", "USER_UNCATEGORIZED" o "STATUS_UPDATE" in base alla presenza e al contenuto di altri campi come "principal_host", "user_id", "has_principal" e "author.type". | |
| read_only_udm.metadata.vendor_name | Imposta il valore su "ATLASSIAN". | |
| read_only_udm.metadata.product_name | Imposta su "CONFLUENCE". | |
| read_only_udm.metadata.log_type | Imposta il valore su "ATLASSIAN_CONFLUENCE". | |
| read_only_udm.principal.user.user_display_name | Il valore di questo campo può provenire da "author.displayName" o "affectedObject.name" a seconda del contesto. | |
| read_only_udm.target.process.pid | Il valore di questo campo può provenire da "principal_host" o "pid" a seconda del contesto. | |
| read_only_udm.principal.resource.attribute.labels | Questo campo viene compilato con varie etichette derivate da campi come "affectedObjects", "changedValues" e "extraAttributes". Le chiavi e i valori di queste etichette vengono generati dinamicamente in base al contenuto specifico di questi campi. |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.