Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Important
Lakewatch jest w trybie Private Preview. Aby poprosić o dostęp, skontaktuj się z zespołem konta Azure Databricks.
Parser to dokument YAML opisujący kolumny wyjściowe źródła logów bezpieczeństwa. Parser jest wersjonowany i przechowywany w katalogu i schemacie Unity Catalog; edycja parsera dodaje nową, niezmienną wersję, dzięki czemu źródło danych, które przypina wersję, nie jest podatne na późniejsze edycje. Ta strona opisuje składnię parsera, którą akceptuje Lakewatch.
Struktura dokumentu
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']
Możesz podać description to w YAML, jak pokazano tutaj, albo ustawić to w interfejsie podczas tworzenia parsera (zalecane).
Czas zdarzenia
Każdy parser generuje kolumnę time : znacznik czasu zdarzenia, na którym Lakewatch się skupia. Musisz zdefiniować go za pomocą bloku najwyższego poziomu time zamiast pola w ; fieldsniestandardowy parser bez niego jest odrzucany. Ponieważ Lakewatch zawsze generuje kolumnę time i jest to zawsze , TIMESTAMPnie ustawiasz jej name, type, ani required. Nie dodawaj time pola do fields: nazwa jest zarezerwowana dla kolumny generowanej przez blok najwyższego poziomu time , a parser, który deklaruje ją jako pole, jest odrzucany.
Blok najwyższego poziomu time przyjmuje listę coalesce : priorytetową listę źródeł, którą Lakewatch ocenia w kolejności, używając pierwszej wartości niezerowej. Jeśli każde źródło jest zerowe, Lakewatch wraca do czasu pobierania i ustawia lw_meta.missing_timestamp się na .true Każde źródło jest jednym z następujących źródeł:
Ścieżka: odczyt wartości z lokalizacji źródłowej:
time: coalesce: - path: published time_formats: ['#rfc3339']Ścieżka z wyrażeniem regularnym: wyodrębnić wartość z lokalizacji źródłowej za pomocą regexu:
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 używa tych samych zestawów formatów i wzorców co TIMESTAMP pole. Zobacz znaczniki czasu.
Ponieważ time to nie jest dziedzina, nie jest używana w klasyfikacji. Aby wymagać, aby pole czasu zdarzenia źródłowe było obecne, aby zdarzenie się zgadzało, dodaj je jako required pole w .fields
Atrybuty pola
| Attribute | Dotyczy | Description |
|---|---|---|
name |
Wszystkie pola | Nazwa kolumny wyjściowej. Również domyślny klucz źródłowy, chyba że path jest ustawiony. |
type |
Wszystkie pola | Typ kolumny wyjściowej. Zobacz Obsługiwane typy. |
required |
Wszystkie pola | Jeśli true, pole musi być obecne, aby zdarzenie odpowiadało temu parserowi. Wartość domyślna to false. |
path |
Wszystkie pola | Lokalizacja źródła do odczytu wartości, gdy różni się od name, takich jak published lub actor.id. |
comment |
Wszystkie pola | Opis pola pojawił się, aby pomóc ci w pisaniu reguł wykrywania. |
time_formats |
TIMESTAMP Typy |
Lista formatów, według których można odczytać znacznik czasu. Zobacz znaczniki czasu. |
validate |
STRING |
Jeden walidator. Zobacz Walidatorzy. |
observables |
STRING |
Jeden lub więcej obserwowalnych typów do wydobycia. Zobacz Obserwables. |
scan_for_observables |
VARIANT |
Reguły dopasowywania kluczy do wyodrębniania obserwables z zagnieżdżonej zawartości. Zobacz Skanowanie dla obserwable. |
fields |
VARIANT |
Definicje pól zagnieżdżonych. |
element |
ARRAY |
Definicja elementu tablicy. |
Obsługiwane typy
STRING
BOOLEAN, , ( TINYINT ),BYTESMALLINT (SHORT), INT (INTEGER), DOUBLEREALFLOATLONGBIGINT , , TIMESTAMPDECIMAL(p,s), TIMESTAMP_NTZTIMESTAMP_LTZBINARYVARIANTDATESTRUCToraz .ARRAY
Obsługiwane są tylko wymienione powyżej typy. Aby modelować zagnieżdżone obiekty, użyj VARIANT z wewnętrznym fields. A toleruje dodatkowe, niezadeklarowane pola bez łamania VARIANT parsera.
Wybór między STRUCT a VARIANT
STRUCT
VARIANT Oba modele zagnieżdżonych danych, ale stosują przeciwne kompromisy. A STRUCT deklaruje kształt na początku: wypisujesz jego członków i ich typy, a kolumna parsowana zawiera dokładnie to, co deklarujesz. A zachowuje VARIANT surową, półstrukturalną wartość całości i wczyta się do niej ścieżką w czasie zapytania, na przykład z .try_variant_get Wciąż można deklarować fields pod , VARIANTale to przypisuje tylko walidację i obserwable do tych ścieżek; nie usuwa pozostałej wartości.
Używaj STRUCT , gdy znasz kształt i chcesz mieć stabilną, typową umowę:
- Kształt znajduje się w specyfikacji parsera, więc jest wersjonowany i recenzowany. Zapytania, detekcje i pulpity odczytują każdego członka jako znany typ i nie psują się, gdy dane źródłowe się zmieniają.
- Lektury są tańsze. A
STRUCTto prawdziwa kolumna typowana, do której masz dostęp z notacją kropkową i którą Spark może przycinać, podczas gdy aVARIANTjest dekodowana przy każdym odczytie. - Kosztem jest sztywność: wszystko, czego nie zadeklarujesz, jest usuwane, a parser musisz aktualizować, gdy zmienia się kształt.
Używaj, VARIANT gdy kształt jest nieznany, ewoluuje lub jest zbyt duży, by modelować pole po polu:
- Sam nadąża za zmianami schematu. Źródła takie jak AWS, CloudTrail i Okta dodają pola bez zmiany parsera.
- Obsługuje mieszane lub konfliktowe kształty, takie jak ścieżka będąca obiektem w jednym zdarzeniu i ciągiem znaków w innym, którego pojedynczy
STRUCTtyp nie może reprezentować. - Zachowuje oryginalny ładunek na późniejsze przetwarzanie i pozwala najpierw wylądować na danych, a potem je modelować.
- Skaluje się do ładunków z setkami pól bez deklarowania każdego z nich.
- Kosztem jest brak typowania ani weryfikacji przy ingest, a płacisz za wyodrębnianie pól przy każdym zapytaniu. Powszechnym wzorcem jest promowanie kilku pól, które najczęściej zapytujesz, do pól typowych.
Znaczniki czasu
Pole jest parsowane z formatami wymienionymi w , próbowanymi TIMESTAMP w kolejności, używając parse_timestamp.time_formats Każdy wpis jest albo wstępnie zdefiniowanym słowem kluczowym w formacie, albo dosłownym wzorcem czasu i daty w Spark:
| Wpis | Meaning |
|---|---|
#rfc3339 |
Rodzina RFC 3339. |
#iso8601, #common, #extended |
Inne słowa kluczowe w zdefiniowanym formacie. |
#unix |
Numeryczny znacznik czasu Uniksa, w sekundach. Wartości milisekund nie są wykrywane. |
MM/dd/yyyy hh:mm:ss a |
Dosłowny wzór. |
Wymień formaty, których faktycznie używa dziennik, aby parsowanie nie było zbyt liberalne.
Moduły sprawdzania poprawności
Walidator stwierdza warunek na STRING polu. Użyj dokładnie jednego z poniższych:
| Moduł sprawdzania poprawności | Prawda, gdy |
|---|---|
in: [...] |
Wartość jest jednym z wymienionych ciągów znaków. |
not_in: [...] |
Wartość nie jest jednym z wymienionych ciągów znaków. |
contains_any: [...] |
Wartość zawiera co najmniej jeden podciąg podciągu. |
contains_none: [...] |
Wartość ta nie zawiera żadnego z wymienionych podciągów. |
Obserwowane elementy
Oznaczenie pola z observables wyodrębnia jego wartość do wspólnej lw_observables kolumny do polowania na zagrożenia. Każdy typ obserwowalny przechwytuje określony rodzaj wartości i wypełnia jedno lub więcej pól w lw_observables:
| Obserwowalny | Zrzuty ekranowe | Występuje w lw_observables |
|---|---|---|
ip |
Adresy IPv4 lub IPv6 | ip_addresses |
domain |
Nazwy domen | hostnames |
hostname |
Nazwy hostów lub adresy IP, gdy wartość jest IP |
hostnames, ip_addresses |
url |
Host adresu URL (nazwa hosta lub adres IP) |
hostnames, ip_addresses |
hash |
Hashy MD5, SHA-1 i SHA-256 | hashes |
aws_arn |
AWS ARN, plus identyfikator konta, identyfikator instancji, e-mail i nazwa użytkownika, które zawiera |
account_ids, resource_ids, , emails, usernamesdevice_ids |
aws_account_id |
12-cyfrowy identyfikator konta AWS | account_ids |
aws_instance_id |
Identyfikator instancji EC2 | device_ids |
trace_id |
ID żądania lub śledzenia | request_trace_ids |
username |
Nazwa użytkownika | usernames |
email |
Adres e-mail i część dotycząca jego nazwy użytkownika |
emails, usernames |
net_addr |
Host host:port wartości (nazwy hosta lub adresu IP) |
hostnames, ip_addresses |
mac |
Adres MAC | mac_addresses |
actor_id |
Identyfikator aktora | actor_ids |
serial_number |
Numer seryjny | serial_numbers |
cve |
Identyfikator CVE, taki jak CVE-2024-1234 |
cves |
resource_tag |
Tag zasobów | resource_tags |
mitre_attack_technique |
ID techniki ATT&CK MITRY, takie jak T1078 |
mitre_attack_technique_ids |
lw_observables to kolumna zarządzana STRUCT przez Lakewatch dodawana do każdej parsowanej tabeli, z jednym ARRAY<STRING> polem na każdy typ obserwowalnej. Lakewatch normalizuje, deduplikuje i sortuje wartości każdego pola oraz pomija nieprawidłowe; pole bez wartości to []. Kolumna jest obecna przy każdym zdarzeniu, nawet gdy parser deklaruje brak obserwowalnych.
Skanowanie pod kątem obserwables
Użyj opcjonalnego atrybutu scan_for_observables na VARIANT polu, aby wyodrębnić obserwable z kluczy w dowolnym miejscu zagnieżdżonej wartości, w tym z zawartością niezadeklarowaną w fields. Atrybut ten nie jest ważny dla innych typów pól.
Przypisz każdy typ obserwacji, który chcesz wyodrębnić, na jawny obiekt dopasowania. Dopasowanie może użyć equals, ends_with, oraz contains; każdy klucz akceptuje tablicę ciągów nazw kluczy. Dopasowywanie kluczy nie jest rozróżniane na wielka litera.
- name: request
type: VARIANT
scan_for_observables:
ip:
equals: [sourceIp, destinationIp]
ends_with: [IpAddress]
contains: [clientIp]
email:
equals: [principalEmail]
ends_with: [Email]
Lakewatch rekurencyjnie bada klucze w wartości.VARIANT Gdy klucz odpowiada skonfigurowanej regułie, Lakewatch weryfikuje wartość kandydata dla tego typu obserwowalnego i dodaje poprawne wartości do odpowiadającego pola w lw_observables. Dopasowywanie wykorzystuje wyłącznie zasady parsera; Lakewatch nie dodaje wbudowanych zasad dopasowywania (match).
Pola zagnieżdżone i tablicowe
Użyj VARIANT z dla fields zagnieżdżonych obiektów i ARRAY z dla element list. Element definiuje się jak ciało, ale bez name, required, lub 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
Źródło danych może mieć dołączone kilka parserów. Każde nadchodzące zdarzenie jest dopasowywane do parserów w kolejności, w jakiej zostały zadeklarowane, i ląduje w pierwszym parserze, do którego się dopasuje. Zdarzenie odpowiada, kiedy są wymagane pola, jego typy pol konwertują na zadeklarowane typy, a wszyscy walidatory przechodzą. Niedopasowane zdarzenia są kierowane do strażnika bez oznak zamiast przeprowadzić potok do porażki.
Parsery wbudowane i niestandardowe
Lakewatch oferuje wbudowane parsery dla typowych źródeł logów bezpieczeństwa i pozwala tworzyć niestandardowe parsery dla źródeł, które nie są objęte lub które chcesz dostosować. Oba korzystają z formatu YAML opisanego powyżej.
Odkrywaj i przeglądaj wbudowane parsery
Gdy dołączasz parsery do źródła danych, możesz przeglądać dostępne wbudowane parsery i wybierać te, które odpowiadają twojemu źródłu. Sprawdź wbudowany parser, aby zobaczyć kolumny, które generuje (pola, typy, walidatory i obserwable), zanim go dołączysz, aby potwierdzić, że zgadza się z zdarzeniami, które pobierasz.
Wbudowane parsery są tylko do odczytu. Aby go spersonalizować, użyj akcji Klon na parserze, aby stworzyć edytowalny, niestandardowy parser zasiadowany z definicji wbudowanego parsera, następnie go dostosuj i zapisz. Klonowanie to wygoda interfejsu, która kopiuje definicję do nowego, niestandardowego parsera (wersja 1). To nie jest operacja klonowania po stronie serwera, a sam wbudowany parser pozostaje niezmieniony.
Autor niestandardowego parsera
Aby stworzyć niestandardowy parser, dostarcz dokument YAML w opisanym powyżej formacie i zapisz go w katalogu i schemacie Unity Catalog. Tworzenie parsera przechowuje definicję jako wersję 1 i rejestruje cię jako właściciela parsera.
Zdefiniuj swoje pola starannie, ponieważ zdarzenie pasujące do żadnego parsera jest kierowane do martwego sentinela, a nie powoduje awarię w pipeline. Zdarzenie, którego wartości nie konwertują się do zadeklarowanych typów lub które nie przechodzi przez walidatora, nie będzie pasować do parsera.
Wersjonowanie i usuwanie
Edycja parsera dodaje nową, niezmienną wersję. Istniejące wersje nigdy nie są zmieniane, a numery wersji nigdy nie są ponownie wykorzystywane. Serwer przypisuje każdej nowej wersji kolejną liczbę w kolejności. Tylko właściciel parsera może dodać wersję.
Źródło danych przypina konkretną wersję, więc używa tej wersji, dopóki nie zmienisz jej wyraźnie. Zobacz Zmień wersję parsera.
Możesz usunąć cały niestandardowy parser, co usuwa wszystkie jego wersje. Nie ma operacji usunięcia pojedynczej wersji. Tylko właściciel może usunąć parser, a usuwanie jest blokowane, dopóki jakiekolwiek źródło danych odwołuje się do dowolnej wersji parsera. Przed usunięciem odłącz parser od wszystkich źródeł danych, które go używają (zmień każde źródło na inny parser i zapisz zmianę), a następnie usuń parser.
Limity
Dokument parsera ma maksymalnie 256 KB.