Recopila registros de Google App Engine

Versión del analizador: 3.0

Compatible con:

En este documento, se explica cómo transferir registros de Google App Engine a Google Security Operations con Google Cloud Storage V2.

Google App Engine es una plataforma sin servidores completamente administrada para compilar e implementar aplicaciones web y APIs. App Engine genera automáticamente registros de solicitudes para las solicitudes HTTP y registros de aplicación a partir de tu código. Estos registros se envían a Cloud Logging y se pueden exportar a Cloud Storage para transferirlos a Google Security Operations.

Antes de comenzar

Asegúrate de cumplir con los siguientes requisitos previos:

  • Una instancia de Google SecOps
  • Un proyecto de GCP con la API de Cloud Storage habilitada
  • Permisos para crear y administrar buckets de GCS
  • Permisos para administrar políticas de IAM en buckets de GCS
  • Permisos para crear receptores de registros de Cloud Logging (roles/logging.configWriter)
  • Una aplicación activa de App Engine (entorno estándar o flexible)

Crea un bucket de Google Cloud Storage

  1. Ve a la consola de Google Cloud.
  2. Selecciona tu proyecto o crea uno nuevo.
  3. En el menú de navegación, ve a Cloud Storage > Buckets.
  4. Haz clic en Crear bucket.
  5. Proporciona los siguientes detalles de configuración:

    Parámetro de configuración Valor
    Asigna un nombre a tu bucket Ingresa un nombre único a nivel global (por ejemplo, appengine-logs-export).
    Tipo de ubicación Elige según tus necesidades (regional, birregional o multirregional)
    Ubicación Selecciona la ubicación (por ejemplo, us-central1).
    Clase de almacenamiento Estándar (recomendado para los registros a los que se accede con frecuencia)
    Control de acceso Uniforme (recomendado)
    Herramientas de protección Opcional: Habilita el control de versiones de objetos o la política de retención
  6. Haz clic en Crear.

Configura Cloud Logging para exportar registros de App Engine a GCS

Cloud Logging usa receptores de registros para enrutar entradas de registro a destinos compatibles, incluidos los buckets de Cloud Storage. La identidad del escritor del receptor requiere el rol de creador de objetos de Storage (roles/storage.objectCreator) en el bucket de destino.

Crea un receptor de registros de Cloud Logging

  1. En la consola de Google Cloud, ve a Logging > Enrutador de registros.
  2. Haz clic en Crear un receptor.
  3. Proporciona los siguientes detalles de configuración:
    • Nombre del receptor: Ingresa un nombre descriptivo (por ejemplo, appengine-to-gcs).
    • Descripción del receptor: Es una descripción opcional.
  4. Haz clic en Siguiente.
  5. En la sección Selecciona el servicio de receptor, haz lo siguiente:
    • Servicio de receptor: Selecciona Bucket de Cloud Storage.
    • Selecciona un bucket de Cloud Storage: Selecciona appengine-logs-export en el menú desplegable.
  6. Haz clic en Siguiente.
  7. En la sección Elige registros para incluirlos en el receptor, ingresa una consulta de filtro para seleccionar los registros de App Engine. El tipo de recurso debe ser exactamente "gae_app".

    Para todos los registros de App Engine (registros de solicitudes y de aplicaciones), haz lo siguiente:

    resource.type="gae_app"
    

    Solo para los registros de solicitudes de App Engine:

    resource.type="gae_app"
    logName="projects/PROJECT_ID/logs/appengine.googleapis.com/request_log"
    

    Para los registros de la aplicación de App Engine (stdout/stderr):

    resource.type="gae_app"
    (logName="projects/PROJECT_ID/logs/stdout" OR logName="projects/PROJECT_ID/logs/stderr")
    

    Reemplaza PROJECT_ID por el ID del proyecto de GCP.

  8. Haz clic en Siguiente.

  9. Revisa la configuración y haz clic en Crear receptor.

Otorga permisos a la identidad de escritor del receptor

Después de crear el receptor, debes otorgarle a la identidad de escritor del receptor el rol de creador de objetos de Storage en el bucket de destino. La identidad de escritura de la cuenta de servicio se ve de la siguiente manera: serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com

  1. En la página Enrutador de registros, busca el receptor recién creado.
  2. Haz clic en el ícono de menú (tres puntos verticales) junto al nombre del receptor.
  3. Selecciona Ver detalles del receptor.
  4. Copia la Identidad del escritor (correo electrónico de la cuenta de servicio).
  5. Ve a Cloud Storage > Buckets.
  6. Haz clic en el nombre del bucket (appengine-logs-export).
  7. Ve a la pestaña Permisos.
  8. Haz clic en Otorgar acceso.
  9. Proporciona los siguientes detalles de configuración:
    • Agregar principales: Pega la identidad de escritor del receptor (correo electrónico de la cuenta de servicio).
    • Asignar roles: Selecciona Creador de objetos de Storage.
  10. Haz clic en Guardar.

Recupera la cuenta de servicio de Google SecOps

Google SecOps usa una cuenta de servicio única para leer datos de tu bucket de GCS. Debes otorgar acceso a tu bucket a esta cuenta de servicio.

Configura un feed en Google SecOps para transferir registros de App Engine

  1. Ve a Configuración de SIEM > Feeds.
  2. Haz clic en Add New Feed.
  3. Haz clic en Configura un feed único.
  4. En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo, App Engine Logs).
  5. Selecciona Google Cloud Storage V2 como el Tipo de fuente.
  6. Selecciona GCP_APP_ENGINE como el Tipo de registro.

  7. Haz clic en Obtener cuenta de servicio.

  8. Se mostrará un correo electrónico único de la cuenta de servicio, por ejemplo:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. Copia esta dirección de correo electrónico. la usarás en el próximo paso.

  10. Haz clic en Siguiente.

  11. Especifica valores para los siguientes parámetros de entrada:

    • URL del bucket de almacenamiento: Ingresa el URI del bucket de GCS con la ruta del prefijo:

      gs://appengine-logs-export/
      

      Cloud Logging organiza los archivos de registro exportados en jerarquías de directorios por tipo de registro y fecha. El tipo de registro puede ser un nombre compuesto, como appengine.googleapis.com/request_log. Los archivos se fragmentan y se nombran con períodos (por ejemplo, 08:00:00_08:59:59_S0.json).

    • Opción de eliminación del código fuente: Selecciona la opción de eliminación según tu preferencia:

      • Nunca: Nunca borra ningún archivo después de las transferencias (se recomienda para las pruebas).
      • Borrar archivos transferidos: Borra los archivos después de que se transfirieron correctamente.
      • Borrar los archivos transferidos y los directorios vacíos: Borra los archivos y los directorios vacíos después de que se transfirieron correctamente.
    • Antigüedad máxima del archivo: Incluye los archivos modificados en la última cantidad de días. El valor predeterminado es de 180 días.

    • Espacio de nombres del recurso: Es el espacio de nombres del recurso.

    • Etiquetas de transferencia: Es la etiqueta que se aplicará a los eventos de este feed.

  12. Haz clic en Siguiente.

  13. Revisa la configuración de tu nuevo feed de noticias en la pantalla Finalizar y, luego, haz clic en Enviar.

Otorga permisos de IAM a la cuenta de servicio de Google SecOps

La cuenta de servicio de Google SecOps necesita el rol de visualizador de objetos de Storage en tu bucket de GCS.

  1. Ve a Cloud Storage > Buckets.
  2. Haz clic en el nombre del bucket (appengine-logs-export).
  3. Ve a la pestaña Permisos.
  4. Haz clic en Otorgar acceso.
  5. Proporciona los siguientes detalles de configuración:
    • Agregar entidades: Pega el correo electrónico de la cuenta de servicio de Google SecOps.
    • Asigna roles: Selecciona Visualizador de objetos de Storage.
  6. Haz clic en Guardar.

Información sobre la estructura de los registros de App Engine

App Engine envía de forma automática los registros de solicitud y los registros de la app a Cloud Logging. App Engine emite registros de forma automática para las solicitudes enviadas a tu app, por lo que no es necesario escribir registros de solicitudes. En esta sección, se explica cómo escribir registros de apps.

Los registros de solicitudes de App Engine tienen entradas de registro que contienen campos protoPayload que contienen objetos de tipo RequestLog con @type "type.googleapis.com/google.appengine.logging.v1.RequestLog". El tipo de recurso es "gae_app".

De forma predeterminada, la carga útil del registro es una cadena de texto almacenada en el campo textPayload de la entrada de registro. Las cadenas aparecen como mensajes en el Explorador de registros y se asocian con el servicio y la versión de App Engine que las emitió.

Para escribir registros estructurados, debes escribir registros en el formato de una sola línea de JSON serializado. Cuando proporcionas un registro estructurado como un diccionario JSON, algunos campos especiales se quitan de jsonPayload y se escriben en el campo correspondiente en la LogEntry generada. Por ejemplo, si tu JSON incluye una propiedad de gravedad, se quita de jsonPayload y aparece como la gravedad de la entrada de registro.

Limitaciones conocidas

Cuando enrutas registros del receptor de registros a Cloud Storage, el destino de Cloud Storage solo contiene registros de solicitud. App Engine escribe registros de aplicaciones en diferentes carpetas.

Las entradas de registro se guardan en buckets de Cloud Storage en lotes por hora. Es posible que pasen de 2 a 3 horas antes de que empiecen a aparecer las primeras entradas.

En el entorno flexible de App Engine, el registro funciona de forma automática. Sin embargo, los registros se recopilan en un formato diferente. Los registros no se agruparán por solicitudes, y los registros de stdout y stderr se recopilarán por separado.

Tabla de asignación de UDM

Campo de registro Asignación 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 Se combinan con etiquetas de par clave-valor creadas a partir de cada campo.
metadatos metadatos Se cambió el nombre a partir de los metadatos
receiveTimestamp metadata.collected_timestamp Se analizó con el filtro de fecha con RFC 3339
metadata.event_type Se establece en "USER_LOGIN" si tiene has_principal, has_target, has_principal_user; "NETWORK_CONNECTION" si tiene has_principal y has_target; "USER_UNCATEGORIZED" si no tiene has_principal y tiene has_target; "STATUS_UPDATE" si tiene has_principal; "USER_UNCATEGORIZED" si tiene has_principal_user; de lo contrario, "GENERIC_EVENT"
metadata.extensions.auth.type Se establece en "AUTHTYPE_UNSPECIFIED" si has_principal, has_target, has_principal_user
insertId metadata.product_log_id El valor se copia directamente.
httpRequest.requestMethod,protoPayload.method network.http.method Valor de httpRequest.requestMethod si no está vacío; de lo contrario, protoPayload.method
httpRequest.userAgent network.http.parsed_user_agent Se convirtió en parseduseragent
httpRequest.status network.http.response_code Se convierte en cadena y, luego, en número entero
httpRequest.userAgent network.http.user_agent El valor se copia directamente.
httpRequest.responseSize network.received_bytes Se convirtió en uinteger
httpRequest.requestSize network.sent_bytes Se convirtió en uinteger
entidad entidad Se cambió el nombre de principal si no está vacío
protoPayload.host principal.asset.hostname El valor se copia directamente.
httpRequest.serverIp, protoPayload.ip principal.asset.ip Se combinó con server_ip de httpRequest.serverIp o protoPayload.ip
protoPayload.host principal.hostname El valor se copió directamente.
httpRequest.serverIp, protoPayload.ip principal.ip Se combinó con server_ip de httpRequest.serverIp o protoPayload.ip
protoPayload.appId principal.resource.attribute.labels Se combina con appId_label, que contiene la clave "appId" y el valor del campo
requestUser principal.user.email_addresses Se combina con requestUser si coincide con el patrón de correo electrónico
security_result security_result Combinado de security_result
resource.labels.forwarding_rule_name security_result.rule_labels Se combina con rule_label que contiene la clave "forwarding_rule_name" y el valor del campo
gravedad, security_result.severity Se establece en gravedad si coincide con (?i)ERROR|CRITICAL, en INFORMATIONAL si coincide con (?i)INFO, en MEDIUM si coincide con (?i)WARN, en LOW si coincide con (?i)DEBUG y, de lo contrario, en UNKNOWN_SEVERITY.
jsonPayload.statusDetails security_result.summary El valor se copia directamente.
objetivo objetivo Se cambió el nombre del destino si no está vacío.
resource.labels.backend_service_name target.application El valor se copió directamente.
httpRequest.remoteIp, jsonPayload.remoteIp target.asset.ip Se combina con remote_ip extraído de httpRequest.remoteIp o jsonPayload.remoteIp.
resource.labels.project_id target.cloud.project.name El valor se copia directamente.
httpRequest.remoteIp, jsonPayload.remoteIp target.ip Se combina con remote_ip extraído de httpRequest.remoteIp o jsonPayload.remoteIp.
resource.labels.zone target.resource.attribute.cloud.availability_zone El valor se copia directamente.
resource.labels.target_proxy_name, resource.labels.url_map_name target.resource.attribute.labels Se combinan con las etiquetas de cada fuente.
resource.type target.resource.type El valor se copia directamente.
httpRequest.requestUrl target.url El valor se copia directamente.
metadata.product_name Se establece en "GCP_APP_ENGINE".
metadata.vendor_name Establece el valor en "GCP".
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.ip Asignado desde el registro de cambios
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.asset.ip Se asignó desde el registro de cambios
protoPayload.authenticationInfo.principalEmail event.idm.read_only_udm.principal.user.email_addresses Se asignó desde el registro de cambios
protoPayload.methodName event.idm.read_only_udm.metadata.product_event_type Se asignó desde el registro de cambios
protoPayload.resourceName event.idm.read_only_udm.target.resource.name Se asignó desde el registro de cambios
protoPayload.serviceName event.idm.read_only_udm.target.application Se asignó desde el registro de cambios
protoPayload.resourceLocation.currentLocations event.idm.read_only_udm.target.resource.attribute.labels Se asignó desde el registro de cambios
protoPayload.authenticationInfo.oauthInfo.oauthClientId event.idm.read_only_udm.principal.resource.attribute.labels Se asignó desde el registro de cambios
protoPayload.requestMetadata.requestAttributes.time event.idm.read_only_udm.additional.fields Se asignó desde el registro de cambios
operation.first event.idm.read_only_udm.additional.fields Se asignó desde el registro de cambios
protoPayload.serviceData.updateService.request.updateMask event.idm.read_only_udm.additional.fields Se asignó desde el registro de cambios
operation.id event.idm.read_only_udm.additional.fields Se asignó desde el registro de cambios
protoPayload.authenticationInfo.serviceAccountKeyName event.idm.read_only_udm.additional.fields Se asignó desde el registro de cambios
protoPayload.authorizationInfo.permission event.idm.read_only_udm.security_result.rule_name Se asignó desde el registro de cambios
protoPayload.authorizationInfo.permissionType event.idm.read_only_udm.security_result.description Se asignó desde el registro de cambios
protoPayload.authorizationInfo.granted event.idm.read_only_udm.security_result.action Se asignó desde el registro de cambios
protoPayload.@type" , "labels.clone_id" and "operation.producer additional.labels Asignado desde el registro de cambios

Registro de cambios

Consulta el registro de cambios de este analizador

¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.