Referencja do parsera

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 STRUCT to prawdziwa kolumna typowana, do której masz dostęp z notacją kropkową i którą Spark może przycinać, podczas gdy a VARIANT jest 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 STRUCT typ 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.