Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Importante
Lakewatch è in anteprima privata. Per richiedere l'accesso, contatta il team del tuo account Azure Databricks.
Un parser è un documento YAML che descrive le colonne di output di una sorgente di log di sicurezza. Un parser viene versionato e memorizzato in un catalogo e schema del Catalogo Unity; modificare un parser aggiunge una nuova versione immutabile, così che una sorgente di dati che pina una versione non è influenzata dalle modifiche successive. Questa pagina descrive la sintassi del parser che Lakewatch accetta.
Struttura del documento
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']
Puoi fornire description nel YAML come mostrato qui, oppure impostarlo nell'interfaccia utente quando crei il parser (consigliato).
Ora dell'evento
Ogni parser produce una time colonna: il timestamp dell'evento su cui Lakewatch si concentra. Devi definirlo con un blocco di time livello superiore invece che con un campo in fields; un parser personalizzato senza uno viene rifiutato. Poiché Lakewatch produce sempre la time colonna ed è sempre un TIMESTAMP, non imposti il suo name, type, o required. Non aggiungere un time campo a fields: il nome è riservato alla colonna che il blocco di time livello superiore produce, e un parser che lo dichiara come campo viene rifiutato.
Il blocco di livello superiore time prende una coalesce lista: una lista prioritaria di fonti che Lakewatch valuta in ordine, utilizzando il primo valore non nullo. Se ogni sorgente è nulla, Lakewatch torna al tempo di ingestione e imposta lw_meta.missing_timestamp a true. Ogni fonte è una delle seguenti:
Path: leggi il valore da una posizione di origine:
time: coalesce: - path: published time_formats: ['#rfc3339']Percorso con espressione regolare: estrarre il valore da una posizione sorgente con un regex:
time: coalesce: - path: raw_message regexp: '<pattern>' match_group_index: 1 # which capture group holds the value; defaults to 1 time_formats: ['#unix']
time_formats utilizza gli stessi set di formato e pattern di un TIMESTAMP campo. Vedi Timestamps.
Poiché time non è un campo, non viene usato nella classificazione. Per richiedere che il campo di tempo di evento di origine sia presente affinché un evento corrisponda, aggiungilo come required campo in fields.
Attributi di campo
| Attribute | Si applica a | Description |
|---|---|---|
name |
Tutti i campi | Nome della colonna di uscita. Anche la chiave sorgente predefinita, a meno che path non sia impostata. |
type |
Tutti i campi | Tipo di colonna di uscita. Vedi Tipi supportati. |
required |
Tutti i campi | Se true, il campo deve essere presente affinché un evento corrisponda a questo parser. Di default è false. |
path |
Tutti i campi | Posizione della sorgente da cui leggere il valore, quando differisce da name, come published o actor.id. |
comment |
Tutti i campi | Descrizione del campo, emersa per aiutarti a scrivere regole di rilevamento. |
time_formats |
TIMESTAMP tipi |
Elenco dei formati con cui analizzare il timestamp. Vedi Timestamps. |
validate |
STRING |
Un singolo validatore. Vedi Validatori. |
observables |
STRING |
Uno o più tipi osservabili da estrarre. Vedi Osservabili. |
scan_for_observables |
VARIANT |
Regole di abbinamento delle chiavi per estrarre osservabili da contenuti annidati. Vedi Scansione per osservabili. |
fields |
VARIANT |
Definizioni di campi annidati. |
element |
ARRAY |
La definizione elementale dell'array. |
Tipi supportati
STRING, BOOLEAN, TINYINT (BYTE), SMALLINT (SHORT), INT (INTEGER), BIGINT (LONG), FLOAT ,REALDECIMAL(p,s)DOUBLE , TIMESTAMP, TIMESTAMP_LTZ, TIMESTAMP_NTZBINARYVARIANTDATE, STRUCTe .ARRAY
Sono supportati solo i tipi sopra elencati. Per modellare oggetti annidati, usare VARIANT con l'interno fields. A VARIANT tollera campi aggiuntivi non definiti senza rompere il parser.
Scegliere tra STRUCT e VARIANT
STRUCT e VARIANT entrambi modellano dati annidati, ma fanno compromessi opposti. A STRUCT dichiara la forma subito: elenchi i suoi membri e i loro tipi, e la colonna analizzata contiene esattamente ciò che dichiari. A VARIANT mantiene il valore grezzo, semi-strutturato, intero, e lo leggi per percorso al momento della query, ad esempio con try_variant_get. Puoi comunque dichiarare fields sotto un VARIANT, ma questo attribuisce solo validazione e osservabili a quei percorsi; non perde il resto del valore.
Usalo STRUCT quando conosci la forma e vuoi un contratto stabile e dattiloscritto:
- La forma rimane nella specifica del parser, quindi viene versionata e revisionata. Query, rilevamenti e dashboard leggono ogni membro come un tipo noto e non si interrompono quando i dati sorgente si spostano.
- Le letture costano meno. A
STRUCTè una vera colonna tipizzata a cui accedi con la notazione dei punti e che Spark può potare, mentre aVARIANTviene decodificata ad ogni lettura. - Il costo è la rigidità: tutto ciò che non dichiari viene eliminato, e devi aggiornare il parser quando la forma cambia.
Da usare VARIANT quando la forma è sconosciuta, in evoluzione o troppo grande per modellare campo per campo:
- Si tiene aggiornato da sola sui cambiamenti dello schema. Fonti come AWS CloudTrail e Okta aggiungono campi senza alcun cambiamento nel parser.
- Gestisce forme miste o in conflitto, come un percorso che è un oggetto in un evento e una stringa in un altro, che un singolo
STRUCTtipo non può rappresentare. - Conserva il payload originale per un riprocessamento successivo e ti permette di atterrare prima i dati e modellarli dopo.
- Scala su payload con centinaia di campi senza dichiarare ciascuno di essi.
- Il costo è che non ottieni alcuna tipizzazione o validazione all'ingest, e paghi per estrarre i campi di ogni query. Un modello comune è promuovere i pochi campi che si interrogano di più in campi tipizzati.
Timestamp
Un TIMESTAMP campo viene analizzato con i formati elencati in time_formats, provati in ordine, usando parse_timestamp. Ogni voce è o una parola chiave predefinita nel formato o un vero e proprio schema di data-time di Spark:
| Ingresso | Meaning |
|---|---|
#rfc3339 |
La famiglia RFC 3339. |
#iso8601, #common, #extended |
Altre parole chiave predefinite nel formato. |
#unix |
Un timestamp numerico Unix, in pochi secondi. I valori dei millisecondi non vengono rilevati. |
MM/dd/yyyy hh:mm:ss a |
Un vero e proprio schema. |
Elenca i formati che il log utilizza effettivamente in modo che l'analisi non sia eccessivamente permissiva.
Validatori
Un validatore afferma una condizione su un STRING campo. Usa esattamente uno dei seguenti metodi:
| Validatore | Vero quando |
|---|---|
in: [...] |
Il valore è una delle stringhe elencate. |
not_in: [...] |
Il valore non è una delle stringhe elencate. |
contains_any: [...] |
Il valore contiene almeno una sottostringa elencata. |
contains_none: [...] |
Il valore non contiene nessuna delle sottostringhe elencate. |
Oggetti osservabili
Marcare un campo con observables estrae il suo valore nella colonna condivisa lw_observables per la caccia alla minaccia. Ogni tipo osservabile cattura un tipo specifico di valore e popola uno o più campi in lw_observables:
| Osservabile | Cattura | Popola in lw_observables |
|---|---|---|
ip |
Indirizzi IPv4 o IPv6 | ip_addresses |
domain |
Nomi di dominio | hostnames |
hostname |
Nomi host o indirizzi IP quando il valore è un IP |
hostnames, ip_addresses |
url |
L'host di un URL (un nome host o IP) |
hostnames, ip_addresses |
hash |
Hash MD5, SHA-1 e SHA-256 | hashes |
aws_arn |
Un ARN AWS, più l'ID account, l'ID dell'istanza, l'email e il nome utente che contiene |
account_ids, resource_ids, emails, usernames, device_ids |
aws_account_id |
Un ID account AWS a 12 cifre | account_ids |
aws_instance_id |
Un ID di istanza EC2 | device_ids |
trace_id |
Un ID di richiesta o traccia | request_trace_ids |
username |
Un nome utente | usernames |
email |
Un indirizzo email e la parte con il nome utente |
emails, usernames |
net_addr |
L'host di un host:port valore (un nome host o IP) |
hostnames, ip_addresses |
mac |
Un indirizzo MAC | mac_addresses |
actor_id |
Un ID attore | actor_ids |
serial_number |
Un numero di serie | serial_numbers |
cve |
Un identificatore CVE, come CVE-2024-1234 |
cves |
resource_tag |
Un tag risorsa | resource_tags |
mitre_attack_technique |
Un ID tecnico MITRE ATT&CK, come T1078 |
mitre_attack_technique_ids |
lw_observables è una colonna gestita STRUCT da Lakewatch aggiunta a ogni tabella analizzata, con un ARRAY<STRING> campo per ogni tipo osservabile. Lakewatch normalizza, deduplica e ordina i valori di ogni campo e salta quelli invalidi; un campo senza valori è []. La colonna è presente in ogni evento, anche quando il parser dichiara che non è osservabile.
Scansione per osservabili
Usa l'attributo opzionale scan_for_observables su un VARIANT campo per estrarre osservabili da chiavi ovunque nel valore annidato, incluso il contenuto non dichiarato in fields. L'attributo non è valido per altri tipi di campo.
Mappare ogni tipo di osservabile che vuoi estrarre a un oggetto matcher esplicito. Un matcher può usare equals, ends_with, e contains; ogni chiave accetta un array di stringhe di nomi chiavi. L'abbinamento delle chiavi è indistinto per le maiuscole e minuscole (case by).
- name: request
type: VARIANT
scan_for_observables:
ip:
equals: [sourceIp, destinationIp]
ends_with: [IpAddress]
contains: [clientIp]
email:
equals: [principalEmail]
ends_with: [Email]
Lakewatch esamina ricorsivamente le chiavi nel VARIANT valore. Quando una chiave corrisponde a una regola configurata, Lakewatch valida il valore candidato per quel tipo osservabile e aggiunge valori validi al campo corrispondente in lw_observables. L'abbinamento utilizza solo le regole nel parser; Lakewatch non aggiunge regole di abbinamento integrate.
Campi annidati e array
Usa VARIANT con fields per oggetti annidati e ARRAY con element per liste. Un elemento è definito come un campo, ma senza name, required, o 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]
Classification
Una sorgente dati può avere diversi parser collegati. Ogni evento in arrivo viene abbinato agli analisi nell'ordine in cui viene dichiarato e si piazza nel primo parser che corrisponde. Un evento corrisponde quando sono presenti i campi richiesti, i suoi campi tipizzati si convertono nei tipi dichiarati e tutti i validatori passano il testo. Gli eventi non abbinati vengono instradati a un sentinel dead-letter invece di fallire la pipeline.
Parser integrati e personalizzati
Lakewatch fornisce parser integrati per le fonti comuni dei log di sicurezza e ti permette di creare parser personalizzati per fonti non coperte o che vuoi personalizzare. Entrambi utilizzano il formato YAML descritto sopra.
Scopri e ispeziona i parser integrati
Quando associ i parser a una sorgente dati, puoi consultare i parser integrati disponibili e selezionare quelli che corrispondono alla tua fonte. Ispeziona un parser integrato per vedere le colonne che produce (campi, tipi, validatori e osservabili) prima di allegarlo, così potrai confermare che corrisponde agli eventi che stai assumendo.
Gli parser integrati sono di sola lettura. Per personalizzarne uno, usa l'azione Clone sul parser per creare un parser personalizzato modificabile basato sulla definizione integrata del parser, poi aggiustalo e salva. Il clonaggio è una comodità dell'interfaccia utente che copia la definizione in un nuovo parser personalizzato (versione 1). Non è un'operazione clone lato server, e il parser integrato è rimasto invariato.
Autore di un parser personalizzato
Per creare un parser personalizzato, fornisci un documento YAML nel formato descritto sopra e salvalo in un catalogo e schema del Catalogo Unity. Creare un parser memorizza la definizione come versione 1 e ti registra come proprietario del parser.
Definisci attentamente i tuoi campi, perché un evento che non corrisponde a nessun parser viene instradato a un sentinel dead-letter invece di fallire la pipeline. Un evento i cui valori non si convertono nei tipi dichiarati, o che fallisce un validatore, non corrisponderà al parser.
Versioning e cancellazione
Modificare un parser aggiunge una nuova versione immutabile. Le versioni esistenti non vengono mai modificate e i numeri di versione non vengono mai riutilizzati. Il server assegna a ogni nuova versione il numero successivo in sequenza. Solo il proprietario del parser può aggiungere una versione.
Una sorgente di dati fissa una versione specifica, quindi continua a usarla finché non la cambi esplicitamente. Vedi Modifica la versione di un parser.
Puoi eliminare un intero parser personalizzato, rimuovendo così tutte le sue versioni. Non esiste un'operazione per eliminare una singola versione. Solo il proprietario può eliminare un parser, e la cancellazione viene bloccata mentre qualsiasi fonte dati fa riferimento a qualsiasi versione del parser. Prima di eliminare, stacca il parser da ogni fonte dati che lo utilizza (cambia ogni fonte con un parser diverso e salva la modifica) poi elimina il parser.
Limits
Un documento parser ha al massimo 256 KB.