Recolha registos do WAF da Fastly

Compatível com:

Vista geral

Este analisador extrai campos dos registos JSON do Fastly WAF, transforma-os, muda-lhes o nome e mapeia-os para o UDM. Processa vários tipos de dados, converte níveis de gravidade e categoriza eventos com base nas informações de IP e nome de anfitrião disponíveis. Também processa potenciais falhas de análise e elimina entradas de registo com formato incorreto.

Antes de começar

Certifique-se de que tem os seguintes pré-requisitos:

  • Instância do Google SecOps.
  • Conta do Fastly com acesso para configurar as definições da WAF.

Configure feeds

Para configurar um feed, siga estes passos:

  1. Aceda a Definições do SIEM > Feeds.
  2. Clique em Adicionar novo feed.
  3. Na página seguinte, clique em Configurar um único feed.
  4. No campo Nome do feed, introduza um nome para o feed (por exemplo, Registos da WAF da Fastly).
  5. Selecione Webhook como o Tipo de origem.
  6. Selecione Fastly WAF como o Tipo de registo.
  7. Clicar em Seguinte.
  8. Opcional: especifique valores para os seguintes parâmetros de entrada:
    • Delimitador de divisão: o delimitador usado para separar linhas de registo, como \n.
  9. Clicar em Seguinte.
  10. Reveja a configuração do feed no ecrã Finalizar e, de seguida, clique em Enviar.
  11. Clique em Gerar chave secreta para gerar uma chave secreta para autenticar este feed.
  12. Copie e armazene a chave secreta. Não pode ver esta chave secreta novamente. Se necessário, pode regenerar uma nova chave secreta, mas esta ação torna a chave secreta anterior obsoleta.
  13. No separador Detalhes, copie o URL do ponto final do feed do campo Informações do ponto final. Tem de especificar este URL do ponto final na sua aplicação cliente.
  14. Clique em Concluído.

Crie uma chave da API para o feed de webhook

  1. Aceda à Google Cloud consola > Credenciais.

    Aceder a Credenciais

  2. Clique em Criar credenciais e, de seguida, selecione Chave de API.

  3. Restrinja o acesso da chave de API à API Google Security Operations.

Especifique o URL do ponto final

  1. Na aplicação cliente, especifique o URL do ponto final HTTPS fornecido no feed do webhook.
  2. Ative a autenticação especificando a chave da API e a chave secreta como parte do cabeçalho personalizado no seguinte formato:

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

    Recomendação: especifique a chave da API como um cabeçalho em vez de a especificar no URL.

  3. Se o seu cliente de webhook não suportar cabeçalhos personalizados, pode especificar a chave da API e a chave secreta através de parâmetros de consulta no seguinte formato:

    ENDPOINT_URL?key=API_KEY&secret=SECRET
    

    Substitua o seguinte:

    • ENDPOINT_URL: o URL do ponto final do feed.
    • API_KEY: a chave da API para autenticar no Google Security Operations.
    • SECRET: a chave secreta que gerou para autenticar o feed.

Configure o webhook no Fastly

  1. Inicie sessão no Fastly.
  2. Opcional: selecione um site no menu Sites (se tiver mais do que um site).
  3. Selecione Gerir > Integrações do site.
  4. Clique em Adicionar integração do site.
  5. Selecione Webhook genérico.
  6. URL do webhook: introduza ENDPOINT_URL do Google SecOps, seguido de API_KEY e SECRET.
  7. Posicionamento de alertas: selecione Toda a atividade ou Atividade específica.
  8. Opcional: se selecionou Atividade específica, aceda ao menu Atividade e selecione os tipos de atividade que quer que o webhook envie.
  9. Clique em Criar integração do site.

Tabela de mapeamento da UDM

Campo de registo Mapeamento de UDM Lógica
anomaly_score security_result.detection_fields[].key: "anomaly"
security_result.detection_fields[].value: anomaly_score
Se waf.score.anomaly for 0 ou estiver vazio e anomaly_score não estiver vazio ou for 0, o valor de anomaly_score é usado para preencher a matriz security_result.detection_fields com uma chave de "anomalia" e o valor do campo anomaly_score.
cache_status additional.fields[].key: "cache_status"
additional.fields[].value.string_value: cache_status
O valor cache_status é usado para preencher a matriz additional.fields com uma chave de "cache_status" e o valor do campo cache_status.
client_ip principal.ip: client_ip O campo client_ip está mapeado para principal.ip.
connection.fastly_is_edge additional.fields[].key: "fastly_is_edge"
additional.fields[].value.bool_value: connection.fastly_is_edge
O valor connection.fastly_is_edge é usado para preencher a matriz additional.fields com uma chave de "fastly_is_edge" e o valor do campo connection.fastly_is_edge.
connection.fastly_is_shield additional.fields[].key: "fastly_is_shield"
additional.fields[].value.bool_value: connection.fastly_is_shield
O valor connection.fastly_is_shield é usado para preencher a matriz additional.fields com uma chave de "fastly_is_shield" e o valor do campo connection.fastly_is_shield.
connection.request_tls_version network.tls.version: connection.request_tls_version O campo connection.request_tls_version está mapeado para network.tls.version.
fastly.server target.hostname: fastly.server O campo fastly.server está mapeado para target.hostname.
fastly.service_id additional.fields[].key: "service_id"
additional.fields[].value.string_value: fastly.service_id
O valor fastly.service_id é usado para preencher a matriz additional.fields com uma chave de "service_id" e o valor do campo fastly.service_id.
geo.city principal.location.city: geo.city O campo geo.city está mapeado para principal.location.city.
geo.country principal.location.country_or_region: geo.country O campo geo.country está mapeado para principal.location.country_or_region.
geo.location principal.location.region_latitude: extraído de geo.location
principal.location.region_longitude: extraído de geo.location
A latitude e a longitude são extraídas do campo geo.location através de uma expressão regular e mapeadas para principal.location.region_latitude e principal.location.region_longitude, respetivamente.
geo.region principal.location.state: geo.region O campo geo.region está mapeado para principal.location.state.
host principal.hostname: host O campo host está mapeado para principal.hostname.
request_headers.accept_charset additional.fields[].key: "accept_charset"
additional.fields[].value.string_value: request_headers.accept_charset
O valor request_headers.accept_charset é usado para preencher a matriz additional.fields com uma chave de "accept_charset" e o valor do campo request_headers.accept_charset.
request_headers.accept_language additional.fields[].key: "accept_language"
additional.fields[].value.string_value: request_headers.accept_language
O valor request_headers.accept_language é usado para preencher a matriz additional.fields com uma chave de "accept_language" e o valor do campo request_headers.accept_language.
request_headers.referer network.http.referral_url: request_headers.referer O campo request_headers.referer está mapeado para network.http.referral_url.
request_headers.user_agent network.http.user_agent: request_headers.user_agent O campo request_headers.user_agent está mapeado para network.http.user_agent.
request_id metadata.product_log_id: request_id O campo request_id está mapeado para metadata.product_log_id.
request_method network.http.method: request_method O campo request_method está mapeado para network.http.method.
response_headers.cache_control additional.fields[].key: "cache_control"
additional.fields[].value.string_value: response_headers.cache_control
O valor response_headers.cache_control é usado para preencher a matriz additional.fields com uma chave de "cache_control" e o valor do campo response_headers.cache_control.
response_headers.content_type additional.fields[].key: "content_type"
additional.fields[].value.string_value: response_headers.content_type
O valor response_headers.content_type é usado para preencher a matriz additional.fields com uma chave de "content_type" e o valor do campo response_headers.content_type.
response_state additional.fields[].key: "response_state"
additional.fields[].value.string_value: response_state
O valor response_state é usado para preencher a matriz additional.fields com uma chave de "response_state" e o valor do campo response_state.
response_status network.http.response_code: response_status O campo response_status é mapeado para network.http.response_code se o campo status estiver vazio.
rule_id security_result.rule_id: rule_id Se waf.rule_id estiver vazio, o valor de rule_id é usado para preencher security_result.rule_id.
severity waf.severity: severity O valor do campo severity é copiado para waf.severity.
size_bytes.request_header network.sent_bytes: size_bytes.request_header O campo size_bytes.request_header está mapeado para network.sent_bytes.
size_bytes.response_header network.received_bytes: size_bytes.response_header O campo size_bytes.response_header está mapeado para network.received_bytes.
status network.http.response_code: status O campo status está mapeado para network.http.response_code.
timestamp metadata.event_timestamp: timestamp O campo timestamp é analisado e mapeado para metadata.event_timestamp.
url target.url: url O campo url está mapeado para target.url.
waf.blocked security_result.action: derivada Se waf.blocked for falso, security_result.action é definido como "ALLOW". Se waf.blocked for verdadeiro, security_result.action é definido como "BLOCK".
waf.executed security_result.detection_fields[].key: "executed"
security_result.detection_fields[].value: waf.executed
O valor waf.executed é usado para preencher a matriz security_result.detection_fields com uma chave de "executed" e o valor do campo waf.executed.
waf.failures security_result.detection_fields[].key: "failures"
security_result.detection_fields[].value: waf.failures
O valor de waf.failures é usado para preencher a matriz security_result.detection_fields com uma chave de "falhas" e o valor do campo waf.failures.
waf.logged security_result.detection_fields[].key: "logged"
security_result.detection_fields[].value: waf.logged
O valor waf.logged é usado para preencher a matriz security_result.detection_fields com uma chave de "logged" e o valor do campo waf.logged.
waf.message metadata.description: waf.message Se waf.message não estiver vazio, é mapeado para metadata.description.
waf.rule_id security_result.rule_id: waf.rule_id Se waf.rule_id não estiver vazio, é mapeado para security_result.rule_id.
waf.score.anomaly security_result.detection_fields[].key: "anomaly"
security_result.detection_fields[].value: waf.score.anomaly
Se waf.score.anomaly não for 0 nem estiver vazio, o valor é usado para preencher a matriz security_result.detection_fields com uma chave de "anomalia" e o valor do campo waf.score.anomaly.
waf.score.http_violation security_result.detection_fields[].key: "http_violation"
security_result.detection_fields[].value: waf.score.http_violation
Se waf.score.http_violation não for 0 nem estiver vazio, o valor é usado para preencher a matriz security_result.detection_fields.
waf.score.lfi security_result.detection_fields[].key: "lfi"
security_result.detection_fields[].value: waf.score.lfi
Lógica semelhante à 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 semelhante à de waf.score.http_violation.
waf.score.rce security_result.detection_fields[].key: "rce"
security_result.detection_fields[].value: waf.score.rce
Lógica semelhante à de waf.score.http_violation.
waf.score.rfi security_result.detection_fields[].key: "rfi"
security_result.detection_fields[].value: waf.score.rfi
Lógica semelhante à 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 semelhante à 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 semelhante à de waf.score.http_violation.
waf.score.xss security_result.detection_fields[].key: "xss"
security_result.detection_fields[].value: waf.score.xss
Lógica semelhante à de waf.score.http_violation.
waf.severity security_result.severity: derived
security_result.severity_details: waf.severity
Se waf.severity não estiver vazio, determina o valor de security_result.severity com base nos intervalos (<=3: HIGH, >3 e <=6: MEDIUM, >6 e <=8: LOW, caso contrário: UNKNOWN_SEVERITY). O valor waf.severity original também está mapeado para security_result.severity_details.
waf_message metadata.description: waf_message Se waf.message estiver vazio e waf_message não estiver vazio, é mapeado para metadata.description. Se client_ip ou host e fastly.server não estiverem vazios, metadata.event_type é definido como "NETWORK_HTTP". Caso contrário, se client_ip ou host não estiverem vazios, metadata.event_type é definido como "STATUS_UPDATE". Caso contrário, é definido como "GENERIC_EVENT". Valor codificado. Valor codificado. Valor codificado.

Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais da Google SecOps.