Coletar registros do Google App Engine
Versão do analisador:3.0
Este documento explica como ingerir registros do Google App Engine no Google Security Operations usando o Google Cloud Storage V2.
O Google App Engine é uma plataforma sem servidor totalmente gerenciada para criar e implantar aplicativos da Web e APIs. O App Engine gera automaticamente registros de solicitação para solicitações HTTP e registros de aplicativo do seu código. Esses registros são enviados ao Cloud Logging e podem ser exportados para o Cloud Storage para ingestão no Google Security Operations.
Antes de começar
Verifique se você atende os seguintes pré-requisitos:
- Uma instância do Google SecOps
- Um projeto do GCP com a API Cloud Storage ativada
- Permissões para criar e gerenciar buckets do GCS
- Permissões para gerenciar políticas do IAM em buckets do GCS
- Permissões para criar coletores de registros do Cloud Logging (roles/logging.configWriter)
- Um aplicativo ativo do App Engine (ambiente padrão ou flexível)
Criar um bucket do Google Cloud Storage
- Acesse o Console do Google Cloud.
- Selecione seu projeto ou crie um novo.
- No menu de navegação, acesse Cloud Storage > Buckets.
- Clique em Criar bucket.
Informe os seguintes detalhes de configuração:
Configuração Valor Nomeie seu bucket Insira um nome globalmente exclusivo (por exemplo, appengine-logs-export)Tipo de local Escolha de acordo com suas necessidades (região, birregional, multirregional) Local Selecione o local (por exemplo, us-central1).Classe de armazenamento Padrão (recomendado para registros acessados com frequência) Controle de acesso Uniforme (recomendado) Ferramentas de proteção Opcional: ativar o controle de versões de objetos ou a política de retenção Clique em Criar.
Configurar o Cloud Logging para exportar registros do App Engine para o GCS
O Cloud Logging usa coletores de registros para rotear entradas de registro para destinos compatíveis, incluindo buckets do Cloud Storage. A identidade gravadora do gravador exige o papel Criador de objetos do Storage (roles/storage.objectCreator) no bucket de destino.
Criar um coletor de registros do Cloud Logging
- No console do Google Cloud, acesse Geração de registros > Roteador de registros.
- Clique em Criar coletor.
- Informe os seguintes detalhes de configuração:
- Nome do coletor: insira um nome descritivo (por exemplo,
appengine-to-gcs). - Descrição do coletor: descrição opcional.
- Nome do coletor: insira um nome descritivo (por exemplo,
- Clique em Próxima.
- Na seção Selecionar serviço de coletor:
- Serviço de coletor: selecione Bucket do Cloud Storage.
- Selecione o bucket do Cloud Storage: selecione
appengine-logs-exportno menu suspenso.
- Clique em Próxima.
Na seção Escolher registros para incluir no coletor, insira uma consulta de filtro para selecionar os registros do App Engine. O tipo de recurso precisa ser exatamente "gae_app".
Para todos os registros do App Engine (de solicitação e de aplicativo):
resource.type="gae_app"Somente para registros de solicitação do App Engine:
resource.type="gae_app" logName="projects/PROJECT_ID/logs/appengine.googleapis.com/request_log"Para registros de aplicativos do App Engine (stdout/stderr):
resource.type="gae_app" (logName="projects/PROJECT_ID/logs/stdout" OR logName="projects/PROJECT_ID/logs/stderr")Substitua
PROJECT_IDpelo ID do projeto do GCP.Clique em Próxima.
Revise a configuração e clique em Criar coletor.
Conceder permissões à identidade do gravador do coletor
Depois de criar o coletor, conceda à identidade de gravador dele o papel de criador de objetos do Storage no bucket de destino. A identidade do gravador para a conta de serviço é semelhante a: serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com
- Na página do Roteador de registros, localize o coletor recém-criado.
- Clique no ícone de menu (três pontos verticais) ao lado do nome do gravador.
- Selecione Ver detalhes do coletor.
- Copie a Identidade do gravador (e-mail da conta de serviço).
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket (
appengine-logs-export). - Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar principais: cole a identidade de gravador do coletor (e-mail da conta de serviço).
- Atribuir papéis: selecione Criador de objetos do Storage.
- Clique em Salvar.
Recuperar a conta de serviço do Google SecOps
O Google SecOps usa uma conta de serviço exclusiva para ler dados do bucket do GCS. Você precisa conceder a essa conta de serviço acesso ao seu bucket.
Configurar um feed no Google SecOps para ingerir registros do App Engine
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
App Engine Logs). - Selecione Google Cloud Storage V2 como o Tipo de origem.
Selecione GCP_APP_ENGINE como o Tipo de registro.
Clique em Get Service Account.
Um e-mail exclusivo da conta de serviço será exibido, por exemplo:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopie o endereço de e-mail. Você vai usá-la na próxima etapa.
Clique em Próxima.
Especifique valores para os seguintes parâmetros de entrada:
URL do bucket de armazenamento: insira o URI do bucket do GCS com o caminho do prefixo:
gs://appengine-logs-export/O Cloud Logging organiza os arquivos de registro exportados em hierarquias de diretórios por tipo de registro e data. O tipo de registro pode ser um nome composto, como appengine.googleapis.com/request_log. Os arquivos são fragmentados e nomeados com períodos (por exemplo, 08:00:00_08:59:59_S0.json).
Opção de exclusão da fonte: selecione a opção de exclusão de acordo com sua preferência:
- Nunca: nunca exclui arquivos após as transferências (recomendado para testes).
- Excluir arquivos transferidos: exclui arquivos após a transferência.
- Excluir arquivos transferidos e diretórios vazios: exclui arquivos e diretórios vazios após a transferência.
Idade máxima do arquivo: inclua arquivos modificados nos últimos dias. O padrão é de 180 dias.
Namespace do recurso: o namespace do recurso.
Rótulos de ingestão: o rótulo a ser aplicado aos eventos desse feed.
Clique em Próxima.
Revise a configuração do novo feed na tela Finalizar e clique em Enviar.
Conceder permissões do IAM à conta de serviço do Google SecOps
A conta de serviço do Google SecOps precisa do papel de Leitor de objetos do Storage no bucket do GCS.
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket (
appengine-logs-export). - Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar principais: cole o e-mail da conta de serviço do Google SecOps.
- Atribuir papéis: selecione Leitor de objetos do Storage.
Clique em Salvar.
Noções básicas sobre a estrutura de registros do App Engine
O App Engine envia automaticamente os registros de solicitação e de aplicativos para o Cloud Logging. O App Engine emite registros automaticamente para solicitações enviadas ao aplicativo. Portanto, não é necessário gravar registros de solicitação. Esta seção aborda como gravar registros de apps.
Os registros de solicitação do App Engine têm entradas de registro com campos protoPayload que contêm objetos do tipo RequestLog com @type "type.googleapis.com/google.appengine.logging.v1.RequestLog". O tipo de recurso é "gae_app".
Por padrão, o payload do registro é uma string de texto armazenada no campo textPayload da entrada de registro. As strings aparecem como mensagens na Análise de Registros e são associadas ao serviço e à versão do App Engine que as emitiu.
Para gravar registros estruturados, grave os registros em uma única linha de JSON serializado. Quando você fornece um registro estruturado como um dicionário JSON, alguns campos especiais são retirados do jsonPayload e gravados no campo correspondente no LogEntry gerado. Por exemplo, se o JSON incluir uma propriedade de gravidade, ela será removida do jsonPayload e aparecerá como a gravidade da entrada de registro.
Limitações conhecidas
Quando você encaminha registros do coletor de registros para o Cloud Storage, o destino do Cloud Storage contém apenas registros de solicitação. O App Engine grava os registros de aplicativos em pastas diferentes.
As entradas de registro encaminhadas são salvas em lotes a cada hora nos buckets do Cloud Storage. Pode levar de 2 a 3 horas para as primeiras entradas aparecerem.
No ambiente flexível do App Engine, a geração de registros funciona automaticamente. No entanto, os registros são coletados em um formato diferente. Os registros não serão agrupados por solicitações, e os registros de stdout e stderr serão coletados separadamente.
Tabela de mapeamento de UDM
| Campo de registro | Mapeamento de UDM | Lógica |
|---|---|---|
| jsonPayload.logger, taskTypeName, jsonPayload.@type, jsonPayload.backendTargetProjectNumber, jsonPayload.cacheDecision, resource.labels.version_id, resource.labels.module_id, logName, spanId, trace, protoPayload.@type, labels.clone_id, operation.producer | additional.fields | Mesclado com rótulos de chave-valor criados em cada campo |
| metadados | metadados | Renomeado de metadados |
| receiveTimestamp | metadata.collected_timestamp | Analisado usando o filtro de data com RFC 3339 |
| metadata.event_type | Defina como "USER_LOGIN" se has_principal, has_target, has_principal_user; "NETWORK_CONNECTION" se has_principal e has_target; "USER_UNCATEGORIZED" se não has_principal e has_target; "STATUS_UPDATE" se has_principal; "USER_UNCATEGORIZED" se has_principal_user; caso contrário, "GENERIC_EVENT" | |
| metadata.extensions.auth.type | Defina como "AUTHTYPE_UNSPECIFIED" se has_principal, has_target, has_principal_user | |
| insertId | metadata.product_log_id | Valor copiado diretamente |
| httpRequest.requestMethod,protoPayload.method | network.http.method | Valor de httpRequest.requestMethod se não estiver vazio. Caso contrário, protoPayload.method. |
| httpRequest.userAgent | network.http.parsed_user_agent | Convertido para parseduseragent |
| httpRequest.status | network.http.response_code | Convertido em string e depois em número inteiro |
| httpRequest.userAgent | network.http.user_agent | Valor copiado diretamente |
| httpRequest.responseSize | network.received_bytes | Convertido para uinteger |
| httpRequest.requestSize | network.sent_bytes | Convertido para uinteger |
| participante | participante | Renomeado do principal, se não estiver vazio |
| protoPayload.host | principal.asset.hostname | Valor copiado diretamente |
| httpRequest.serverIp, protoPayload.ip | principal.asset.ip | Mesclado com server_ip de httpRequest.serverIp ou protoPayload.ip |
| protoPayload.host | principal.hostname | Valor copiado diretamente |
| httpRequest.serverIp, protoPayload.ip | principal.ip | Mesclado com server_ip de httpRequest.serverIp ou protoPayload.ip |
| protoPayload.appId | principal.resource.attribute.labels | Mesclado com appId_label contendo a chave "appId" e o valor do campo |
| requestUser | principal.user.email_addresses | Mesclado com requestUser se corresponder ao padrão de e-mail |
| security_result | security_result | Mesclado de security_result |
| resource.labels.forwarding_rule_name | security_result.rule_labels | Mesclado com rule_label contendo a chave "forwarding_rule_name" e o valor do campo |
| gravidade, | security_result.severity | Defina como gravidade se corresponder a (?i)ERROR|CRITICAL, INFORMATIONAL se corresponder a (?i)INFO, MEDIUM se corresponder a (?i)WARN, LOW se corresponder a (?i)DEBUG, caso contrário, UNKNOWN_SEVERITY |
| jsonPayload.statusDetails | security_result.summary | Valor copiado diretamente |
| destino | destino | Renomeado do destino se não estiver vazio |
| resource.labels.backend_service_name | target.application | Valor copiado diretamente |
| httpRequest.remoteIp, jsonPayload.remoteIp | target.asset.ip | Mesclado com remote_ip extraído de httpRequest.remoteIp ou jsonPayload.remoteIp |
| resource.labels.project_id | target.cloud.project.name | Valor copiado diretamente |
| httpRequest.remoteIp, jsonPayload.remoteIp | target.ip | Mesclado com remote_ip extraído de httpRequest.remoteIp ou jsonPayload.remoteIp |
| resource.labels.zone | target.resource.attribute.cloud.availability_zone | Valor copiado diretamente |
| resource.labels.target_proxy_name, resource.labels.url_map_name | target.resource.attribute.labels | Mesclados com marcadores de cada fonte |
| resource.type | target.resource.type | Valor copiado diretamente |
| httpRequest.requestUrl | target.url | Valor copiado diretamente |
| metadata.product_name | Defina como "GCP_APP_ENGINE" | |
| metadata.vendor_name | Defina como "GCP". | |
protoPayload.requestMetadata.callerIp |
event.idm.read_only_udm.principal.ip |
Mapeado do registro de mudanças |
protoPayload.requestMetadata.callerIp |
event.idm.read_only_udm.principal.asset.ip |
Mapeado do registro de alterações |
protoPayload.authenticationInfo.principalEmail |
event.idm.read_only_udm.principal.user.email_addresses |
Mapeado do registro de alterações |
protoPayload.methodName |
event.idm.read_only_udm.metadata.product_event_type |
Mapeado do registro de alterações |
protoPayload.resourceName |
event.idm.read_only_udm.target.resource.name |
Mapeado do registro de alterações |
protoPayload.serviceName |
event.idm.read_only_udm.target.application |
Mapeado do registro de alterações |
protoPayload.resourceLocation.currentLocations |
event.idm.read_only_udm.target.resource.attribute.labels |
Mapeado do registro de alterações |
protoPayload.authenticationInfo.oauthInfo.oauthClientId |
event.idm.read_only_udm.principal.resource.attribute.labels |
Mapeado do registro de alterações |
protoPayload.requestMetadata.requestAttributes.time |
event.idm.read_only_udm.additional.fields |
Mapeado do registro de alterações |
operation.first |
event.idm.read_only_udm.additional.fields |
Mapeado do registro de alterações |
protoPayload.serviceData.updateService.request.updateMask |
event.idm.read_only_udm.additional.fields |
Mapeado do registro de alterações |
operation.id |
event.idm.read_only_udm.additional.fields |
Mapeado do registro de alterações |
protoPayload.authenticationInfo.serviceAccountKeyName |
event.idm.read_only_udm.additional.fields |
Mapeado do registro de alterações |
protoPayload.authorizationInfo.permission |
event.idm.read_only_udm.security_result.rule_name |
Mapeado do registro de alterações |
protoPayload.authorizationInfo.permissionType |
event.idm.read_only_udm.security_result.description |
Mapeado do registro de alterações |
protoPayload.authorizationInfo.granted |
event.idm.read_only_udm.security_result.action |
Mapeado do registro de alterações |
protoPayload.@type" , "labels.clone_id" and "operation.producer |
additional.labels |
Mapeado do registro de alterações |
Registro de alterações
Confira o registro de alterações deste analisador
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.