GITHUB
Questo documento spiega come importare gli audit log di GitHub in Google Security Operations utilizzando Amazon S3. Il parser tenta di estrarre i dati dal campo "message" utilizzando vari pattern grok, gestendo sia i formati JSON che non JSON. In base al "process_type" estratto, applica una logica di analisi specifica utilizzando grok, kv e altri filtri per mappare i dati di log non elaborati nello schema Unified Data Model (UDM).
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Istanza Google SecOps.
- Accesso privilegiato al tenant GitHub Enterprise Cloud con autorizzazioni di proprietario dell'organizzazione.
- Accesso con privilegi ad AWS (S3, IAM).
Raccogli i prerequisiti di GitHub Enterprise Cloud (accesso Enterprise)
- Accedi alla Console di amministrazione di GitHub Enterprise Cloud.
- Vai a Impostazioni aziendali > Impostazioni > Log di controllo > Streaming dei log.
- Assicurati di disporre delle autorizzazioni di proprietario dell'azienda per configurare lo streaming degli audit log.
- Copia e salva in una posizione sicura i seguenti dettagli:
- Nome di GitHub Enterprise
- Nomi delle organizzazioni nell'impresa
Configura il bucket AWS S3 e Identity and Access Management 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,
github-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.
Configura il criterio IAM per lo streaming S3 di GitHub
- Nella console AWS, vai a IAM > Policy > Crea policy > Scheda JSON.
- Copia e incolla i seguenti criteri.
JSON delle policy (sostituisci
github-audit-logs
se hai inserito un nome del bucket diverso):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::github-audit-logs/*" } ] }
Fai clic su Avanti > Crea policy.
Assegna un nome alla policy
GitHubAuditStreamingPolicy
e fai clic su Crea policy.Torna all'utente IAM creato in precedenza.
Seleziona la scheda Autorizzazioni.
Fai clic su Aggiungi autorizzazioni > Allega norme direttamente.
Cerca e seleziona
GitHubAuditStreamingPolicy
.Fai clic su Avanti > Aggiungi autorizzazioni.
Configura lo streaming dei log di controllo di GitHub Enterprise Cloud
- Accedi a GitHub Enterprise Cloud come proprietario dell'organizzazione.
- Fai clic sulla tua foto del profilo, poi su Impostazioni Enterprise.
- Nella barra laterale dell'account aziendale, fai clic su Impostazioni > Log di controllo > Streaming dei log.
- Seleziona Configura stream e fai clic su Amazon S3.
- In Autenticazione, fai clic su Chiavi di accesso.
- Fornisci i seguenti dettagli di configurazione:
- Regione: seleziona la regione del bucket (ad esempio
us-east-1
). - Bucket: digita il nome del bucket in cui vuoi eseguire lo streaming (ad esempio
github-audit-logs
). - ID chiave di accesso: inserisci l'ID chiave di accesso dell'utente IAM.
- Secret Key (Chiave segreta): inserisci la chiave segreta dell'utente IAM.
- Regione: seleziona la regione del bucket (ad esempio
- Fai clic su Controlla endpoint per verificare che GitHub possa connettersi e scrivere nell'endpoint Amazon S3.
- Dopo aver verificato correttamente l'endpoint, fai clic su Salva.
Crea un utente IAM con autorizzazione di sola lettura e chiavi per Google SecOps
- Vai alla console AWS > IAM > Utenti > Aggiungi utenti.
- Fai clic su Add users (Aggiungi utenti).
- Fornisci i seguenti dettagli di configurazione:
- Utente: inserisci
secops-reader
. - Tipo di accesso: seleziona Chiave di accesso - Accesso programmatico.
- Utente: inserisci
- Fai clic su Crea utente.
- Allega la criterio per la lettura minima (personalizzata): Utenti > secops-reader > Autorizzazioni > Aggiungi autorizzazioni > Allega norme direttamente > Crea norma.
JSON:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::github-audit-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::github-audit-logs" } ] }
Name =
secops-reader-policy
.Fai clic su Crea criterio > cerca/seleziona > Avanti > Aggiungi autorizzazioni.
Crea una chiave di accesso per
secops-reader
: Credenziali di sicurezza > Chiavi di accesso > Crea chiave di accesso > scarica.CSV
(incollerai questi valori nel feed).
Configura un feed in Google SecOps per importare i log di GitHub
- Vai a Impostazioni SIEM > Feed.
- Fai clic su + Aggiungi nuovo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio,
GitHub audit logs
). - Seleziona Amazon S3 V2 come Tipo di origine.
- Seleziona GitHub come Tipo di log.
- Fai clic su Avanti.
- Specifica i valori per i seguenti parametri di input:
- URI S3:
s3://github-audit-logs/
- 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 |
---|---|---|
actor |
principal.user.userid |
Il valore viene estratto dal campo actor . |
actor_id |
principal.user.attribute.labels.value |
Il valore viene estratto dal campo actor_id . |
actor_ip |
principal.ip |
Il valore viene estratto dal campo actor_ip . |
actor_location.country_code |
principal.location.country_or_region |
Il valore viene estratto dal campo actor_location.country_code . |
application_name |
target.application |
Il valore viene estratto dal campo application_name . |
business |
target.user.company_name |
Il valore viene estratto dal campo business . |
business_id |
target.resource.attribute.labels.value |
Il valore viene estratto dal campo business_id . |
config.url |
target.url |
Il valore viene estratto dal campo config.url . |
created_at |
metadata.event_timestamp |
Il valore viene convertito da millisecondi UNIX a un timestamp. |
data.cancelled_at |
extensions.vulns.vulnerabilities.scan_end_time |
Il valore viene convertito dal formato ISO8601 a un timestamp. |
data.email |
target.email |
Il valore viene estratto dal campo data.email . |
data.event |
security_result.about.labels.value |
Il valore viene estratto dal campo data.event . |
data.events |
security_result.about.labels.value |
Il valore viene estratto dal campo data.events . |
data.head_branch |
security_result.about.labels.value |
Il valore viene estratto dal campo data.head_branch . |
data.head_sha |
target.file.sha256 |
Il valore viene estratto dal campo data.head_sha . |
data.hook_id |
target.resource.attribute.labels.value |
Il valore viene estratto dal campo data.hook_id . |
data.started_at |
extensions.vulns.vulnerabilities.scan_start_time |
Il valore viene convertito dal formato ISO8601 a un timestamp. |
data.team |
target.user.group_identifiers |
Il valore viene estratto dal campo data.team . |
data.trigger_id |
security_result.about.labels.value |
Il valore viene estratto dal campo data.trigger_id . |
data.workflow_id |
security_result.about.labels.value |
Il valore viene estratto dal campo data.workflow_id . |
data.workflow_run_id |
security_result.about.labels.value |
Il valore viene estratto dal campo data.workflow_run_id . |
enterprise.name |
additional.fields.value.string_value |
Il valore viene estratto dal campo enterprise.name . |
external_identity_nameid |
target.user.email_addresses |
Se il valore è un indirizzo email, viene aggiunto all'array target.user.email_addresses . |
external_identity_nameid |
target.user.userid |
Il valore viene estratto dal campo external_identity_nameid . |
external_identity_username |
target.user.user_display_name |
Il valore viene estratto dal campo external_identity_username . |
hashed_token |
network.session_id |
Il valore viene estratto dal campo hashed_token . |
job_name |
target.resource.attribute.labels.value |
Il valore viene estratto dal campo job_name . |
job_workflow_ref |
target.resource.attribute.labels.value |
Il valore viene estratto dal campo job_workflow_ref . |
org |
target.administrative_domain |
Il valore viene estratto dal campo org . |
org_id |
additional.fields.value.string_value |
Il valore viene estratto dal campo org_id . |
programmatic_access_type |
additional.fields.value.string_value |
Il valore viene estratto dal campo programmatic_access_type . |
public_repo |
additional.fields.value.string_value |
Il valore viene estratto dal campo public_repo . |
public_repo |
target.location.name |
Se il valore è "false", viene mappato su "PRIVATE". In caso contrario, viene mappato su "PUBLIC". |
query_string |
additional.fields.value.string_value |
Il valore viene estratto dal campo query_string . |
rate_limit_remaining |
additional.fields.value.string_value |
Il valore viene estratto dal campo rate_limit_remaining . |
repo |
target.resource.name |
Il valore viene estratto dal campo repo . |
repo_id |
additional.fields.value.string_value |
Il valore viene estratto dal campo repo_id . |
repository_public |
additional.fields.value.string_value |
Il valore viene estratto dal campo repository_public . |
request_body |
additional.fields.value.string_value |
Il valore viene estratto dal campo request_body . |
request_method |
network.http.method |
Il valore viene convertito in maiuscolo. |
route |
additional.fields.value.string_value |
Il valore viene estratto dal campo route . |
status_code |
network.http.response_code |
Il valore viene convertito in un numero intero. |
timestamp |
metadata.event_timestamp |
Il valore viene convertito da millisecondi UNIX a un timestamp. |
token_id |
additional.fields.value.string_value |
Il valore viene estratto dal campo token_id . |
token_scopes |
additional.fields.value.string_value |
Il valore viene estratto dal campo token_scopes . |
transport_protocol_name |
network.application_protocol |
Il valore viene convertito in maiuscolo. |
url_path |
target.url |
Il valore viene estratto dal campo url_path . |
user |
target.user.user_display_name |
Il valore viene estratto dal campo user . |
user_agent |
network.http.user_agent |
Il valore viene estratto dal campo user_agent . |
user_agent |
network.http.parsed_user_agent |
Il valore viene analizzato. |
user_id |
target.user.userid |
Il valore viene estratto dal campo user_id . |
workflow.name |
security_result.about.labels.value |
Il valore viene estratto dal campo workflow.name . |
workflow_run.actor.login |
principal.user.userid |
Il valore viene estratto dal campo workflow_run.actor.login . |
workflow_run.event |
additional.fields.value.string_value |
Il valore viene estratto dal campo workflow_run.event . |
workflow_run.head_branch |
security_result.about.labels.value |
Il valore viene estratto dal campo workflow_run.head_branch . |
workflow_run.head_sha |
target.file.sha256 |
Il valore viene estratto dal campo workflow_run.head_sha . |
workflow_run.id |
target.resource.attribute.labels.value |
Il valore viene estratto dal campo workflow_run.id . |
workflow_run.workflow_id |
security_result.about.labels.value |
Il valore viene estratto dal campo workflow_run.workflow_id . |
N/D | metadata.event_type |
Il valore viene determinato in base ai campi action e actor . Se il campo action contiene "_member", il valore è impostato su "USER_RESOURCE_UPDATE_PERMISSIONS". Se il campo action non è vuoto e il campo actor non è vuoto, il valore è impostato su "USER_RESOURCE_UPDATE_CONTENT". In caso contrario, il valore viene impostato su "USER_RESOURCE_ACCESS". |
N/D | metadata.log_type |
Il valore è impostato su "GITHUB". |
N/D | metadata.product_name |
Il valore è impostato su "GITHUB". |
N/D | metadata.vendor_name |
Il valore è impostato su "GITHUB". |
N/D | target.resource.resource_type |
Il valore è impostato su "STORAGE_OBJECT". |
N/D | security_result.about.labels.key |
Il valore viene impostato su una stringa costante in base al campo data corrispondente. Ad esempio, per data.workflow_id , la chiave è impostata su "ID flusso di lavoro". |
N/D | target.resource.attribute.labels.key |
Il valore viene impostato su una stringa costante in base al campo data corrispondente. Ad esempio, per data.hook_id , la chiave è impostata su "ID hook". |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.