Ú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í:
- 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:
---
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:
---
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
- 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. - Tato větev se zabývá vstupy ve formátu
PROCESS.NAME[PROCESS.PID]
(např.cron[123]
). - Tato větev se zabývá vstupy ve formátu
PROCESS.NAME:
(např.sudo:
). - 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:
---
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:
---
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:
---
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
- Výraz
!PARSE.DATETIME RFC3339
parsuje časovou značku podle formátu RFC3339. - 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:
---
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:
---
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...