Coletar registros do Google App Engine

Versão do analisador:3.0

Compatível com:

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

  1. Acesse o Console do Google Cloud.
  2. Selecione seu projeto ou crie um novo.
  3. No menu de navegação, acesse Cloud Storage > Buckets.
  4. Clique em Criar bucket.
  5. 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
  6. 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

  1. No console do Google Cloud, acesse Geração de registros > Roteador de registros.
  2. Clique em Criar coletor.
  3. 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.
  4. Clique em Próxima.
  5. 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-export no menu suspenso.
  6. Clique em Próxima.
  7. 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_ID pelo ID do projeto do GCP.

  8. Clique em Próxima.

  9. 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

  1. Na página do Roteador de registros, localize o coletor recém-criado.
  2. Clique no ícone de menu (três pontos verticais) ao lado do nome do gravador.
  3. Selecione Ver detalhes do coletor.
  4. Copie a Identidade do gravador (e-mail da conta de serviço).
  5. Acesse Cloud Storage > Buckets.
  6. Clique no nome do bucket (appengine-logs-export).
  7. Acesse a guia Permissões.
  8. Clique em Conceder acesso.
  9. 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.
  10. 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

  1. Acesse Configurações do SIEM > Feeds.
  2. Clique em Adicionar novo feed.
  3. Clique em Configurar um único feed.
  4. No campo Nome do feed, insira um nome para o feed (por exemplo, App Engine Logs).
  5. Selecione Google Cloud Storage V2 como o Tipo de origem.
  6. Selecione GCP_APP_ENGINE como o Tipo de registro.

  7. Clique em Get Service Account.

  8. Um e-mail exclusivo da conta de serviço será exibido, por exemplo:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. Copie o endereço de e-mail. Você vai usá-la na próxima etapa.

  10. Clique em Próxima.

  11. 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.

  12. Clique em Próxima.

  13. 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.

  1. Acesse Cloud Storage > Buckets.
  2. Clique no nome do bucket (appengine-logs-export).
  3. Acesse a guia Permissões.
  4. Clique em Conceder acesso.
  5. 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.
  6. 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.