Recopila registros de WAF de Fastly

Se admite en los siguientes países:

Descripción general

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

Antes de comenzar

  • Asegúrate de tener una instancia de Google SecOps.
  • Una cuenta de Fastly con acceso para configurar la configuración de WAF

Configura un feed en Google SecOps para transferir los registros de WAF de Fastly

  1. Ve a Configuración de SIEM > Feeds.
  2. Haz clic en Agregar nueva.
  3. En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo, Registros de WAF de Fastly).
  4. Selecciona Webhook como el Tipo de origen.
  5. Selecciona Fastly WAF como el Tipo de registro.
  6. Haz clic en Siguiente.
  7. 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.
    • Espacio de nombres del activo: Es el espacio de nombres del activo.
    • Etiquetas de transferencia: Es la etiqueta que se aplica a los eventos de este feed.
  8. Haz clic en Siguiente.
  9. Revisa la configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.
  10. Haz clic en Generate Secret Key para generar una clave secreta que autentique este feed.
  11. Copia y almacena la clave secreta. No podrás volver a ver esta clave secreta. Si es necesario, puedes volver a generar una clave secreta nueva, pero esta acción hace que la clave secreta anterior quede obsoleta.
  12. 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.
  13. Haz clic en Listo.

Crea una clave de API para el feed de webhook

  1. Ve a consola de Google Cloud > Credenciales.

    Ir a Credenciales

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

  3. Restringe el acceso de 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 en 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 consulta 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 uno).
  3. Selecciona Administrar > Integraciones de sitios.
  4. Haz clic en Agregar integración de sitios.
  5. Selecciona Webhook genérico.
  6. URL de webhook: Ingresa ENDPOINT_URL de SecOps de Google, seguido de API_KEY y SECRET.
  7. Ubicación de la alerta: Selecciona Toda la actividad o Actividad específica.
  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 de sitios.

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 ni es 0, el valor de anomaly_score se usa para propagar el array security_result.detection_fields con una clave de "anomaly" 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 connection.fastly_is_edge se usa para propagar el array additional.fields con una clave de "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 propagar el array additional.fields con una clave de "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 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 extrae de geo.location
principal.location.region_longitude: Se extrae 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 request_headers.accept_charset se usa para propagar 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 request_headers.accept_language se usa para propagar 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 propagar 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 propagar el array additional.fields con una clave de "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 propagar 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 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 waf.logged se usa para propagar el array security_result.detection_fields con una clave de "registrado" 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 y no está vacío, el valor se usa para propagar el array security_result.detection_fields con una clave de "anomaly" 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 propagar el array security_result.detection_fields.
waf.score.lfi security_result.detection_fields[].key: "lfi"
security_result.detection_fields[].value: waf.score.lfi
Tiene una 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
Tiene una 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
Tiene una 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
Tiene una 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
Tiene una 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
Tiene una 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
Tiene una lógica similar a la de waf.score.http_violation.
waf.severity security_result.severity: derivado
security_result.severity_details: waf.severity
Si waf.severity no está vacío, determina el valor de security_result.severity en función de los rangos (<=3: ALTA, >3 y <=6: MEDIA, >6 y <=8: BAJA, de lo contrario: UNKNOWN_SEVERITY). El valor waf.severity original 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 hard-coded. Valor hard-coded. Valor hard-coded.

Cambios

2022-06-06

  • Sin embargo, el analizador se creó recientemente.