Přeskočit obsah

Úvod

Syslog je široce používaný standard pro zaznamenávání zpráv v počítačových systémech, síťových zařízeních a aplikacích. Umožňuje sběr, ukládání a analýzu logových zpráv z různých zdrojů, což poskytuje cenné informace pro monitorování, odstraňování problémů a analýzu bezpečnosti.

Existují dva hlavní typy syslog protokolů:

  • Syslog RFC3164: Dědičná varianta syslog protokolu, často označovaná jako BSD syslog. Jeho formát zprávy je popsán v RFC3164, sekce 4.
  • Syslog RFC5424: Standardizovaná a strukturovanější varianta, popsaná v RFC5424, sekce 6. Zavádí další pole a vylepšenou strukturu zprávy.

Porozumění rozdílům mezi těmito protokoly je nezbytné pro přesné parsování a normalizaci syslog událostí.

  • Syslog RFC3164: Dědičná varianta syslog protokolu. Formát zprávy je popsán v RFC3164, sekce 4.
  • Syslog RFC5424: Standardizovaná varianta syslog protokolu. Formát zprávy je popsán v RFC5424, sekce 6.

Syslog RFC3164

Událost ve formátu RFC3164 typicky sestává z následujících částí:

Syslog hlavičky Syslog hlavičky

  • priorita (PRI část): Číslo uzavřené v "<>" závorkách, které označuje zařízení a závažnost logu.
  • časová značka: Místní čas ve formátu Mmm dd hh:mm:ss (např. Jan 17 12:10:03). Časové pásmo by mělo být nastaveno na UTC.
  • hostname: Název zařízení, které událost vyprodukovalo.
  • proces: Identifikátor procesu, který událost vyprodukoval. Může obsahovat PID v hranatých závorkách.
  • zpráva: Část zprávy události.

Parsování hlavičky

Následující deklarace parseru rozděluje zprávu RFC3164 na její komponenty:

10_parser.yaml
---
define:
  type: parsec/parser

parse:
  !PARSE.KVLIST
  - "<"
  - PRI: !PARSE.DIGITS
  - ">"
  - TIMESTAMP: !PARSE.DATETIME RFC3164
  - !PARSE.SPACES
  - HOSTNAME: !PARSE.UNTIL " "
  - PROCESS: !PARSE.UNTIL " "
  - !PARSE.OPTIONAL { what: !PARSE.SPACES }
  - MESSAGE: !PARSE.CHARS

Parsování procesu

Pole procesu se skládá z názvu procesu a PID. V současnosti následující vstup:

<38>Sep 3 13:38:07 host01 systemd-logind[1078]: New session 49 of user harrypotter

produkuje výstup:

"PROCESS": "systemd-logind[1078]:"

Abychom správně rozdělili pole PROCESS na PROCESS.NAME a PROCESS.PID, potřebujeme druhý parser pro všechny případy:

20_parser_process.yaml
---
define:
  type: parsec/parser
  field: PROCESS

parse:
  !TRY  #(1)

  - !PARSE.KVLIST  #(2)
    - PROCESS.NAME: !PARSE.UNTIL "["
    - PROCESS.PID: !PARSE.UNTIL "]"
    - !PARSE.OPTIONAL { what: !PARSE.EXACTLY ":" }

  - !PARSE.KVLIST  #(3)
    - PROCESS.NAME: !PARSE.UNTIL ":"

  - !PARSE.KVLIST  #(4)
    - PROCESS.NAME: !PARSE.CHARS
  1. Výraz !TRY přijímá seznam výrazů jako argument. Pokyny parseru pokračovat s prvním prvkem. Pokud tento výraz selže, pokračuje druhým, poté třetím atd.
  2. Tato větev se zabývá vstupy ve formátu PROCESS.NAME[PROCESS.PID] (např. cron[123]).
  3. Tato větev se zabývá vstupy ve formátu PROCESS.NAME: (např. sudo:).
  4. Tato větev se zabývá vstupy ve formátu PROCESS.NAME, bez : na konci (např. sudo).

Mapování na ECS schéma

Po proscanování celého logu vypadá výstup takto:

PRI: 38
TIMESTAMP: Sep 3 13:38:07
HOSTNAME: host01
PROCESS.NAME: systemd-logind
PROCESS.PID: 1078
MESSAGE: New session 49 of user harrypotter

Další fází je mapování na ECS schéma:

30_mapping_ECS.yaml
---
define:
  type: parsec/mapping
  schema: /Schemas/ECS.yaml

mapping:
  PRI: log.syslog.priority
  TIMESTAMP: "@timestamp"
  HOSTNAME: host.hostname
  PROCESS.NAME: process.name
  PROCESS.PID: process.pid
  MESSAGE: message

Po mapování vypadá výstup takto:

log.syslog.priority: 38
@timestamp: Sep 3 13:38:07
host.hostname: host01
process.name: systemd-logind
process.pid: 1078
message: New session 49 of user harrypotter

Obohacení závažnosti a zařízení syslogu

Zařízení a závažnost syslogu lze vypočítat z priority následujícím způsobem:

PRIORITY = FACILITY * 8 + SEVERITY

FACILITY = PRIORITY // 8
SEVERITY = PRIORITY (mod) 8

Výpočet lze dále optimalizovat pomocí bitových posunů.

Abychom obohatili událost o log.syslog.facility.code, log.syslog.facility.name, log.syslog.severity.code a log.syslog.severity.name, použijeme deklaraci obohacovače:

40_enricher_syslog_ECS.yaml
---
define:
  type: parsec/enricher
  schema: /Schemas/ECS.yaml

enrich:
  # SYSLOG ZAŘÍZENÍ
  log.syslog.facility.code: !SHR { what: !GET { from: !ARG EVENT, what: log.syslog.priority }, by: 3 }
  log.syslog.facility.name: !MATCH
                            what: !GET { from: !ARG EVENT, what: log.syslog.facility.code }
                            with:
                              0: kern
                              1: user
                              2: mail
                              3: daemon
                              4: auth
                              5: syslog
                              6: lpr
                              7: news
                              8: uucp
                              9: cron
                              10: authpriv
                              11: ftp
                              16: local0
                              17: local1
                              18: local2
                              19: local3
                              20: local4
                              21: local5
                              22: local6
                              23: local7

  # SYSLOG ZÁVAŽNOST
  log.syslog.severity.code: !AND [ !GET { from: !ARG EVENT, what: log.syslog.priority }, 7 ]
  log.syslog.severity.name: !MATCH
                            what: !GET {from: !ARG EVENT, what: log.syslog.severity.code}
                            with:
                              0: emergency
                              1: alert
                              2: critical
                              3: error
                              4: warning
                              5: notice
                              6: information
                              7: debug

To produkuje následující (a konečný) výstup, s přidanými poli:

log.syslog.priority: 38
log.syslog.severity.code: 6
log.syslog.severity.name: information
log.syslog.facility.code: 4
log.syslog.facility.name: auth
@timestamp: Sep 3 13:38:07
host.hostname: host01
process.name: systemd-logind
process.pid: 1078
message: New session 49 of user harrypotter

Syslog RFC5424

Zprávy Syslog RFC5424 mají strukturovanější formát než zprávy RFC3164. Událost ve formátu RFC5424 typicky sestává z následujících částí:

  • priorita (PRI část): Číslo uzavřené v "<>" závorkách, které označuje zařízení a závažnost logu.
  • verze: Verze syslog protokolu (obvykle "1").
  • časová značka: Časová značka ve formátu YYYY-MM-DDThh:mm:ss.sTZD (např. 2003-10-11T22:14:15.003Z), podle RFC3339.
  • hostname: Název zařízení, které událost vyprodukovalo.
  • app-name: Název aplikace, která událost vyprodukovala.
  • procid: ID procesu aplikace, která událost vyprodukovala.
  • msgid: ID zprávy.
  • structured-data: Volitelná strukturovaná data uzavřená v hranatých závorkách.
  • zpráva: Část zprávy události.

Parsování hlavičky

Následující deklarace parseru rozděluje zprávu RFC5424 na její komponenty:

10_parser.yaml
---
define:
  type: parsec/parser

parse:
  !PARSE.KVLIST
  - "<"
  - PRI: !PARSE.DIGITS
  - ">"
  - VERSION: !PARSE.DIGITS
  - !PARSE.SPACES
  - TIMESTAMP: !PARSE.DATETIME RFC3339  #(1)
  - !PARSE.SPACES
  - HOSTNAME: !PARSE.UNTIL " "
  - APPNAME: !PARSE.UNTIL " "
  - PROCID: !PARSE.UNTIL " "
  - MSGID: !PARSE.UNTIL " "
  - !PARSE.OPTIONAL { what: !PARSE.SPACES }
  - STRUCTURED_DATA: !PARSE.OPTIONAL { what: !PARSE.BETWEEN { start: "[", stop: "]" } }  #(2)
  - !PARSE.OPTIONAL { what: !PARSE.SPACES }
  - MESSAGE: !PARSE.CHARS
  1. Výraz !PARSE.DATETIME RFC3339 parsuje časovou značku podle formátu RFC3339.
  2. Strukturovaná data jsou volitelná a uzavřená v hranatých závorkách. Výraz !PARSE.OPTIONAL zajišťuje, že parser může zpracovat zprávy bez strukturovaných dat.

Mapování na ECS schéma

Po proscanování celého logu vypadá výstup takto:

PRI: 38
VERSION: 1
TIMESTAMP: 2003-10-11T22:14:15.003Z
HOSTNAME: host01
APPNAME: myapp
PROCID: 1234
MSGID: ID47
STRUCTURED_DATA: [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"]
MESSAGE: An application event log entry...

Další fází je mapování na ECS schéma:

20_mapping_ECS.yaml
---
define:
  type: parsec/mapping
  schema: /Schemas/ECS.yaml
mapping:
  PRI: log.syslog.priority
  VERSION: log.syslog.version
  TIMESTAMP: "@timestamp"
  HOSTNAME: host.hostname
  APPNAME: process.name
  PROCID: process.pid
  MSGID: log.syslog.message_id
  STRUCTURED_DATA: log.syslog.structured_data
  MESSAGE: message

Po mapování vypadá výstup takto:

log.syslog.priority: 38
log.syslog.version: 1
@timestamp: 2003-10-11T22:14:15.003Z
host.hostname: host01
process.name: myapp
process.pid: 1234
log.syslog.message_id: ID47
log.syslog.structured_data: [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"]
message: An application event log entry...

Obohacení závažnosti a zařízení syslogu

Zařízení a závažnost syslogu lze vypočítat z priority následujícím způsobem:

PRIORITY = FACILITY * 8 + SEVERITY

FACILITY = PRIORITY // 8
SEVERITY = PRIORITY (mod) 8

Výpočet lze dále optimalizovat pomocí bitových posunů.

Abychom obohatili událost o log.syslog.facility.code, log.syslog.facility.name, log.syslog.severity.code a log.syslog.severity.name, použijeme deklaraci obohacovače:

30_enricher_syslog_ECS.yaml
---
define:
  type: parsec/enricher
  schema: /Schemas/ECS.yaml

enrich:
  # SYSLOG ZAŘÍZENÍ
  log.syslog.facility.code: !SHR { what: !GET { from: !ARG EVENT, what: log.syslog.priority }, by: 3 }
  log.syslog.facility.name: !MATCH
                            what: !GET { from: !ARG EVENT, what: log.syslog.facility.code }
                            with:
                              0: kern
                              1: user
                              2: mail
                              3: daemon
                              4: auth
                              5: syslog
                              6: lpr
                              7: news
                              8: uucp
                              9: cron
                              10: authpriv
                              11: ftp
                              16: local0
                              17: local1
                              18: local2
                              19: local3
                              20: local4
                              21: local5
                              22: local6
                              23: local7

  # SYSLOG ZÁVAŽNOST
  log.syslog.severity.code: !AND [ !GET { from: !ARG EVENT, what: log.syslog.priority }, 7 ]
  log.syslog.severity.name: !MATCH
                            what: !GET {from: !ARG EVENT, what: log.syslog.severity.code}
                            with:
                              0: emergency
                              1: alert
                              2: critical
                              3: error
                              4: warning
                              5: notice
                              6: information
                              7: debug

To produkuje následující (a konečný) výstup, s přidanými poli:

log.syslog.priority: 38
log.syslog.severity.code: 6
log.syslog.severity.name: information
log.syslog.facility.code: 4
log.syslog.facility.name: auth
log.syslog.version: 1
@timestamp: 2003-10-11T22:14:15.003Z
host.hostname: host01
process.name: myapp
process.pid: 1234
log.syslog.message_id: ID47
log.syslog.structured_data: [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"]
message: An application event log entry...