Recopila registros del WAF de Fastly

Compatible con:

Descripción general

Este analizador extrae campos de los registros JSON del WAF de Fastly, los transforma y cambia de nombre, y los asigna al UDM. Maneja varios tipos de datos, convierte los niveles de gravedad y categoriza los eventos según la información disponible de la dirección IP y el nombre de host. También controla posibles errores de análisis y descarta las entradas de registro con formato incorrecto.

Antes de comenzar

Asegúrate de cumplir con los siguientes requisitos previos:

  • Instancia de Google SecOps.
  • Cuenta de Fastly con acceso para configurar los parámetros del WAF

Configura feeds

Existen dos puntos de entrada diferentes para configurar feeds en la plataforma de Google SecOps:

  • Configuración de SIEM > Feeds
  • Centro de contenido > Paquetes de contenido

Configura feeds en Configuración del SIEM > Feeds

Para configurar un feed, sigue estos pasos:

  1. Ve a Configuración del SIEM > Feeds.
  2. Haz clic en Agregar feed nuevo.
  3. En la siguiente página, haz clic en Configurar un solo feed.
  4. En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo, Registros del WAF de Fastly).
  5. Selecciona Webhook como el Tipo de origen.
  6. Selecciona Fastly WAF como el Tipo de registro.
  7. Haz clic en Siguiente.
  8. Opcional: Especifica valores para los siguientes parámetros de entrada:
    • Delimitador de división: Es el delimitador que se usa para separar las líneas de registro, como \n.
  9. Haz clic en Siguiente.
  10. Revisa la configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.
  11. Haz clic en Generar clave secreta para generar una clave secreta que autentique este feed.
  12. Copia y almacena la clave secreta. No podrás volver a ver esta clave secreta. Si es necesario, puedes regenerar una clave secreta nueva, pero esta acción hace que la clave secreta anterior quede obsoleta.
  13. En la pestaña Detalles, copia la URL del extremo del feed del campo Información del extremo. Debes especificar esta URL de extremo en tu aplicación cliente.
  14. Haz clic en Listo.

Configura feeds desde el Centro de contenido

Especifica valores para los siguientes campos:

  • Delimitador de división: Es el delimitador que se usa para separar las líneas de registro, como \n.

Opciones avanzadas

  • Nombre del feed: Es un valor completado previamente que identifica el feed.
  • Tipo de fuente: Es el método que se usa para recopilar registros en Google SecOps.
  • Espacio de nombres del activo: Es el espacio de nombres asociado con el feed.
  • Etiquetas de transferencia: Son las etiquetas que se aplican a todos los eventos de este feed.

  • Haz clic en Generar clave secreta para generar una clave secreta que autentique este feed.

  • Copia y almacena la clave secreta. No podrás volver a ver esta clave secreta. Si es necesario, puedes regenerar una clave secreta nueva, pero esta acción hace que la clave secreta anterior quede obsoleta.

  • En la pestaña Detalles, copia la URL del extremo del feed del campo Información del extremo. Debes especificar esta URL de extremo en tu aplicación cliente.

Crea una clave de API para el feed del webhook

  1. Ve a Google Cloud consola > Credenciales.

    Ir a Credenciales

  2. Haz clic en Crear credenciales y selecciona Clave de API.

  3. Restringe el acceso a la clave de API a la API de Google Security Operations.

Especifica la URL del extremo

  1. En tu aplicación cliente, especifica la URL del extremo HTTPS que se proporciona en el feed de webhook.
  2. Para habilitar la autenticación, especifica la clave de API y la clave secreta como parte del encabezado personalizado con el siguiente formato:

    X-goog-api-key = API_KEY
    X-Webhook-Access-Key = SECRET
    

    Recomendación: Especifica la clave de API como un encabezado en lugar de hacerlo en la URL.

  3. Si tu cliente de webhook no admite encabezados personalizados, puedes especificar la clave de API y la clave secreta con parámetros de búsqueda en el siguiente formato:

    ENDPOINT_URL?key=API_KEY&secret=SECRET
    

    Reemplaza lo siguiente:

    • ENDPOINT_URL: Es la URL del extremo del feed.
    • API_KEY: Es la clave de API para autenticarse en Google Security Operations.
    • SECRET: Es la clave secreta que generaste para autenticar el feed.

Configura el webhook en Fastly

  1. Accede a Fastly.
  2. Opcional: Selecciona un sitio en el menú Sitios (si tienes más de un sitio).
  3. Selecciona Administrar > Integraciones del sitio.
  4. Haz clic en Agregar integración del sitio.
  5. Selecciona Generic Webhook.
  6. URL de webhook: Ingresa ENDPOINT_URL de Google SecOps, seguido de API_KEY y SECRET.
  7. Alert Placement: Selecciona All activity o Specific activity.
  8. Opcional: Si seleccionaste Actividad específica, ve al menú Actividad y selecciona los tipos de actividad que quieres que envíe el webhook.
  9. Haz clic en Crear integración del sitio.

Tabla de asignación de UDM

Campo de registro Asignación de UDM Lógica
anomaly_score security_result.detection_fields[].key: "anomaly"
security_result.detection_fields[].value: anomaly_score
Si waf.score.anomaly es 0 o está vacío, y anomaly_score no está vacío o es 0, el valor de anomaly_score se usa para completar el array security_result.detection_fields con una clave de "anomalía" y el valor del campo anomaly_score.
cache_status additional.fields[].key: "cache_status"
additional.fields[].value.string_value: cache_status
El valor cache_status se usa para propagar el array additional.fields con una clave de "cache_status" y el valor del campo cache_status.
client_ip principal.ip: client_ip El campo client_ip se asigna a principal.ip.
connection.fastly_is_edge additional.fields[].key: "fastly_is_edge"
additional.fields[].value.bool_value: connection.fastly_is_edge
El valor de connection.fastly_is_edge se usa para completar el array additional.fields con una clave "fastly_is_edge" y el valor del campo connection.fastly_is_edge.
connection.fastly_is_shield additional.fields[].key: "fastly_is_shield"
additional.fields[].value.bool_value: connection.fastly_is_shield
El valor connection.fastly_is_shield se usa para completar el array additional.fields con una clave "fastly_is_shield" y el valor del campo connection.fastly_is_shield.
connection.request_tls_version network.tls.version: connection.request_tls_version El campo connection.request_tls_version se asigna a network.tls.version.
fastly.server target.hostname: fastly.server El campo fastly.server se asigna a target.hostname.
fastly.service_id additional.fields[].key: "service_id"
additional.fields[].value.string_value: fastly.service_id
El valor de fastly.service_id se usa para propagar el array additional.fields con una clave de "service_id" y el valor del campo fastly.service_id.
geo.city principal.location.city: geo.city El campo geo.city se asigna a principal.location.city.
geo.country principal.location.country_or_region: geo.country El campo geo.country se asigna a principal.location.country_or_region.
geo.location principal.location.region_latitude: Se extrajo de geo.location
principal.location.region_longitude: Se extrajo de geo.location
La latitud y la longitud se extraen del campo geo.location con una expresión regular y se asignan a principal.location.region_latitude y principal.location.region_longitude, respectivamente.
geo.region principal.location.state: geo.region El campo geo.region se asigna a principal.location.state.
host principal.hostname: host El campo host se asigna a principal.hostname.
request_headers.accept_charset additional.fields[].key: "accept_charset"
additional.fields[].value.string_value: request_headers.accept_charset
El valor de request_headers.accept_charset se usa para completar el array additional.fields con una clave de "accept_charset" y el valor del campo request_headers.accept_charset.
request_headers.accept_language additional.fields[].key: "accept_language"
additional.fields[].value.string_value: request_headers.accept_language
El valor de request_headers.accept_language se usa para completar el array additional.fields con una clave de "accept_language" y el valor del campo request_headers.accept_language.
request_headers.referer network.http.referral_url: request_headers.referer El campo request_headers.referer se asigna a network.http.referral_url.
request_headers.user_agent network.http.user_agent: request_headers.user_agent El campo request_headers.user_agent se asigna a network.http.user_agent.
request_id metadata.product_log_id: request_id El campo request_id se asigna a metadata.product_log_id.
request_method network.http.method: request_method El campo request_method se asigna a network.http.method.
response_headers.cache_control additional.fields[].key: "cache_control"
additional.fields[].value.string_value: response_headers.cache_control
El valor response_headers.cache_control se usa para propagar el array additional.fields con una clave de "cache_control" y el valor del campo response_headers.cache_control.
response_headers.content_type additional.fields[].key: "content_type"
additional.fields[].value.string_value: response_headers.content_type
El valor response_headers.content_type se usa para completar el array additional.fields con una clave de "content_type" y el valor del campo response_headers.content_type.
response_state additional.fields[].key: "response_state"
additional.fields[].value.string_value: response_state
El valor response_state se usa para completar el array additional.fields con una clave "response_state" y el valor del campo response_state.
response_status network.http.response_code: response_status El campo response_status se asigna a network.http.response_code si el campo status está vacío.
rule_id security_result.rule_id: rule_id Si waf.rule_id está vacío, se usa el valor rule_id para completar security_result.rule_id.
severity waf.severity: severity El valor del campo severity se copia en waf.severity.
size_bytes.request_header network.sent_bytes: size_bytes.request_header El campo size_bytes.request_header se asigna a network.sent_bytes.
size_bytes.response_header network.received_bytes: size_bytes.response_header El campo size_bytes.response_header se asigna a network.received_bytes.
status network.http.response_code: status El campo status se asigna a network.http.response_code.
timestamp metadata.event_timestamp: timestamp El campo timestamp se analiza y se asigna a metadata.event_timestamp.
url target.url: url El campo url se asigna a target.url.
waf.blocked security_result.action: Derivado Si waf.blocked es falso, security_result.action se establece en "ALLOW". Si waf.blocked es verdadero, security_result.action se establece en "BLOCK".
waf.executed security_result.detection_fields[].key: "executed"
security_result.detection_fields[].value: waf.executed
El valor de waf.executed se usa para propagar el array security_result.detection_fields con una clave de "executed" y el valor del campo waf.executed.
waf.failures security_result.detection_fields[].key: "failures"
security_result.detection_fields[].value: waf.failures
El valor waf.failures se usa para propagar el array security_result.detection_fields con una clave de "failures" y el valor del campo waf.failures.
waf.logged security_result.detection_fields[].key: "logged"
security_result.detection_fields[].value: waf.logged
El valor de waf.logged se usa para completar el array security_result.detection_fields con una clave "logged" y el valor del campo waf.logged.
waf.message metadata.description: waf.message Si waf.message no está vacío, se asigna a metadata.description.
waf.rule_id security_result.rule_id: waf.rule_id Si waf.rule_id no está vacío, se asigna a security_result.rule_id.
waf.score.anomaly security_result.detection_fields[].key: "anomaly"
security_result.detection_fields[].value: waf.score.anomaly
Si waf.score.anomaly no es 0 ni está vacío, el valor se usa para propagar el array security_result.detection_fields con una clave de "anomalía" y el valor del campo waf.score.anomaly.
waf.score.http_violation security_result.detection_fields[].key: "http_violation"
security_result.detection_fields[].value: waf.score.http_violation
Si waf.score.http_violation no es 0 ni está vacío, el valor se usa para completar el array security_result.detection_fields.
waf.score.lfi security_result.detection_fields[].key: "lfi"
security_result.detection_fields[].value: waf.score.lfi
Lógica similar a la de waf.score.http_violation.
waf.score.php_injection security_result.detection_fields[].key: "php_injection"
security_result.detection_fields[].value: waf.score.php_injection
Lógica similar a la de waf.score.http_violation.
waf.score.rce security_result.detection_fields[].key: "rce"
security_result.detection_fields[].value: waf.score.rce
Lógica similar a la de waf.score.http_violation.
waf.score.rfi security_result.detection_fields[].key: "rfi"
security_result.detection_fields[].value: waf.score.rfi
Lógica similar a la de waf.score.http_violation.
waf.score.session_fixation security_result.detection_fields[].key: "session_fixation"
security_result.detection_fields[].value: waf.score.session_fixation
Lógica similar a la de waf.score.http_violation.
waf.score.sql_injection security_result.detection_fields[].key: "sql_injection"
security_result.detection_fields[].value: waf.score.sql_injection
Lógica similar a la de waf.score.http_violation.
waf.score.xss security_result.detection_fields[].key: "xss"
security_result.detection_fields[].value: waf.score.xss
Lógica similar a la de waf.score.http_violation.
waf.severity security_result.severity: derived
security_result.severity_details: waf.severity
Si waf.severity no está vacío, determina el valor de security_result.severity según los rangos (<=3: ALTA, >3 y <=6: MEDIA, >6 y <=8: BAJA, de lo contrario: UNKNOWN_SEVERITY). El valor original de waf.severity también se asigna a security_result.severity_details.
waf_message metadata.description: waf_message Si waf.message está vacío y waf_message no está vacío, se asigna a metadata.description. Si client_ip o host y fastly.server no están vacíos, metadata.event_type se establece en "NETWORK_HTTP". De lo contrario, si client_ip o host no están vacíos, metadata.event_type se establece en "STATUS_UPDATE". De lo contrario, se establece como "GENERIC_EVENT". Valor codificado. Valor codificado. Valor codificado.

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