feat: add Juniper chassis alarm alerting, Discord notifications, and global timezone configuration for accurate syslog timestamp parsing
This commit is contained in:
parent
eed2de0571
commit
0db85fa860
8 changed files with 182 additions and 52 deletions
49
README.md
49
README.md
|
|
@ -268,6 +268,34 @@ each widget needs a matching `search_types` entry (in `search.json`) and
|
|||
docs still reference 6.0.x — don't trust cached documentation over
|
||||
what the running server actually reports).
|
||||
|
||||
- **RFC3164 syslog timestamps have no timezone - Graylog assumes UTC by
|
||||
default**: most network gear and accel-ppp send classic RFC3164 syslog
|
||||
(`Jul 22 09:15:13`, no year, no offset). Without an explicit `timezone`
|
||||
setting on the input, Graylog stores that bare timestamp as if it were
|
||||
already UTC - so a device logging in local Kyiv time (UTC+3) shows up
|
||||
3 hours in the future in Graylog. Confirmed live: a raw test packet with
|
||||
`Jul 22 09:15:13` was stored as `09:15:13Z` (wrong) until each Syslog UDP
|
||||
input's `timezone` config was set to the container's own timezone
|
||||
(`Europe/Kyiv` here); afterwards it correctly stored as `06:15:13Z`
|
||||
(`09:15:13` Kyiv = `06:15:13` UTC). `step_inputs()` in
|
||||
`install-graylog.sh` sets this automatically from `/etc/timezone` for
|
||||
every input it creates, and self-heals it on existing inputs that
|
||||
predate this fix.
|
||||
|
||||
- **The built-in `admin` user's displayed timezone is a separate setting
|
||||
from the input-level fix above**: even after the RFC3164 fix, the Web UI
|
||||
can still show times in UTC for the read-only built-in `admin` account.
|
||||
That account's timezone is `read_only: true` and **cannot** be changed
|
||||
via `PUT /api/users/admin` (confirmed live - fails with `"state should
|
||||
be: hexString has 24 characters"`, since that endpoint isn't meant for
|
||||
the special built-in account). It can only be set server-side via the
|
||||
`root_timezone` config option, i.e. Docker's `GRAYLOG_ROOT_TIMEZONE` env
|
||||
var. `step_compose_files()` sets this from `/etc/timezone` for fresh
|
||||
installs and self-heals it into any pre-existing `.env` that predates
|
||||
this fix; `docker-compose.yml` passes it through to the `graylog`
|
||||
service. A `docker compose up -d` re-run picks up the change and
|
||||
recreates the container automatically.
|
||||
|
||||
- **Network gear sends syslog to port 514, not a custom port**: most
|
||||
switches/OLTs (confirmed live with a BDCOM S5612) only support
|
||||
`logging <host>`, which always uses the standard UDP/514, with no way to
|
||||
|
|
@ -299,6 +327,7 @@ are parsed and searchable but never page anyone):
|
|||
| RADIUS server unreachable | `radius: server(N) not responding` or `radius: no available servers` (verified strings from accel-ppp source, `radius/req.c`) | High |
|
||||
| conntrack table full (packet loss) | `nf_conntrack: table full, dropping packet` (standard Linux kernel message - active, ongoing packet loss) | High |
|
||||
| Unrecognized critical-severity syslog | Any message (any vendor, either stream) with RFC5424/3164 syslog severity Emergency/Alert/Critical (0-2) that no specific pipeline rule already classified | Medium |
|
||||
| Juniper chassis hardware alarm | `CHASSISD_SNMP_TRAP`/`CHASSISD_SNMP_TRAP6` (over temperature, fan, power supply, etc.) - confirmed live against a real `VC.MYRONIVKA` chassis | High |
|
||||
|
||||
That third one is the "universal network equipment problem" catch-all: it
|
||||
doesn't depend on knowing any vendor's specific message format, just the
|
||||
|
|
@ -316,13 +345,29 @@ when running `create-graylog-lxc.sh`. Under the hood this uses Graylog's
|
|||
built-in **Slack** notification type pointed at
|
||||
`<your-webhook-url>/slack` - Discord's Slack-compatibility endpoint - so no
|
||||
extra converter service is needed. The message template shows the event
|
||||
title/description plus the source and raw text of every matched message:
|
||||
title/description plus the source, sending IP, and raw text of every
|
||||
matched message:
|
||||
```
|
||||
*${event_definition_title}*
|
||||
${event_definition_description}
|
||||
${if backlog}${foreach backlog message}• `${message.source}`: ${message.message}
|
||||
${if backlog}${foreach backlog message}• `${message.source}` (IP: ${message.fields.gl2_remote_ip}): ${message.message}
|
||||
${end}${end}
|
||||
```
|
||||
`gl2_remote_ip` is a field Graylog attaches automatically to every message
|
||||
based on the actual UDP packet's source address, regardless of what
|
||||
hostname the device itself claims in the syslog `source` field.
|
||||
|
||||
### Searching by IP address
|
||||
|
||||
Every message is searchable by the sending device's real IP via the same
|
||||
`gl2_remote_ip` field, in the Search page query bar:
|
||||
```
|
||||
gl2_remote_ip:93.171.243.4
|
||||
```
|
||||
`source:<value>` also works, but only matches if the device's self-reported
|
||||
hostname was used (some equipment sends its actual IP as the hostname,
|
||||
others send a configured name) - `gl2_remote_ip` is the reliable one since
|
||||
it's derived from the packet itself, not device-supplied data.
|
||||
|
||||
### Verifying a test alert
|
||||
|
||||
|
|
|
|||
50
README.uk.md
50
README.uk.md
|
|
@ -277,6 +277,35 @@ keyboard/click-події без одночасного тригера внут
|
|||
документація досі згадує 6.0.x — не довіряйте кешованій документації
|
||||
більше, ніж тому, що фактично повідомляє запущений сервер).
|
||||
|
||||
- **У RFC3164 syslog немає часового поясу — Graylog за замовчуванням
|
||||
вважає це UTC**: більшість мережевого обладнання і accel-ppp шлють
|
||||
класичний RFC3164 syslog (`Jul 22 09:15:13`, без року, без зсуву). Без
|
||||
явного налаштування `timezone` на input Graylog зберігає цей "голий"
|
||||
час так, ніби він уже в UTC — тож пристрій, що пише за київським часом
|
||||
(UTC+3), в Graylog виглядає так, ніби події відбулись на 3 години в
|
||||
майбутньому. Перевірено наживо: тестовий пакет із `Jul 22 09:15:13`
|
||||
зберігався як `09:15:13Z` (неправильно), поки в конфігурації кожного
|
||||
Syslog UDP input не виставили `timezone` на часовий пояс самого
|
||||
контейнера (`Europe/Kyiv`); після цього він коректно зберігається як
|
||||
`06:15:13Z` (`09:15:13` за Києвом = `06:15:13` UTC). `step_inputs()` у
|
||||
`install-graylog.sh` виставляє це автоматично з `/etc/timezone` для
|
||||
кожного input, який створює, і сам виправляє це на вже існуючих input,
|
||||
створених до цього фіксу.
|
||||
|
||||
- **Часовий пояс відображення для вбудованого користувача `admin` — це
|
||||
окреме налаштування, не те саме, що фікс вище**: навіть після фіксу
|
||||
RFC3164 веб-інтерфейс міг далі показувати час в UTC для вбудованого
|
||||
read-only акаунта `admin`. Часовий пояс цього акаунта **не можна**
|
||||
змінити через `PUT /api/users/admin` (перевірено наживо — падає з
|
||||
`"state should be: hexString has 24 characters"`, оскільки цей ендпоінт
|
||||
не призначений для спеціального вбудованого акаунта). Він
|
||||
налаштовується лише на рівні сервера — опція `root_timezone`, тобто
|
||||
змінна оточення Docker `GRAYLOG_ROOT_TIMEZONE`. `step_compose_files()`
|
||||
виставляє її з `/etc/timezone` для нових інсталяцій і сам додає її в
|
||||
уже існуючий `.env`, створений до цього фіксу; `docker-compose.yml`
|
||||
прокидає її в сервіс `graylog`. Повторний запуск `docker compose up -d`
|
||||
підхоплює зміну і сам перестворює контейнер.
|
||||
|
||||
- **Retention індексів звужений навмисно**: фабричний дефолт Graylog 7.1
|
||||
зберігає 30-40 днів даних у до 20 індексах — прийнятно загалом, але
|
||||
ризиковано на малому диску (це розгортання: 50GB) у поєднанні з
|
||||
|
|
@ -316,6 +345,7 @@ keyboard/click-події без одночасного тригера внут
|
|||
| RADIUS server unreachable | `radius: server(N) not responding` або `radius: no available servers` (перевірені рядки з вихідного коду accel-ppp, `radius/req.c`) | High |
|
||||
| conntrack table full (packet loss) | `nf_conntrack: table full, dropping packet` (стандартне повідомлення ядра Linux — активна втрата пакетів прямо зараз) | High |
|
||||
| Unrecognized critical-severity syslog | Будь-яке повідомлення (будь-який вендор, будь-який стрім) із syslog-severity Emergency/Alert/Critical (0-2) за RFC5424/3164, яке не класифікувало жодне спеціальне правило | Medium |
|
||||
| Juniper chassis hardware alarm | `CHASSISD_SNMP_TRAP`/`CHASSISD_SNMP_TRAP6` (перегрів, вентилятор, блок живлення тощо) — перевірено наживо на реальному шасі `VC.MYRONIVKA` | High |
|
||||
|
||||
Третій алерт і є тим самим "універсальним" покриттям проблем мережевого
|
||||
обладнання: він не залежить від знання формату повідомлень конкретного
|
||||
|
|
@ -334,13 +364,29 @@ keyboard/click-події без одночасного тригера внут
|
|||
використовується вбудований тип нотифікації Graylog **Slack**, спрямований
|
||||
на `<ваш-webhook-url>/slack` — Slack-сумісний ендпоінт Discord — тож окремий
|
||||
конвертер не потрібен. Шаблон повідомлення показує заголовок/опис події
|
||||
плюс джерело і повний текст кожного повідомлення, що спрацювало:
|
||||
плюс джерело, IP відправника і повний текст кожного повідомлення, що
|
||||
спрацювало:
|
||||
```
|
||||
*${event_definition_title}*
|
||||
${event_definition_description}
|
||||
${if backlog}${foreach backlog message}• `${message.source}`: ${message.message}
|
||||
${if backlog}${foreach backlog message}• `${message.source}` (IP: ${message.fields.gl2_remote_ip}): ${message.message}
|
||||
${end}${end}
|
||||
```
|
||||
`gl2_remote_ip` — поле, яке Graylog проставляє автоматично для кожного
|
||||
повідомлення на основі реальної адреси відправника UDP-пакета, незалежно
|
||||
від того, яке ім'я хоста заявляє сам пристрій у полі syslog `source`.
|
||||
|
||||
### Пошук за IP-адресою
|
||||
|
||||
Кожне повідомлення можна знайти за реальною IP-адресою пристрою через те
|
||||
саме поле `gl2_remote_ip`, у рядку пошуку на сторінці Search:
|
||||
```
|
||||
gl2_remote_ip:93.171.243.4
|
||||
```
|
||||
`source:<значення>` теж працює, але лише якщо пристрій сам надсилає свою
|
||||
IP-адресу як ім'я хоста (деяке обладнання так робить, інше шле
|
||||
налаштоване ім'я) — `gl2_remote_ip` надійніший, бо береться з самого
|
||||
пакета, а не з даних, які надає пристрій.
|
||||
|
||||
### Перевірка тестового алерту
|
||||
|
||||
|
|
|
|||
21
alerts/alert4_juniper_chassis_alarm.json
Normal file
21
alerts/alert4_juniper_chassis_alarm.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"title": "CRITICAL: Juniper chassis hardware alarm",
|
||||
"description": "Chassis-level SNMP trap from Juniper equipment (over temperature, fan, power supply, etc.) - potential hardware failure risk",
|
||||
"priority": 3,
|
||||
"alert": true,
|
||||
"config": {
|
||||
"type": "aggregation-v1",
|
||||
"query": "event_type:chassis_alarm",
|
||||
"streams": ["__NETWORK_STREAM_ID__"],
|
||||
"group_by": [],
|
||||
"series": [],
|
||||
"conditions": {"expression": null},
|
||||
"search_within_ms": 60000,
|
||||
"execute_every_ms": 60000,
|
||||
"event_limit": 100
|
||||
},
|
||||
"field_spec": {},
|
||||
"key_spec": [],
|
||||
"notification_settings": {"grace_period_ms": 600000, "backlog_size": 5},
|
||||
"notifications": [{"notification_id": "__DISCORD_NOTIFICATION_ID__"}]
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
"color": "#FF0000",
|
||||
"webhook_url": "__DISCORD_WEBHOOK_URL_SLACK__",
|
||||
"channel": "#alerts",
|
||||
"custom_message": "*${event_definition_title}*\n${event_definition_description}\n${if backlog}${foreach backlog message}• `${message.source}`: ${message.message}\n${end}${end}",
|
||||
"custom_message": "*${event_definition_title}*\n${event_definition_description}\n${if backlog}${foreach backlog message}• `${message.source}` (IP: ${message.fields.gl2_remote_ip}): ${message.message}\n${end}${end}",
|
||||
"user_name": "Graylog",
|
||||
"notify_channel": false,
|
||||
"notify_here": false,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ services:
|
|||
- GRAYLOG_PASSWORD_SECRET=${GRAYLOG_PASSWORD_SECRET}
|
||||
- GRAYLOG_ROOT_PASSWORD_SHA2=${GRAYLOG_ROOT_PASSWORD_SHA2}
|
||||
- GRAYLOG_HTTP_EXTERNAL_URI=${GRAYLOG_HTTP_EXTERNAL_URI}
|
||||
- GRAYLOG_ROOT_TIMEZONE=${GRAYLOG_ROOT_TIMEZONE}
|
||||
- GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
|
||||
- GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200
|
||||
- "GRAYLOG_SERVER_JAVA_OPTS=-Xms1g -Xmx1g -XX:NewRatio=1 -server -XX:+UseG1GC"
|
||||
|
|
|
|||
|
|
@ -101,8 +101,21 @@ step_compose_files() {
|
|||
mkdir -p "$INSTALL_DIR"
|
||||
cp "$SCRIPT_DIR/docker-compose.yml" "$INSTALL_DIR/docker-compose.yml"
|
||||
|
||||
# Same timezone detection used by step_inputs() for Syslog input parsing.
|
||||
# GRAYLOG_ROOT_TIMEZONE governs the display timezone of the built-in
|
||||
# read-only "admin" user - it CANNOT be changed via the Users REST API
|
||||
# (confirmed live: PUT /api/users/admin with a timezone field fails with
|
||||
# "state should be: hexString has 24 characters"), only via this env var.
|
||||
local tz
|
||||
tz="$(cat /etc/timezone 2>/dev/null || echo UTC)"
|
||||
|
||||
if [ -f "$INSTALL_DIR/.env" ]; then
|
||||
skip ".env already exists, keeping existing secrets"
|
||||
if grep -q '^GRAYLOG_ROOT_TIMEZONE=' "$INSTALL_DIR/.env"; then
|
||||
skip ".env already exists, keeping existing secrets"
|
||||
else
|
||||
echo "GRAYLOG_ROOT_TIMEZONE=$tz" >> "$INSTALL_DIR/.env"
|
||||
ok ".env existed but was missing GRAYLOG_ROOT_TIMEZONE - added it ($tz)"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
log "Generating fresh secrets into $INSTALL_DIR/.env ..."
|
||||
|
|
@ -115,6 +128,7 @@ step_compose_files() {
|
|||
GRAYLOG_PASSWORD_SECRET=$secret
|
||||
GRAYLOG_ROOT_PASSWORD_SHA2=$admin_sha2
|
||||
GRAYLOG_HTTP_EXTERNAL_URI=$GRAYLOG_EXTERNAL_URI
|
||||
GRAYLOG_ROOT_TIMEZONE=$tz
|
||||
EOF
|
||||
chmod 600 "$INSTALL_DIR/.env"
|
||||
|
||||
|
|
@ -217,57 +231,55 @@ print(json.dumps(d))
|
|||
|
||||
step_inputs() {
|
||||
log "Creating Syslog UDP inputs (idempotent)..."
|
||||
local existing
|
||||
local existing tz
|
||||
existing="$(gcurl GET /system/inputs)"
|
||||
|
||||
# RFC3164 syslog (which is what most network gear/accel-ppp send) has no
|
||||
# timezone in its timestamp ("Jul 22 09:15:13"). Without this setting,
|
||||
# Graylog defaults to treating that bare timestamp as UTC - so a device
|
||||
# logging in local Kyiv time (UTC+3) shows up 3 hours in the future.
|
||||
# Confirmed live: a raw test packet with "Jul 22 09:15:13" was stored as
|
||||
# 09:15:13Z UTC (wrong) until this was set; afterwards it correctly
|
||||
# stored as 06:15:13Z UTC (09:15:13 Kyiv time). Uses the container's own
|
||||
# configured timezone so it stays correct regardless of where this is
|
||||
# deployed.
|
||||
tz="$(cat /etc/timezone 2>/dev/null || echo UTC)"
|
||||
|
||||
ensure_syslog_input() {
|
||||
local port="$1" title="$2" var_name="$3"
|
||||
local id current_tz
|
||||
id="$(echo "$existing" | python3 -c "import json,sys;d=json.load(sys.stdin);print(next((i['id'] for i in d['inputs'] if i['attributes'].get('port')==$port),''))")"
|
||||
local body="{
|
||||
\"title\": \"$title\",
|
||||
\"type\": \"org.graylog2.inputs.syslog.udp.SyslogUDPInput\",
|
||||
\"global\": true,
|
||||
\"configuration\": {\"bind_address\":\"0.0.0.0\",\"port\":$port,\"recv_buffer_size\":262144,
|
||||
\"number_worker_threads\":2,\"force_rdns\":false,\"allow_override_date\":true,
|
||||
\"store_full_message\":false,\"expand_structured_data\":true,\"charset_name\":\"UTF-8\",
|
||||
\"timezone\":\"$tz\"}
|
||||
}"
|
||||
if [ -z "$id" ]; then
|
||||
id="$(gcurl POST /system/inputs "$body" | python3 -c "import json,sys;print(json.load(sys.stdin)['id'])")"
|
||||
ok "Created $title: $id"
|
||||
else
|
||||
current_tz="$(echo "$existing" | python3 -c "import json,sys;d=json.load(sys.stdin);print(next((i['attributes'].get('timezone') for i in d['inputs'] if i['attributes'].get('port')==$port),''))")"
|
||||
if [ "$current_tz" != "$tz" ]; then
|
||||
gcurl PUT "/system/inputs/$id" "$body" >/dev/null
|
||||
ok "$title already existed - fixed timezone ($current_tz -> $tz)"
|
||||
else
|
||||
skip "$title already exists: $id"
|
||||
fi
|
||||
fi
|
||||
printf -v "$var_name" '%s' "$id"
|
||||
}
|
||||
|
||||
# Port 514 is the standard syslog port and the one most network gear
|
||||
# actually sends to (confirmed live: BDCOM switches here can't be pointed
|
||||
# at a custom port). Port 1514 is kept as a secondary input for any
|
||||
# equipment that *can* be configured with a non-standard destination port.
|
||||
NETWORK_INPUT_ID_514="$(echo "$existing" | python3 -c "import json,sys;d=json.load(sys.stdin);print(next((i['id'] for i in d['inputs'] if i['attributes'].get('port')==514),''))")"
|
||||
if [ -z "$NETWORK_INPUT_ID_514" ]; then
|
||||
NETWORK_INPUT_ID_514="$(gcurl POST /system/inputs '{
|
||||
"title": "Network Equipment Syslog (standard port 514)",
|
||||
"type": "org.graylog2.inputs.syslog.udp.SyslogUDPInput",
|
||||
"configuration": {"bind_address":"0.0.0.0","port":514,"recv_buffer_size":262144,
|
||||
"number_worker_threads":2,"force_rdns":false,"allow_override_date":true,
|
||||
"store_full_message":false,"expand_structured_data":true,"charset_name":"UTF-8"},
|
||||
"global": true
|
||||
}' | python3 -c "import json,sys;print(json.load(sys.stdin)['id'])")"
|
||||
ok "Created Network Equipment input (514): $NETWORK_INPUT_ID_514"
|
||||
else
|
||||
skip "Network Equipment input (514) already exists: $NETWORK_INPUT_ID_514"
|
||||
fi
|
||||
|
||||
NETWORK_INPUT_ID_1514="$(echo "$existing" | python3 -c "import json,sys;d=json.load(sys.stdin);print(next((i['id'] for i in d['inputs'] if i['attributes'].get('port')==1514),''))")"
|
||||
if [ -z "$NETWORK_INPUT_ID_1514" ]; then
|
||||
NETWORK_INPUT_ID_1514="$(gcurl POST /system/inputs '{
|
||||
"title": "Network Equipment Syslog (Juniper-ZTE-DLink)",
|
||||
"type": "org.graylog2.inputs.syslog.udp.SyslogUDPInput",
|
||||
"configuration": {"bind_address":"0.0.0.0","port":1514,"recv_buffer_size":262144,
|
||||
"number_worker_threads":2,"force_rdns":false,"allow_override_date":true,
|
||||
"store_full_message":false,"expand_structured_data":true,"charset_name":"UTF-8"},
|
||||
"global": true
|
||||
}' | python3 -c "import json,sys;print(json.load(sys.stdin)['id'])")"
|
||||
ok "Created Network Equipment input (1514): $NETWORK_INPUT_ID_1514"
|
||||
else
|
||||
skip "Network Equipment input (1514) already exists: $NETWORK_INPUT_ID_1514"
|
||||
fi
|
||||
|
||||
SERVERS_INPUT_ID="$(echo "$existing" | python3 -c "import json,sys;d=json.load(sys.stdin);print(next((i['id'] for i in d['inputs'] if i['attributes'].get('port')==5140),''))")"
|
||||
if [ -z "$SERVERS_INPUT_ID" ]; then
|
||||
SERVERS_INPUT_ID="$(gcurl POST /system/inputs '{
|
||||
"title": "Servers Syslog (RADIUS-accel-ppp)",
|
||||
"type": "org.graylog2.inputs.syslog.udp.SyslogUDPInput",
|
||||
"configuration": {"bind_address":"0.0.0.0","port":5140,"recv_buffer_size":262144,
|
||||
"number_worker_threads":2,"force_rdns":false,"allow_override_date":true,
|
||||
"store_full_message":false,"expand_structured_data":true,"charset_name":"UTF-8"},
|
||||
"global": true
|
||||
}' | python3 -c "import json,sys;print(json.load(sys.stdin)['id'])")"
|
||||
ok "Created Servers input: $SERVERS_INPUT_ID"
|
||||
else
|
||||
skip "Servers input already exists: $SERVERS_INPUT_ID"
|
||||
fi
|
||||
ensure_syslog_input 514 "Network Equipment Syslog (standard port 514)" NETWORK_INPUT_ID_514
|
||||
ensure_syslog_input 1514 "Network Equipment Syslog (Juniper-ZTE-DLink)" NETWORK_INPUT_ID_1514
|
||||
ensure_syslog_input 5140 "Servers Syslog (RADIUS-accel-ppp)" SERVERS_INPUT_ID
|
||||
}
|
||||
|
||||
step_pipeline_rules() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Network Equipment Parsing",
|
||||
"description": "Parses Juniper and BDCOM/OLT-style syslog, plus universal critical-severity fallback",
|
||||
"source": "pipeline \"Network Equipment Parsing\"\nstage 0 match either\n rule \"juniper_ntp_unreachable\";\n rule \"juniper_ssh_login_success\";\n rule \"juniper_ssh_login_failed_tagged\";\n rule \"juniper_ssh_failed_password\";\n rule \"juniper_ui_configuration_error\";\n rule \"olt_privilege_mode\";\n rule \"olt_cli_logout\";\n rule \"olt_ip_arp_moved\";\n rule \"olt_config_write\";\n rule \"generic_critical_severity\";\nend"
|
||||
"source": "pipeline \"Network Equipment Parsing\"\nstage 0 match either\n rule \"juniper_ntp_unreachable\";\n rule \"juniper_ssh_login_success\";\n rule \"juniper_ssh_login_failed_tagged\";\n rule \"juniper_ssh_failed_password\";\n rule \"juniper_ui_configuration_error\";\n rule \"juniper_chassis_alarm\";\n rule \"olt_privilege_mode\";\n rule \"olt_cli_logout\";\n rule \"olt_ip_arp_moved\";\n rule \"olt_config_write\";\n rule \"generic_critical_severity\";\nend"
|
||||
}
|
||||
|
|
|
|||
5
rules/rule19_juniper_chassis_alarm.json
Normal file
5
rules/rule19_juniper_chassis_alarm.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"title": "juniper_chassis_alarm",
|
||||
"description": "Juniper chassisd SNMP trap (hardware health: over temperature, fan, power supply, etc.) - CHASSISD_SNMP_TRAP6",
|
||||
"source": "rule \"juniper_chassis_alarm\"\nwhen\n contains(to_string($message.message), \"CHASSISD_SNMP_TRAP\")\nthen\n set_field(\"vendor\", \"juniper\");\n set_field(\"event_type\", \"chassis_alarm\");\n set_field(\"severity_tag\", \"critical\");\n let m = regex(\"SNMP trap generated: ([^(]+?)\\\\s*\\\\(\", to_string($message.message), [\"alarm\"]);\n set_field(\"chassis_alarm_type\", m[\"alarm\"]);\n let d = regex(\"jnxContentsDescr ([^,]+)\", to_string($message.message), [\"descr\"]);\n set_field(\"chassis_component\", d[\"descr\"]);\nend"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue