Recopila registros de Google App Engine

Se admite en los siguientes sistemas operativos:

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 aplicaciones a partir de tu código. Estos registros se envían a Cloud Logging y se pueden exportar a Cloud Storage para su transferencia 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 Cloud Logging (roles/logging.configWriter)
  • Una aplicación de App Engine activa (entorno estándar o flexible)

Crea un bucket de Google Cloud Storage

  1. Ve a Google Cloud Console.
  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:

    Configuración Valor
    Asigna un nombre a tu bucket Ingresa un nombre global único (por ejemplo, appengine-logs-export).
    Tipo de ubicación Elige según tus necesidades (región, birregional, 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 las entradas de registro a destinos compatibles, incluidos los buckets de Cloud Storage. La identidad de escritor del receptor requiere el rol de Creador de objetos de Storage (roles/storage.objectCreator) en el bucket de destino.

Crea un receptor 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):

    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 aplicaciones 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 escritor 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 que creaste recientemente.
  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 del 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

Las Operaciones de seguridad de Google usan 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 Agregar feed nuevo.
  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 de acceso 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 borrado de la fuente: Selecciona la opción de borrado 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 la transferencia exitosa.
      • Borrar los archivos transferidos y los directorios vacíos: Borra los archivos y los directorios vacíos después de la transferencia exitosa.
    • Antigüedad máxima del archivo: Incluye los archivos modificados en la cantidad de días especificada. El valor predeterminado es de 180 días.

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

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

  12. Haz clic en Siguiente.

  13. Revisa la nueva configuración del feed 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 almacenamiento 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 principales: Pega el correo electrónico de la cuenta de servicio de Google SecOps.
    • Asignar 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 automáticamente 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 incluyen 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 aparecerán como mensajes en el Explorador de registros y se asociarán 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 se necesiten entre 2 y 3 horas para que aparezcan las primeras entradas.

En el entorno flexible de App Engine, el registro funciona automáticamente. Sin embargo, los registros se recopilan en un formato diferente. Los registros no se agruparán por solicitudes, y los 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 las etiquetas de clave-valor creadas a partir de cada campo.
metadatos metadatos Se cambió el nombre de los metadatos
receiveTimestamp metadata.collected_timestamp Se analizó con el filtro de fecha con RFC3339
metadata.event_type Se establece en "USER_LOGIN" si tiene principal, tiene destino y tiene usuario principal; en "NETWORK_CONNECTION" si tiene principal y tiene destino; en "USER_UNCATEGORIZED" si no tiene principal y tiene destino; en "STATUS_UPDATE" si tiene principal; en "USER_UNCATEGORIZED" si tiene usuario principal; de lo contrario, en "GENERIC_EVENT".
metadata.extensions.auth.type Se establece en "AUTHTYPE_UNSPECIFIED" si tiene principal, tiene destino o tiene usuario principal.
insertId metadata.product_log_id Valor copiado 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ó a parseduseragent
httpRequest.status network.http.response_code Se convierte en una cadena y, luego, en un número entero.
httpRequest.userAgent network.http.user_agent Valor copiado 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 Valor copiado directamente
httpRequest.serverIp, protoPayload.ip principal.asset.ip Se combinó con server_ip de httpRequest.serverIp o protoPayload.ip
protoPayload.host principal.hostname Valor copiado 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 combinó 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 Se combinó de security_result
resource.labels.forwarding_rule_name security_result.rule_labels Se combinó 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 Valor copiado directamente
objetivo objetivo Se cambió el nombre del destino si no está vacío.
resource.labels.backend_service_name target.application Valor copiado 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 Valor copiado 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 Valor copiado 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 Valor copiado directamente
httpRequest.requestUrl target.url Valor copiado directamente
metadata.product_name Se establece en "GCP_APP_ENGINE".
metadata.vendor_name Se estableció en "GCP".

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