Referência do analisador
Beta
O Lakewatch está em Beta. Os administradores do Workspace podem controlar o acesso a esse recurso na página Pré-visualizações . Consulte Gerenciar prévias do nível do workspace.
Um parser é um documento YAML que descreve as colunas de saída de uma fonte de log de segurança. Um parser tem versão e está armazenado em um catálogo e esquema do Unity Catalog. A edição de um parser adiciona uma nova versão imutável, portanto, uma fonte de dados que pin uma versão não é afetada por edições posteriores. Esta página descreve a sintaxe de parser que o Lakewatch aceita.
Estrutura de documentos
description: Product audit events # what this log source is
fields:
- name: event_name
type: STRING
required: true
validate:
in: ['sale', 'buy']
- name: source_ip
type: STRING
observables: [ip]
- name: actor
type: VARIANT
fields:
- name: id
type: STRING
observables: [actor_id]
time:
coalesce:
- path: published
time_formats: ['#rfc3339']
Você pode fornecer description no YAML conforme mostrado aqui ou configurá-lo na IU quando criar o analisador (recomendado).
Tempo do evento
Cada analisador produz uma coluna time: o Timestamp do evento em que os clusters Lakewatch se agrupam. Você deve defini-lo com um bloco time de nível superior em vez de um campo em fields. Um analisador personalizado sem um será rejeitado. Como o Lakewatch produz a coluna time para cada analisador como um TIMESTAMP, você não define seu name, type ou required. Não adicione um campo time a fields: o nome é reservado para a coluna que o bloco time de nível superior produz, e um analisador que o declara como um campo é rejeitado.
O bloco time de nível superior assume uma lista coalesce: uma lista priorizada de origens que o Lakewatch avalia em ordem, usando o primeiro valor não nulo. Se todas as origens forem nulas, o Lakewatch retorna ao horário de ingestão e define lw_meta.missing_timestamp como true. Cada origem é uma das seguintes:
-
Caminho : Leia o valor de um local de origem:
YAMLtime:coalesce:- path: publishedtime_formats: ['#rfc3339'] -
Caminho com uma expressão regular : extraia o valor de um local de origem com uma regex:
YAMLtime:coalesce:- path: raw_messageregexp: '<pattern>'match_group_index: 1 # which capture group holds the value; defaults to 1time_formats: ['#unix']
time_formats usa o mesmo formato de conjuntos e padrões que um campo TIMESTAMP. Consulte Timestamp.
Como time não é um campo, ele não é usado na classificação. Para exigir que o campo de tempo do evento de origem esteja presente para que um evento corresponda, adicione-o como um campo required em fields.
Atributos de campo
Atributo | Aplica-se a | Descrição |
|---|---|---|
| Todos os campos | Nome da coluna de saída. Também a key de origem default, a menos que |
| Todos os campos | Tipo de coluna de saída. Consulte Tipos compatíveis. |
| Todos os campos | Se |
| Todos os campos | Local de origem de onde ler o valor, quando difere de |
| Todos os campos | Descrição do campo, exibida para ajudar você a escrever regras de detecção. |
|
| Lista de formatos para analisar o Timestamp. Consulte Timestamp. |
|
| Um validador único. Consulte Validadores. |
|
| Um ou mais tipos observáveis a extrair. Consulte Observáveis. |
|
| Regras de correspondência de key para extrair observáveis de conteúdo aninhado. Consulte Verificar observáveis. |
|
| Definições de campo aninhadas. Um |
|
| Defina como |
|
| A definição de elemento da matriz. |
Tipos compatíveis
STRING, BOOLEAN, TINYINT (BYTE), SMALLINT (SHORT), INT (INTEGER), BIGINT (LONG), FLOAT (REAL), DOUBLE, DECIMAL(p,s), TIMESTAMP, TIMESTAMP_LTZ, TIMESTAMP_NTZ, DATE, BINARY, VARIANT, STRUCT e ARRAY.
Apenas os tipos listados acima são compatíveis. Para modelar objetos aninhados, use VARIANT com fields interno. Um VARIANT tolera campos adicionais e não declarados sem quebrar o analisador.
Escolha entre STRUCT e VARIANT
STRUCT e VARIANT modelam dados aninhados, mas fazem concessões opostas. Um STRUCT declara a forma antecipadamente: você lista seus membros e seus tipos, e a coluna analisada contém exatamente o que você declara. Um VARIANT mantém o valor bruto e semiestruturado inteiro, e você o lê por caminho no momento da query, por exemplo, com try_variant_get. Você ainda pode declarar fields sob um VARIANT, mas isso apenas anexa validação e observáveis a esses caminhos. Ele não descarta o restante do valor.
Use STRUCT quando você conhece a forma e deseja um contrato tipado e estável:
- A forma reside na especificação do analisador, por isso é versionada e revisada. Queries, detecções e painéis leem cada membro como um tipo conhecido e não quebram quando os dados de origem mudam.
- As leituras são mais baratas. Uma
STRUCTé uma coluna tipada real que você acessa com notação de ponto e que o Spark pode podar, enquanto umaVARIANTé decodificada em cada leitura. - O custo é a rigidez: tudo o que você não declara é descartado, e você deve atualizar o analisador quando o formato muda.
Use VARIANT quando a forma for desconhecida, evolutiva ou grande demais para ser modelada campo a campo:
- Ele acompanha as mudanças de esquema por conta própria. Fontes como AWS CloudTrail e Okta adicionam campos sem alterações no analisador.
- Ele lida com formatos mistos ou conflitantes, como um caminho que é um objeto em um evento e uma strings em outro, que um único tipo
STRUCTnão pode representar. - Ele preserva o payload original para posterior reprocessamento, para que você possa gravar os dados primeiro e modelá-los depois.
- Ele escala para payloads com centenas de campos sem precisar declarar cada um.
- O custo é que você não tem tipagem ou validação na ingestão, e você paga para extrair campos em cada query. Um padrão comum é promover os poucos campos que você query mais para campos tipados.
Timestamp
Um campo TIMESTAMP é analisado com os formatos listados em time_formats, tentados em ordem, usando parse_timestamp. Cada entrada é uma palavra-chave de formato predefinida ou um padrão literal de data/hora do Spark:
Entrada | Significado |
|---|---|
| A família RFC 3339. |
| Outras palavras-chave de formato predefinidas. |
| Um timestamp numérico da época Unix em segundos, microssegundos ou nanossegundos. Os valores de milissegundos não são detectados. |
| Um padrão literal. |
Liste os formatos que o log realmente usa para que a análise não seja excessivamente permissiva.
Validadores
Um validador afirma uma condição em um campo STRING. Use exatamente uma das seguintes opções:
Validador | Verdadeiro quando |
|---|---|
| O valor é uma das strings listadas. |
| O valor não é uma das strings listadas. |
| O valor contém pelo menos uma substring listada. |
| O valor não contém nenhuma das substrings listadas. |
Observáveis
Marcar um campo com observables extrai seu valor para a coluna lw_observables compartilhada para busca de ameaças. Cada tipo observável captura um tipo específico de valor e preenche um ou mais campos em lw_observables:
Observável | Capturas | Preenche em |
|---|---|---|
| Endereços IPv4 ou IPv6 |
|
| Nomes de domínio |
|
| Hostnames ou endereços IP quando o valor é um IP |
|
| O host de uma URL (um hostname ou endereço IP) |
|
| Hashes MD5, SHA-1 e SHA-256 |
|
| Um ARN da AWS, mais o ID da account, o ID da instância, o email e o nome de usuário que ele contém |
|
| Um ID de account AWS de 12 dígitos |
|
| Um ID de instância EC2 |
|
| Um ID de solicitação ou rastreamento |
|
| Um nome de usuário |
|
| Um endereço de email e a parte de nome de usuário dele |
|
| O host de um valor |
|
| Um endereço MAC |
|
| Um ID de ator |
|
| Um número de série |
|
| Um identificador CVE, como |
|
| Uma tag de recurso |
|
| Um ID de técnica MITRE ATT&CK, como |
|
lw_observables é uma coluna STRUCT gerenciada pelo Lakewatch adicionada a cada tabela analisada, com um campo ARRAY<STRING> por tipo observável. O Lakewatch normaliza, deduplica e classifica os valores de cada campo e ignora os inválidos. Um campo sem valores é []. A coluna está presente em todos os eventos, mesmo quando o parser declara que não há observáveis.
Escanear em busca de observáveis
Use o atributo opcional scan_for_observables em um campo VARIANT para extrair observáveis de keys em qualquer lugar do valor aninhado, incluindo conteúdo não declarado em fields. O atributo não é válido em outros tipos de campo.
Mapeie cada tipo observável que você deseja extrair para um objeto matcher explícito. Um matcher pode usar equals, ends_with e contains. Cada key aceita uma matriz de strings de nomes de key. A correspondência de key não diferencia maiúsculas de minúsculas.
- name: request
type: VARIANT
scan_for_observables:
ip:
equals: [sourceIp, destinationIp]
ends_with: [IpAddress]
contains: [clientIp]
email:
equals: [principalEmail]
ends_with: [Email]
O Lakewatch examina recursivamente as keys no valor VARIANT. Quando uma key corresponde a uma regra configurada, o Lakewatch valida o valor candidato para esse tipo observável e adiciona valores válidos ao campo correspondente em lw_observables. A correspondência usa apenas as regras no parser. O Lakewatch não adiciona regras de correspondência integradas.
Campos aninhados e array
Use VARIANT com fields para objetos aninhados e ARRAY com element para listas. Um elemento é definido como um campo, mas sem name, required ou path:
- name: resources
type: ARRAY
path: resources
element:
type: VARIANT
fields:
- name: accountId
type: STRING
observables: [aws_account_id]
- name: source_ips
type: ARRAY
path: sourceIps
element:
type: STRING
observables: [ip]
Classificação
Uma fonte de dados pode ter vários analisadores anexados e cada analisador grava em sua própria tabela analisada. O Lakewatch corresponde a cada evento de entrada com os analisadores na ordem em que são declarados. O evento cai no primeiro analisador correspondente, portanto, cada evento é gravado em no máximo uma tabela analisada. Um evento corresponde quando seus campos obrigatórios estão presentes, seus campos digitados são convertidos para os tipos declarados e todos os validadores são aprovados. Eventos sem correspondência são encaminhados para um sentinela de letra morta em vez de falhar no pipeline.
As definições do parser decidem quais eventos cada parser recebe, portanto, você não configura filtros na fonte de dados. Para rotear um tipo de evento para um parser, marque os campos que identificam esse tipo de evento como required no parser. Se outros tipos de eventos compartilharem esses campos, adicione um validador que os diferencia. Como o primeiro parser correspondente vence, ordene parsers mais específicos antes dos mais gerais na fonte de dados.
Analisadores integrados e personalizados
O Lakewatch fornece parsers integrados para fontes de logs de segurança comuns, e você pode criar parsers personalizados para fontes que não são cobertas ou que você deseja personalizar. Ambos usam o formato YAML descrito acima.
Descubra e inspecione analisadores integrados
Ao anexar analisadores a uma fonte de dados, você pode navegar pelos analisadores integrados disponíveis e selecionar os que correspondem à sua fonte. Inspecione um analisador integrado para ver as colunas que ele produz (seus campos, tipos, validadores e observáveis) antes de anexá-lo, para que você possa confirmar se ele corresponde aos eventos que está ingerindo.
Analisadores integrados são apenas de leitura. Para personalizar um, use a ação Clonar no analisador para criar um analisador personalizado editável com base na definição do analisador integrado, em seguida, ajuste-o e salve-o. A clonagem é uma conveniência da IU que copia a definição para um novo analisador personalizado (versão 1). Não se trata de uma operação de clone do lado do servidor e o analisador integrado não foi alterado.
Criar um analisador personalizado
Para criar um analisador personalizado, forneça um documento YAML no formato descrito acima e salve-o em um catálogo e esquema do Unity Catalog. Criar um analisador armazena a definição como versão 1 e registra você como o proprietário do analisador.
Defina seus campos com cuidado, porque um evento que não corresponde a nenhum analisador é encaminhado para um sentinela de dead-letter em vez de falhar na pipeline. Um evento cujos valores não convertem para os tipos declarados, ou que falha em um validador, não corresponderá ao analisador.
Versão e exclusão
Editar um parser adiciona uma nova versão imutável. As versões existentes não mudam e os números de versão não são reutilizados. O servidor atribui a cada nova versão o próximo número em sequência. Apenas o proprietário do parser pode adicionar uma versão.
Uma fonte de dados pin uma versão específica, para que continue usando essa versão até que você a altere explicitamente. Consulte Alterar a versão de um analisador.
Você pode excluir um parser personalizado inteiro, o que remove todas as suas versões. Você não pode excluir uma versão individual. Somente o proprietário pode excluir um parser, e a exclusão é bloqueada enquanto qualquer fonte de dados fizer referência a qualquer versão do parser. Antes de excluir, desanexe o parser de cada fonte de dados que o utiliza (altere cada fonte de dados para um parser diferente e salve a alteração) e, em seguida, exclua o parser.
Limites
Um documento de analisador tem no máximo 256 KiB, e um analisador pode declarar no máximo 512 campos. A contagem inclui membros VARIANT e STRUCT aninhados e elementos ARRAY.
Os nomes dos campos de nível superior devem ser exclusivos independentemente de maiúsculas e minúsculas e não podem usar os nomes reservados time, lw_id, lw_meta ou lw_observables. Os nomes dos membros em um STRUCT também devem ser exclusivos, independentemente de maiúsculas e minúsculas.