feat: add generic critical severity classification rule and update deployment documentation

This commit is contained in:
byrsapty 2026-07-22 15:19:10 +03:00
parent 30d8512146
commit eed2de0571
2 changed files with 38 additions and 25 deletions

View file

@ -1,5 +1,5 @@
{
"title": "generic_critical_severity",
"description": "Universal fallback: any syslog message (any vendor) with RFC5424/3164 severity Emergency/Alert/Critical (0-2) that wasn't already classified by a more specific rule",
"source": "rule \"generic_critical_severity\"\nwhen\n !has_field(\"event_type\") && has_field(\"level\") && to_long($message.level) <= 2\nthen\n set_field(\"event_type\", \"generic_critical_syslog\");\n set_field(\"severity_tag\", \"critical\");\nend"
"description": "Universal fallback: any syslog message (any vendor) with RFC5424/3164 severity Emergency/Alert/Critical (0-2) that was not already classified by a more specific rule. Excludes level<0 (unparseable/unknown severity - e.g. raw text sent without a syslog PRI header, such as Vector socket sink output), which is NOT the same as an actually critical message.",
"source": "rule \"generic_critical_severity\"\nwhen\n !has_field(\"event_type\") && has_field(\"level\") && to_long($message.level) >= 0 && to_long($message.level) <= 2\nthen\n set_field(\"event_type\", \"generic_critical_syslog\");\n set_field(\"severity_tag\", \"critical\");\nend"
}

View file

@ -86,7 +86,7 @@
read_from: "beginning"
# ==========================================
# 2. ПЕРЕТВОРЕННЯ (Transforms) — форматування та тегування
# 2. ПЕРЕТВОРЕННЯ (Transforms) — тегування джерела
# ==========================================
transforms:
format_for_graylog:
@ -94,12 +94,11 @@
inputs:
- "accel_ppp_log"
source: |
.message = encode_key_value({
"timestamp": to_string!(.timestamp),
"host": get_hostname!(),
"tag": "accel-remote-only",
"message": .message
})
# Додаємо лише ім'я хоста спереду, як префікс — оригінальний
# рядок логу accel-ppp лишається без змін. Саме під його формат
# написані pipeline rules у Graylog (interface, RADIUS-атрибути
# тощо), тож його не можна перекручувати.
.message = "[" + get_hostname!() + "] " + to_string!(.message)
# ==========================================
# 3. ПРИЗНАЧЕННЯ (Sinks) — куди відправляти
@ -115,6 +114,19 @@
codec: "text"
```
> **Чому не `encode_key_value()`?** Перша версія цього гайду огортала
> повідомлення в `encode_key_value({...})` (`timestamp=... host=...
> tag=... message="..."`). Це виглядало акуратно, але на практиці
> ламало обробку в Graylog двома способами: (1) `encode_key_value()`
> екранує лапки всередині значення `message` (`"NAS1"` ставало
> `\"NAS1\"`), через що regex-правила Graylog для RADIUS/accel-ppp
> переставали витягувати поля (`accelppp_interface`,
> `acct_status_type` тощо лишались порожніми); (2) Graylog-вхід тут —
> звичайний Syslog UDP, а не GELF/структурований, тож жодної реальної
> користі з "красивого" key-value формату однаково не було — усе одно
> зберігається як один текстовий рядок. Простий префікс з hostname
> дає ідентифікацію джерела без цих побічних ефектів.
3. Збережіть файл (`Ctrl+O`, `Enter`) і вийдіть (`Ctrl+X`).
4. Перевірте синтаксис перед запуском:
@ -208,14 +220,14 @@ transforms:
inputs:
- "<унікальнаазва_джерела>"
source: |
.message = encode_key_value({
"timestamp": to_string!(.timestamp),
"host": get_hostname!(),
"tag": "<унікальний_тег_для_пошуку_в_graylog>",
"message": .message
})
.message = "[" + get_hostname!() + "] " + to_string!(.message)
```
> Не додавайте сюди `encode_key_value()` чи інше перепакування —
> дивіться пояснення "Чому не `encode_key_value()`?" у кроці 2. Якщо
> потрібно розрізняти джерела в Graylog, найпростіше — унікальний
> префікс замість hostname, наприклад `"[radius] " + to_string!(.message)`.
Потім допишіть `<унікальнаазва_transform>` у список `inputs` sink'у
`graylog_out` (він уже є в конфізі з кроку 2):
@ -256,12 +268,7 @@ transforms:
inputs:
- "freeradius_log"
source: |
.message = encode_key_value({
"timestamp": to_string!(.timestamp),
"host": get_hostname!(),
"tag": "radius-server",
"message": .message
})
.message = "[" + get_hostname!() + "] " + to_string!(.message)
sinks:
graylog_out:
@ -315,6 +322,8 @@ Graylog двічі з різними форматами.
| Повідомлення доходять, але без полів `vendor`/`event_type` у Graylog | Pipeline rules у Graylog ще не мають правила під формат саме цього тегу/сервісу | Дайте кілька реальних рядків логу — можна додати нове pipeline rule за тим самим принципом, що й для accel-ppp/RADIUS |
| Дублікати повідомлень у Graylog | Старе правило `rsyslog` досі активне паралельно з Vector | Виконайте крок 6 |
| Vector запускається, але не бачить оновлень файлу | Файл ротується (logrotate) інакше, ніж очікує Vector | Перевірте `include`/`ignore_older_secs`; за потреби додайте `fingerprint` налаштування у `source`, щоб Vector коректно стежив за файлом після ротації |
| `vector validate` видає `error[E103]: unhandled fallible assignment` у `transform` | VRL вимагає явно гарантувати тип операнда перед конкатенацією/операцією (наприклад, `.message` без `to_string!()`) | Обгорніть проблемне поле в `to_string!(...)` (або іншу `!`-функцію відповідного типу) — саме так це вирішено в базовому конфізі кроку 2 |
| Критичні алерти в Discord на рутинні `info`-повідомлення від Vector-джерела | Syslog UDP input не бачить валідного `<PRI>` заголовка в сирому тексті Vector, тож Graylog проставляє severity `-1` ("невідомо") — а не 0-2 (справді критично) | Це вже виправлено на стороні Graylog (правило `generic_critical_severity` тепер явно виключає `level < 0`); якщо побачите знову — перевірте, чи не відкотилось це правило |
## Довідка: структура конфігурації
@ -322,10 +331,14 @@ Graylog двічі з різними форматами.
вказаний файл, `read_from: "beginning"` = при першому запуску прочитати
файл з початку (а не тільки нові рядки).
- **`transforms`** (тип `remap`) — обробка даних мовою VRL (Vector Remap
Language). У цьому гайді використовується `encode_key_value()`, щоб
зібрати повідомлення у вигляді `timestamp=... host=... tag=... message=...`
— простий, передбачуваний текстовий формат, який легко парсити правилами
в Graylog.
Language). У цьому гайді використовується лише конкатенація рядків
(`"[" + get_hostname!() + "] " + to_string!(.message)`), щоб додати
ідентифікацію хоста, не чіпаючи оригінальний формат рядка логу — саме
під цей оригінальний формат написані pipeline rules у Graylog.
`to_string!()` потрібен тому, що VRL вимагає явно гарантувати тип
рядка перед конкатенацією (`!` означає "перервати обробку цього
повідомлення, якщо не вдалось" — тут це станеться хіба що для зовсім
нетипових вхідних даних).
- **`sinks`** (тип `socket`, `mode: "udp"`) — куди й як відправляти
результат. Один sink може приймати від багатьох transforms одночасно
(список `inputs`) — саме так додаються нові джерела логів без створення