Coletar registros do WAF do Fastly
Visão geral
Esse analisador extrai campos dos registros JSON do WAF do Fastly, transforma e renomeia esses campos e os mapeia para o UDM. Ele processa vários tipos de dados, converte níveis de gravidade e categoriza eventos com base nas informações disponíveis de IP e nome do host. Ele também lida com possíveis falhas de análise e descarta entradas de registro malformadas.
Antes de começar
Verifique se você atende aos seguintes pré-requisitos:
- Instância do Google SecOps.
- Conta da Fastly com acesso para configurar as definições do WAF.
Configurar feeds
Há dois pontos de entrada diferentes para configurar feeds na plataforma do Google SecOps:
- Configurações do SIEM > Feeds
- Central de conteúdo > Pacotes de conteúdo
Configure feeds em "Configurações do SIEM" > "Feeds".
Para configurar um feed, siga estas etapas:
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Na próxima página, clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo, Registros do WAF do Fastly).
- Selecione Webhook como o Tipo de origem.
- Selecione Fastly WAF como o Tipo de registro.
- Clique em Próxima.
- Opcional: especifique valores para os seguintes parâmetros de entrada:
- Delimitador de divisão: o delimitador usado para separar linhas de registro, como
\n
.
- Delimitador de divisão: o delimitador usado para separar linhas de registro, como
- Clique em Próxima.
- Revise a configuração do feed na tela Finalizar e clique em Enviar.
- Clique em Gerar chave secreta para autenticar o feed.
- Copie e armazene a chave secreta. Não é possível ver essa chave secreta novamente. Se necessário, você pode gerar uma nova chave secreta, mas isso torna a anterior obsoleta.
- Na guia Detalhes, copie o URL do endpoint do feed no campo Informações do endpoint. É necessário especificar esse URL de endpoint no aplicativo cliente.
- Clique em Concluído.
Configurar feeds na Central de conteúdo
Especifique valores para os seguintes campos:
- Delimitador de divisão: o delimitador usado para separar linhas de registro, como
\n
.
Opções avançadas
- Nome do feed: um valor pré-preenchido que identifica o feed.
- Tipo de origem: método usado para coletar registros no Google SecOps.
- Namespace do recurso: namespace associado ao feed.
Rótulos de ingestão: rótulos aplicados a todos os eventos deste feed.
Clique em Gerar chave secreta para autenticar o feed.
Copie e armazene a chave secreta. Não é possível ver essa chave secreta novamente. Se necessário, você pode gerar uma nova chave secreta, mas isso torna a anterior obsoleta.
Na guia Detalhes, copie o URL do endpoint do feed no campo Informações do endpoint. É necessário especificar esse URL de endpoint no aplicativo cliente.
Criar uma chave de API para o feed de webhook
Acesse console doGoogle Cloud > Credenciais.
Clique em Criar credenciais e, em seguida, selecione Chave de API.
Restrinja o acesso da chave de API à API Google Security Operations.
Especifique o URL do endpoint
- No aplicativo cliente, especifique o URL do endpoint HTTPS fornecido no feed do webhook.
Ative a autenticação especificando a chave de 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 de API como um cabeçalho em vez de no URL.
Se o cliente de webhook não aceitar cabeçalhos personalizados, especifique a chave de API e a chave secreta usando parâmetros de consulta no seguinte formato:
ENDPOINT_URL?key=API_KEY&secret=SECRET
Substitua:
ENDPOINT_URL
: o URL do endpoint do feed.API_KEY
: a chave de API para autenticar no Google Security Operations.SECRET
: a chave secreta gerada para autenticar o feed.
Configurar webhook no Fastly
- Faça login no Fastly.
- Opcional: selecione um site no menu Sites (se você tiver mais de um).
- Selecione Gerenciar > Integrações do site.
- Clique em Adicionar integração do site.
- Selecione Webhook genérico.
- URL do webhook: insira o ENDPOINT_URL do Google SecOps, seguido por API_KEY e SECRET.
- Posicionamento do alerta: selecione Toda a atividade ou Atividade específica.
- Opcional: se você selecionou Atividade específica, acesse o menu "Atividade" e selecione os tipos de atividade que você quer que o webhook envie.
- Clique em Criar integração de site.
Tabela de mapeamento do UDM
Campo de registro | Mapeamento do 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 será usado para preencher a matriz security_result.detection_fields com uma chave "anomaly" 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 "cache_status" e o valor do campo cache_status . |
client_ip |
principal.ip : client_ip |
O campo client_ip é 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 "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 "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 é mapeado para network.tls.version . |
fastly.server |
target.hostname : fastly.server |
O campo fastly.server é 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 "service_id" e o valor do campo fastly.service_id . |
geo.city |
principal.location.city : geo.city |
O campo geo.city é mapeado para principal.location.city . |
geo.country |
principal.location.country_or_region : geo.country |
O campo geo.country é 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 usando uma expressão regular e mapeadas para principal.location.region_latitude e principal.location.region_longitude , respectivamente. |
geo.region |
principal.location.state : geo.region |
O campo geo.region é mapeado para principal.location.state . |
host |
principal.hostname : host |
O campo host é 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 "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 "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 é mapeado para network.http.referral_url . |
request_headers.user_agent |
network.http.user_agent : request_headers.user_agent |
O campo request_headers.user_agent é mapeado para network.http.user_agent . |
request_id |
metadata.product_log_id : request_id |
O campo request_id é mapeado para metadata.product_log_id . |
request_method |
network.http.method : request_method |
O campo request_method é 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 "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 "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 "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 será 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 é mapeado para network.sent_bytes . |
size_bytes.response_header |
network.received_bytes : size_bytes.response_header |
O campo size_bytes.response_header é mapeado para network.received_bytes . |
status |
network.http.response_code : status |
O campo status é 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 é mapeado para target.url . |
waf.blocked |
security_result.action : derivado |
Se waf.blocked for "false", security_result.action será definido como "ALLOW". Se waf.blocked for verdadeiro, security_result.action será 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 "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 waf.failures é usado para preencher a matriz security_result.detection_fields com uma chave "failures" 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 "logged" e o valor do campo waf.logged . |
waf.message |
metadata.description : waf.message |
Se waf.message não estiver vazio, ele será mapeado para metadata.description . |
waf.rule_id |
security_result.rule_id : waf.rule_id |
Se waf.rule_id não estiver vazio, ele será 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 será usado para preencher a matriz security_result.detection_fields com uma chave "anomaly" 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 será 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 a 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 a waf.score.http_violation . |
waf.score.rce |
security_result.detection_fields[].key : "rce"security_result.detection_fields[].value : waf.score.rce |
Lógica semelhante a waf.score.http_violation . |
waf.score.rfi |
security_result.detection_fields[].key : "rfi"security_result.detection_fields[].value : waf.score.rfi |
Lógica semelhante a 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 a 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 a waf.score.http_violation . |
waf.score.xss |
security_result.detection_fields[].key : "xss"security_result.detection_fields[].value : waf.score.xss |
Lógica semelhante a waf.score.http_violation . |
waf.severity |
security_result.severity : derivedsecurity_result.severity_details : waf.severity |
Se waf.severity não estiver vazio, ele vai determinar o valor de security_result.severity com base em intervalos (<=3: HIGH, >3 e <=6: MEDIUM, >6 e <=8: LOW, else: UNKNOWN_SEVERITY). O valor original waf.severity também é mapeado para security_result.severity_details . |
waf_message |
metadata.description : waf_message |
Se waf.message estiver vazio e waf_message não estiver, ele será mapeado para metadata.description . Se client_ip ou host e fastly.server não estiverem vazios, metadata.event_type será definido como "NETWORK_HTTP". Caso contrário, se client_ip ou host não estiverem vazios, metadata.event_type será definido como "STATUS_UPDATE". Caso contrário, será definido como "GENERIC_EVENT". Valor codificado. Valor codificado. Valor codificado. |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.