GITHUB
Este documento explica como ingerir registros de auditoria do GitHub no Google Security Operations usando o Amazon S3. O analisador tenta extrair dados do campo "message" usando vários padrões grok, processando formatos JSON e não JSON. Com base no "process_type" extraído, ele aplica uma lógica de análise específica usando grok, kv e outros filtros para mapear os dados de registro brutos no esquema do Modelo de Dados Unificado (UDM).
Antes de começar
Verifique se você tem os pré-requisitos a seguir:
- Instância do Google SecOps.
- Acesso privilegiado ao locatário do GitHub Enterprise Cloud com permissões de proprietário da empresa.
- Acesso privilegiado à AWS (S3, IAM).
Coletar os pré-requisitos do GitHub Enterprise Cloud (acesso empresarial)
- Faça login no Admin Console do GitHub Enterprise Cloud.
- Acesse Configurações da empresa > Configurações > Registro de auditoria > Streaming de registros.
- Verifique se você tem permissões de proprietário da empresa para configurar o streaming de registro de auditoria.
- Copie e salve em um local seguro os seguintes detalhes:
- Nome do GitHub Enterprise
- Nomes de organizações na empresa
Configurar o bucket do Amazon S3 e o Identity and Access Management para o Google SecOps
- Crie um bucket do Amazon S3 seguindo este guia do usuário: Como criar um bucket
- Salve o Nome e a Região do bucket para referência futura (por exemplo,
github-audit-logs
). - Crie um usuário seguindo este guia do usuário: Como criar um usuário do IAM.
- Selecione o usuário criado.
- Selecione a guia Credenciais de segurança.
- Clique em Criar chave de acesso na seção Chaves de acesso.
- Selecione Serviço de terceiros como Caso de uso.
- Clique em Próxima.
- Opcional: adicione uma tag de descrição.
- Clique em Criar chave de acesso.
- Clique em Fazer o download do arquivo .CSV para salvar a chave de acesso e a chave de acesso secreta para referência futura.
- Clique em Concluído.
Configurar a política do IAM para o streaming do GitHub S3
- No console da AWS, acesse IAM > Políticas > Criar política > guia JSON.
- Copie e cole a política a seguir.
JSON da política (substitua
github-audit-logs
se você tiver inserido um nome de bucket diferente):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::github-audit-logs/*" } ] }
Clique em Próxima > Criar política.
Nomeie a política como
GitHubAuditStreamingPolicy
e clique em Criar política.Volte para o usuário do IAM criado anteriormente.
Selecione a guia Permissões.
Clique em Adicionar permissões > Anexar políticas diretamente.
Pesquise e selecione
GitHubAuditStreamingPolicy
.Clique em Próxima > Adicionar permissões.
Configurar o streaming registro de auditoria do GitHub Enterprise Cloud
- Faça login no GitHub Enterprise Cloud como proprietário da empresa.
- Clique na foto do perfil e em Configurações corporativas.
- Na barra lateral da conta corporativa, clique em Configurações > Registro de auditoria > Transmissão de registros.
- Selecione Configurar stream e clique em Amazon S3.
- Em Autenticação, clique em Chaves de acesso.
- Informe os seguintes detalhes de configuração:
- Região: selecione a região do bucket (por exemplo,
us-east-1
). - Bucket: digite o nome do bucket para onde você quer transmitir (por exemplo,
github-audit-logs
). - ID da chave de acesso: insira o ID da chave de acesso do usuário do IAM.
- Chave secreta: insira sua chave secreta do usuário do IAM.
- Região: selecione a região do bucket (por exemplo,
- Clique em Verificar endpoint para verificar se o GitHub pode se conectar e gravar no endpoint do Amazon S3.
- Depois de verificar o endpoint, clique em Salvar.
Criar um usuário e chaves do IAM somente leitura para o Google SecOps
- Acesse Console da AWS > IAM > Usuários > Adicionar usuários.
- Clique em Add users.
- Informe os seguintes detalhes de configuração:
- Usuário: insira
secops-reader
. - Tipo de acesso: selecione Chave de acesso – Acesso programático.
- Usuário: insira
- Clique em Criar usuário.
- Anexe a política de leitura mínima (personalizada): Usuários > secops-reader > Permissões > Adicionar permissões > Anexar políticas diretamente > Criar política.
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
.Clique em Criar política > pesquisar/selecionar > Próxima > Adicionar permissões.
Crie uma chave de acesso para
secops-reader
: Credenciais de segurança > Chaves de acesso > Criar chave de acesso > faça o download do.CSV
(cole esses valores no feed).
Configurar um feed no Google SecOps para ingerir registros do GitHub
- Acesse Configurações do SIEM > Feeds.
- Clique em + Adicionar novo feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
GitHub audit logs
). - Selecione Amazon S3 V2 como o Tipo de origem.
- Selecione GitHub como o Tipo de registro.
- Clique em Próxima.
- Especifique valores para os seguintes parâmetros de entrada:
- URI do S3:
s3://github-audit-logs/
- Opções de exclusão de fontes: selecione a opção de exclusão de acordo com sua preferência.
- Idade máxima do arquivo: inclui arquivos modificados no último número de dias. O padrão é de 180 dias.
- ID da chave de acesso: chave de acesso do usuário com acesso ao bucket do S3.
- Chave de acesso secreta: chave secreta do usuário com acesso ao bucket do S3.
- Namespace do recurso: o namespace do recurso.
- Rótulos de ingestão: o rótulo aplicado aos eventos deste feed.
- URI do S3:
- Clique em Próxima.
- Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Tabela de mapeamento da UDM
Campo de registro | Mapeamento do UDM | Lógica |
---|---|---|
actor |
principal.user.userid |
O valor é extraído do campo actor . |
actor_id |
principal.user.attribute.labels.value |
O valor é extraído do campo actor_id . |
actor_ip |
principal.ip |
O valor é extraído do campo actor_ip . |
actor_location.country_code |
principal.location.country_or_region |
O valor é extraído do campo actor_location.country_code . |
application_name |
target.application |
O valor é extraído do campo application_name . |
business |
target.user.company_name |
O valor é extraído do campo business . |
business_id |
target.resource.attribute.labels.value |
O valor é extraído do campo business_id . |
config.url |
target.url |
O valor é extraído do campo config.url . |
created_at |
metadata.event_timestamp |
O valor é convertido de milissegundos UNIX para um carimbo de data/hora. |
data.cancelled_at |
extensions.vulns.vulnerabilities.scan_end_time |
O valor é convertido do formato ISO8601 para um carimbo de data/hora. |
data.email |
target.email |
O valor é extraído do campo data.email . |
data.event |
security_result.about.labels.value |
O valor é extraído do campo data.event . |
data.events |
security_result.about.labels.value |
O valor é extraído do campo data.events . |
data.head_branch |
security_result.about.labels.value |
O valor é extraído do campo data.head_branch . |
data.head_sha |
target.file.sha256 |
O valor é extraído do campo data.head_sha . |
data.hook_id |
target.resource.attribute.labels.value |
O valor é extraído do campo data.hook_id . |
data.started_at |
extensions.vulns.vulnerabilities.scan_start_time |
O valor é convertido do formato ISO8601 para um carimbo de data/hora. |
data.team |
target.user.group_identifiers |
O valor é extraído do campo data.team . |
data.trigger_id |
security_result.about.labels.value |
O valor é extraído do campo data.trigger_id . |
data.workflow_id |
security_result.about.labels.value |
O valor é extraído do campo data.workflow_id . |
data.workflow_run_id |
security_result.about.labels.value |
O valor é extraído do campo data.workflow_run_id . |
enterprise.name |
additional.fields.value.string_value |
O valor é extraído do campo enterprise.name . |
external_identity_nameid |
target.user.email_addresses |
Se o valor for um endereço de e-mail, ele será adicionado à matriz target.user.email_addresses . |
external_identity_nameid |
target.user.userid |
O valor é extraído do campo external_identity_nameid . |
external_identity_username |
target.user.user_display_name |
O valor é extraído do campo external_identity_username . |
hashed_token |
network.session_id |
O valor é extraído do campo hashed_token . |
job_name |
target.resource.attribute.labels.value |
O valor é extraído do campo job_name . |
job_workflow_ref |
target.resource.attribute.labels.value |
O valor é extraído do campo job_workflow_ref . |
org |
target.administrative_domain |
O valor é extraído do campo org . |
org_id |
additional.fields.value.string_value |
O valor é extraído do campo org_id . |
programmatic_access_type |
additional.fields.value.string_value |
O valor é extraído do campo programmatic_access_type . |
public_repo |
additional.fields.value.string_value |
O valor é extraído do campo public_repo . |
public_repo |
target.location.name |
Se o valor for "false", ele será mapeado como "PRIVATE". Caso contrário, será mapeado como "PUBLIC". |
query_string |
additional.fields.value.string_value |
O valor é extraído do campo query_string . |
rate_limit_remaining |
additional.fields.value.string_value |
O valor é extraído do campo rate_limit_remaining . |
repo |
target.resource.name |
O valor é extraído do campo repo . |
repo_id |
additional.fields.value.string_value |
O valor é extraído do campo repo_id . |
repository_public |
additional.fields.value.string_value |
O valor é extraído do campo repository_public . |
request_body |
additional.fields.value.string_value |
O valor é extraído do campo request_body . |
request_method |
network.http.method |
O valor é convertido em letras maiúsculas. |
route |
additional.fields.value.string_value |
O valor é extraído do campo route . |
status_code |
network.http.response_code |
O valor é convertido em um número inteiro. |
timestamp |
metadata.event_timestamp |
O valor é convertido de milissegundos UNIX para um carimbo de data/hora. |
token_id |
additional.fields.value.string_value |
O valor é extraído do campo token_id . |
token_scopes |
additional.fields.value.string_value |
O valor é extraído do campo token_scopes . |
transport_protocol_name |
network.application_protocol |
O valor é convertido em letras maiúsculas. |
url_path |
target.url |
O valor é extraído do campo url_path . |
user |
target.user.user_display_name |
O valor é extraído do campo user . |
user_agent |
network.http.user_agent |
O valor é extraído do campo user_agent . |
user_agent |
network.http.parsed_user_agent |
O valor é analisado. |
user_id |
target.user.userid |
O valor é extraído do campo user_id . |
workflow.name |
security_result.about.labels.value |
O valor é extraído do campo workflow.name . |
workflow_run.actor.login |
principal.user.userid |
O valor é extraído do campo workflow_run.actor.login . |
workflow_run.event |
additional.fields.value.string_value |
O valor é extraído do campo workflow_run.event . |
workflow_run.head_branch |
security_result.about.labels.value |
O valor é extraído do campo workflow_run.head_branch . |
workflow_run.head_sha |
target.file.sha256 |
O valor é extraído do campo workflow_run.head_sha . |
workflow_run.id |
target.resource.attribute.labels.value |
O valor é extraído do campo workflow_run.id . |
workflow_run.workflow_id |
security_result.about.labels.value |
O valor é extraído do campo workflow_run.workflow_id . |
N/A | metadata.event_type |
O valor é determinado com base nos campos action e actor . Se o campo action contiver "_member", o valor será definido como "USER_RESOURCE_UPDATE_PERMISSIONS". Se os campos action e actor não estiverem vazios, o valor será definido como "USER_RESOURCE_UPDATE_CONTENT". Caso contrário, o valor será definido como "USER_RESOURCE_ACCESS". |
N/A | metadata.log_type |
O valor é definido como "GITHUB". |
N/A | metadata.product_name |
O valor é definido como "GITHUB". |
N/A | metadata.vendor_name |
O valor é definido como "GITHUB". |
N/A | target.resource.resource_type |
O valor é definido como "STORAGE_OBJECT". |
N/A | security_result.about.labels.key |
O valor é definido como uma string constante com base no campo data correspondente. Por exemplo, para data.workflow_id , a chave é definida como "ID do fluxo de trabalho". |
N/A | target.resource.attribute.labels.key |
O valor é definido como uma string constante com base no campo data correspondente. Por exemplo, para data.hook_id , a chave é definida como "ID do hook". |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.