# Event Handler

> Event Handler на VyOS - автоматизация реакции на события, обработка логов journald, выполнение скриптов и мониторинг системы

Source: https://opennix.org/docs/vyos/services/vyos-event-handler/


Event Handler позволяет выполнять скрипты в ответ на события в системных логах VyOS, обеспечивая автоматизацию реакций на системные события.

## Обзор

Event Handler предоставляет:
- Мониторинг journald логов в реальном времени
- Выполнение пользовательских скриптов при совпадении паттернов
- Передачу переменных окружения в скрипты
- Фильтрацию по syslog идентификаторам
- Автоматизацию реагирования на события системы

Event Handler работает с journald (systemd journal) и поддерживает регулярные выражения для поиска событий.

## Базовая конфигурация

### Минимальная настройка

Минимальная конфигурация Event Handler:

```
set service event-handler event <event-name> filter pattern '<regex>'
set service event-handler event <event-name> script path '/config/scripts/handler.sh'
commit
```

Где:
- `<event-name>` - имя обработчика события
- `<regex>` - регулярное выражение для поиска в логах
- `/config/scripts/handler.sh` - путь к исполняемому скрипту

### Структура конфигурации

```
service event-handler
  └── event <event-name>
      ├── filter
      │   ├── pattern <regex>
      │   └── syslog-identifier <identifier>
      └── script
          ├── path <script-path>
          ├── environment <name> value <value>
          └── arguments <arguments>
```

## Конфигурация Event Handler

### Создание обработчика события

Создание нового event handler:

```
set service event-handler event MY_EVENT
```

### Определение паттерна

Регулярное выражение для поиска в логах (обязательный параметр):

```
set service event-handler event MY_EVENT filter pattern 'interface eth0.*up'
```

**Важно**: Регулярное выражение должно совпадать с полной строкой сообщения, а не с частью.

Примеры паттернов:

```
# Совпадение для интерфейса
set service event-handler event LINK_DOWN filter pattern '.*link is no longer valid.*'

# Совпадение для OSPF
set service event-handler event OSPF_CHANGE filter pattern '.*OSPF.*neighbor.*changed.*'

# Совпадение для BGP
set service event-handler event BGP_DOWN filter pattern '.*BGP.*peer.*down.*'

# Совпадение для VPN
set service event-handler event IPSEC_UP filter pattern '.*IPsec SA established.*'
```

### Указание скрипта

Путь к исполняемому скрипту:

```
set service event-handler event MY_EVENT script path '/config/scripts/my-handler.sh'
```

**Важно**: Скрипт должен быть исполняемым:
```bash
chmod +x /config/scripts/my-handler.sh
```

Скрипт может быть написан на любом языке:
- Shell (bash, sh)
- Python
- Perl
- Ruby
- Любой другой доступный интерпретатор

### Фильтрация по syslog идентификатору

Ограничение поиска конкретным syslog идентификатором:

```
set service event-handler event MY_EVENT filter syslog-identifier 'kernel'
```

Примеры syslog идентификаторов:
- `kernel` - события ядра
- `systemd` - события systemd
- `sshd` - события SSH
- `vyos-configd` - события конфигурации VyOS
- `frr` - события FRR (routing)
- `chrony` - события NTP
- `snmpd` - события SNMP

Список активных идентификаторов:
```bash
journalctl -F SYSLOG_IDENTIFIER
```

### Переменные окружения

Передача переменных окружения в скрипт (рекомендуемый метод):

```
set service event-handler event MY_EVENT script environment VAR_NAME value 'value'
```

Множественные переменные:
```
set service event-handler event IF_DOWN script environment INTERFACE value 'eth0'
set service event-handler event IF_DOWN script environment ACTION value 'notify'
set service event-handler event IF_DOWN script environment EMAIL value 'admin@example.com'
```

**Встроенная переменная окружения**:
- `message` - полное сообщение, которое вызвало срабатывание

### Аргументы скрипта

Передача аргументов скрипту (устаревший метод, не рекомендуется):

```
set service event-handler event MY_EVENT script arguments 'arg1 arg2 arg3'
```

**Рекомендация**: Используйте переменные окружения вместо аргументов.

## Примеры скриптов

### Shell скрипт - базовый пример

`/config/scripts/interface-handler.sh`:

```bash
#!/bin/bash

# Получение сообщения
MESSAGE="${message}"

# Получение пользовательских переменных
INTERFACE="${INTERFACE:-unknown}"
ACTION="${ACTION:-unknown}"

# Логирование
logger -t event-handler "Event triggered: $ACTION on $INTERFACE"
logger -t event-handler "Message: $MESSAGE"

# Действия
case "$ACTION" in
    down)
        logger -t event-handler "Interface $INTERFACE is down!"
        # Отправка уведомления, перезапуск интерфейса и т.д.
        ;;
    up)
        logger -t event-handler "Interface $INTERFACE is up"
        ;;
esac
```

### Python скрипт - мониторинг интерфейса

`/config/scripts/interface-monitor.py`:

```python
#!/usr/bin/env python3

import os
import sys
import logging
from datetime import datetime

# Настройка логирования
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger('event-handler')

def main():
    # Получение переменных окружения
    message = os.environ.get('message', '')
    interface = os.environ.get('interface_name', 'unknown')
    action = os.environ.get('interface_action', 'unknown')

    logger.info(f"Event triggered for interface: {interface}")
    logger.info(f"Action: {action}")
    logger.info(f"Full message: {message}")

    # Логика обработки
    if action == 'down':
        logger.warning(f"Interface {interface} is DOWN!")
        # Отправка алерта, выполнение действий
        send_alert(interface, action, message)
    elif action == 'up':
        logger.info(f"Interface {interface} is UP")
        send_notification(interface, action)

def send_alert(interface, action, message):
    """Отправка критического алерта"""
    # Здесь может быть интеграция с:
    # - Email
    # - Telegram
    # - Slack
    # - Syslog server
    # - Monitoring system
    pass

def send_notification(interface, action):
    """Отправка информационного уведомления"""
    pass

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        logger.error(f"Error in event handler: {e}")
        sys.exit(1)
```

### Python скрипт - отправка в Telegram

`/config/scripts/telegram-alert.py`:

```python
#!/usr/bin/env python3

import os
import requests
import json
from datetime import datetime

# Конфигурация Telegram (можно передать через environment)
TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN', '')
TELEGRAM_CHAT_ID = os.environ.get('TELEGRAM_CHAT_ID', '')

def send_telegram_message(message):
    """Отправка сообщения в Telegram"""
    if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID:
        print("Telegram credentials not configured")
        return False

    url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
    payload = {
        'chat_id': TELEGRAM_CHAT_ID,
        'text': message,
        'parse_mode': 'Markdown'
    }

    try:
        response = requests.post(url, json=payload, timeout=10)
        return response.status_code == 200
    except Exception as e:
        print(f"Failed to send Telegram message: {e}")
        return False

def main():
    # Получение информации о событии
    log_message = os.environ.get('message', 'No message')
    event_type = os.environ.get('event_type', 'unknown')
    severity = os.environ.get('severity', 'info')
    hostname = os.environ.get('hostname', 'vyos')

    # Формирование сообщения
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    telegram_text = f"""
*VyOS Event Alert*

*Hostname:* `{hostname}`
*Timestamp:* `{timestamp}`
*Event Type:* `{event_type}`
*Severity:* `{severity}`

*Message:*
```
{log_message}
```
"""

    # Отправка
    if send_telegram_message(telegram_text):
        print("Alert sent to Telegram successfully")
    else:
        print("Failed to send alert to Telegram")

if __name__ == '__main__':
    main()
```

### Shell скрипт - webhook уведомление

`/config/scripts/webhook-notify.sh`:

```bash
#!/bin/bash

# Конфигурация
WEBHOOK_URL="${WEBHOOK_URL:-http://monitoring.example.com/webhook}"
MESSAGE="${message:-No message}"
EVENT_NAME="${event_name:-unknown}"
HOSTNAME=$(hostname)

# Формирование JSON payload
JSON_PAYLOAD=$(cat <<EOF
{
  "hostname": "$HOSTNAME",
  "event": "$EVENT_NAME",
  "message": "$MESSAGE",
  "timestamp": "$(date -Iseconds)"
}
EOF
)

# Отправка webhook
curl -X POST \
  -H "Content-Type: application/json" \
  -d "$JSON_PAYLOAD" \
  "$WEBHOOK_URL" \
  --max-time 10 \
  --silent \
  --show-error

exit 0
```

## Примеры конфигурации

### Мониторинг интерфейса

Отслеживание состояния интерфейса и выполнение скрипта при изменении:

```
# Обработчик для падения интерфейса
set service event-handler event INTERFACE_DOWN filter pattern '.*eth0.*link is no longer valid.*'
set service event-handler event INTERFACE_DOWN filter syslog-identifier 'kernel'
set service event-handler event INTERFACE_DOWN script path '/config/scripts/interface-down.sh'
set service event-handler event INTERFACE_DOWN script environment INTERFACE value 'eth0'
set service event-handler event INTERFACE_DOWN script environment ACTION value 'down'

# Обработчик для поднятия интерфейса
set service event-handler event INTERFACE_UP filter pattern '.*eth0.*link is now usable.*'
set service event-handler event INTERFACE_UP filter syslog-identifier 'kernel'
set service event-handler event INTERFACE_UP script path '/config/scripts/interface-up.sh'
set service event-handler event INTERFACE_UP script environment INTERFACE value 'eth0'
set service event-handler event INTERFACE_UP script environment ACTION value 'up'

commit
```

### Мониторинг BGP соседей

```
# BGP neighbor down
set service event-handler event BGP_NEIGHBOR_DOWN filter pattern '.*BGP.*neighbor.*Down.*'
set service event-handler event BGP_NEIGHBOR_DOWN filter syslog-identifier 'bgpd'
set service event-handler event BGP_NEIGHBOR_DOWN script path '/config/scripts/bgp-alert.py'
set service event-handler event BGP_NEIGHBOR_DOWN script environment EVENT_TYPE value 'bgp_down'
set service event-handler event BGP_NEIGHBOR_DOWN script environment SEVERITY value 'critical'

# BGP neighbor up
set service event-handler event BGP_NEIGHBOR_UP filter pattern '.*BGP.*neighbor.*Up.*'
set service event-handler event BGP_NEIGHBOR_UP filter syslog-identifier 'bgpd'
set service event-handler event BGP_NEIGHBOR_UP script path '/config/scripts/bgp-alert.py'
set service event-handler event BGP_NEIGHBOR_UP script environment EVENT_TYPE value 'bgp_up'
set service event-handler event BGP_NEIGHBOR_UP script environment SEVERITY value 'info'

commit
```

### Мониторинг VPN соединений

```
# IPsec tunnel установлен
set service event-handler event IPSEC_UP filter pattern '.*IPsec SA established.*'
set service event-handler event IPSEC_UP filter syslog-identifier 'charon'
set service event-handler event IPSEC_UP script path '/config/scripts/vpn-notify.sh'
set service event-handler event IPSEC_UP script environment VPN_STATUS value 'up'

# IPsec tunnel разорван
set service event-handler event IPSEC_DOWN filter pattern '.*IPsec SA deleted.*'
set service event-handler event IPSEC_DOWN filter syslog-identifier 'charon'
set service event-handler event IPSEC_DOWN script path '/config/scripts/vpn-notify.sh'
set service event-handler event IPSEC_DOWN script environment VPN_STATUS value 'down'
set service event-handler event IPSEC_DOWN script environment SEVERITY value 'warning'

commit
```

### Мониторинг SSH входов

```
# Успешный SSH вход
set service event-handler event SSH_LOGIN filter pattern '.*Accepted publickey for.*'
set service event-handler event SSH_LOGIN filter syslog-identifier 'sshd'
set service event-handler event SSH_LOGIN script path '/config/scripts/ssh-login-notify.sh'
set service event-handler event SSH_LOGIN script environment EVENT_TYPE value 'ssh_login'

# Неудачная попытка SSH
set service event-handler event SSH_FAILED filter pattern '.*Failed password for.*'
set service event-handler event SSH_FAILED filter syslog-identifier 'sshd'
set service event-handler event SSH_FAILED script path '/config/scripts/ssh-failed-notify.sh'
set service event-handler event SSH_FAILED script environment EVENT_TYPE value 'ssh_failed'
set service event-handler event SSH_FAILED script environment SEVERITY value 'warning'

commit
```

### Мониторинг использования диска

```
set service event-handler event DISK_FULL filter pattern '.*No space left on device.*'
set service event-handler event DISK_FULL script path '/config/scripts/disk-full-alert.py'
set service event-handler event DISK_FULL script environment ALERT_TYPE value 'disk_full'
set service event-handler event DISK_FULL script environment SEVERITY value 'critical'
set service event-handler event DISK_FULL script environment WEBHOOK_URL value 'https://monitoring.example.com/alerts'

commit
```

### Интеграция с Telegram

```
set service event-handler event CRITICAL_ALERT filter pattern '.*(critical|panic|emergency).*'
set service event-handler event CRITICAL_ALERT script path '/config/scripts/telegram-alert.py'
set service event-handler event CRITICAL_ALERT script environment TELEGRAM_BOT_TOKEN value 'YOUR_BOT_TOKEN'
set service event-handler event CRITICAL_ALERT script environment TELEGRAM_CHAT_ID value 'YOUR_CHAT_ID'
set service event-handler event CRITICAL_ALERT script environment event_type value 'critical'
set service event-handler event CRITICAL_ALERT script environment severity value 'critical'
set service event-handler event CRITICAL_ALERT script environment hostname value 'vyos-gateway'

commit
```

### Мониторинг температуры

```
set service event-handler event HIGH_TEMP filter pattern '.*temperature.*critical.*'
set service event-handler event HIGH_TEMP filter syslog-identifier 'kernel'
set service event-handler event HIGH_TEMP script path '/config/scripts/temp-alert.sh'
set service event-handler event HIGH_TEMP script environment ALERT_TYPE value 'temperature'
set service event-handler event HIGH_TEMP script environment SEVERITY value 'critical'

commit
```

## Интеграции

### Email уведомления

Настройка отправки email через внешний SMTP:

`/config/scripts/email-notify.sh`:

```bash
#!/bin/bash

MESSAGE="${message}"
RECIPIENT="${EMAIL_TO:-admin@example.com}"
SUBJECT="${EMAIL_SUBJECT:-VyOS Event Alert}"

# Через mail команду (требует настройки postfix/sendmail)
echo "$MESSAGE" | mail -s "$SUBJECT" "$RECIPIENT"

# Или через curl и SMTP
# curl --url 'smtp://mail.example.com:587' \
#   --mail-from 'vyos@example.com' \
#   --mail-rcpt "$RECIPIENT" \
#   --user 'username:password' \
#   --upload-file <(echo -e "Subject: $SUBJECT\n\n$MESSAGE")
```

Конфигурация:
```
set service event-handler event EMAIL_ALERT script environment EMAIL_TO value 'admin@example.com'
set service event-handler event EMAIL_ALERT script environment EMAIL_SUBJECT value 'VyOS Critical Alert'
```

### Slack webhook

`/config/scripts/slack-notify.sh`:

```bash
#!/bin/bash

SLACK_WEBHOOK="${SLACK_WEBHOOK_URL}"
MESSAGE="${message}"
HOSTNAME=$(hostname)

if [ -z "$SLACK_WEBHOOK" ]; then
    echo "Slack webhook URL not configured"
    exit 1
fi

# Формирование JSON для Slack
JSON_PAYLOAD=$(cat <<EOF
{
  "text": "VyOS Event on $HOSTNAME",
  "attachments": [
    {
      "color": "danger",
      "fields": [
        {
          "title": "Message",
          "value": "$MESSAGE",
          "short": false
        }
      ]
    }
  ]
}
EOF
)

# Отправка в Slack
curl -X POST \
  -H 'Content-Type: application/json' \
  -d "$JSON_PAYLOAD" \
  "$SLACK_WEBHOOK"
```

Конфигурация:
```
set service event-handler event SLACK_ALERT script environment SLACK_WEBHOOK_URL value 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
```

### Syslog server

Перенаправление событий на внешний syslog сервер:

`/config/scripts/syslog-forward.sh`:

```bash
#!/bin/bash

SYSLOG_SERVER="${SYSLOG_SERVER:-192.168.1.100}"
SYSLOG_PORT="${SYSLOG_PORT:-514}"
MESSAGE="${message}"
FACILITY="${SYSLOG_FACILITY:-local0}"
SEVERITY="${SYSLOG_SEVERITY:-warning}"

# Отправка через logger с remote syslog
logger -n "$SYSLOG_SERVER" \
       -P "$SYSLOG_PORT" \
       -p "${FACILITY}.${SEVERITY}" \
       -t "vyos-event-handler" \
       "$MESSAGE"
```

### Prometheus Alertmanager

`/config/scripts/alertmanager.py`:

```python
#!/usr/bin/env python3

import os
import requests
import json
from datetime import datetime

ALERTMANAGER_URL = os.environ.get('ALERTMANAGER_URL', 'http://alertmanager:9093')

def send_alert():
    message = os.environ.get('message', '')
    alert_name = os.environ.get('alert_name', 'VyOSEvent')
    severity = os.environ.get('severity', 'warning')

    alert = [{
        'labels': {
            'alertname': alert_name,
            'severity': severity,
            'instance': os.uname().nodename,
        },
        'annotations': {
            'summary': 'VyOS Event Triggered',
            'description': message,
        },
        'startsAt': datetime.utcnow().isoformat() + 'Z',
    }]

    try:
        response = requests.post(
            f"{ALERTMANAGER_URL}/api/v1/alerts",
            json=alert,
            timeout=5
        )
        print(f"Alert sent: {response.status_code}")
    except Exception as e:
        print(f"Failed to send alert: {e}")

if __name__ == '__main__':
    send_alert()
```

## Операционные команды

### Просмотр конфигурации

Просмотр всех event handlers:
```
show service event-handler
```

Конкретного обработчика:
```
show service event-handler event MY_EVENT
```

### Тестирование регулярных выражений

Проверка совпадения паттерна с логами:

```bash
# Просмотр последних записей журнала
journalctl -n 100 --no-pager

# Фильтрация по идентификатору
journalctl -t kernel -n 50

# Поиск конкретного паттерна
journalctl | grep -E 'your-regex-pattern'
```

### Отладка скриптов

Запуск скрипта вручную с переменными окружения:

```bash
# Установка переменных окружения
export message="Test event message"
export INTERFACE="eth0"
export ACTION="down"

# Запуск скрипта
/config/scripts/interface-handler.sh
```

### Просмотр логов выполнения

Event handler логи:
```bash
journalctl -t vyos-event-handler

# В реальном времени
journalctl -t vyos-event-handler -f
```

Логи конкретного скрипта (если используется logger):
```bash
journalctl -t event-handler

# Поиск ошибок
journalctl -t event-handler | grep -i error
```

### Перезапуск service

```
restart event-handler
```

### Отключение обработчика

Временное отключение без удаления конфигурации:

```
set service event-handler event MY_EVENT disable
commit
```

Включение обратно:
```
delete service event-handler event MY_EVENT disable
commit
```

## Устранение неполадок

### Скрипт не выполняется

1. Проверьте права выполнения:
```bash
ls -l /config/scripts/my-script.sh
chmod +x /config/scripts/my-script.sh
```

2. Проверьте shebang в скрипте:
```bash
#!/bin/bash
```

3. Проверьте логи:
```bash
journalctl -t vyos-event-handler | tail -50
```

### Паттерн не срабатывает

1. Проверьте journald логи:
```bash
journalctl -n 100 | grep -i "ваш-паттерн"
```

2. Тестируйте регулярное выражение:
```bash
echo "тестовое сообщение" | grep -E 'ваш-regex'
```

3. Убедитесь что паттерн совпадает с **полной строкой**:
```
# Неправильно (частичное совпадение)
pattern 'eth0'

# Правильно (полное совпадение)
pattern '.*eth0.*'
```

### Скрипт выполняется но не работает

1. Проверьте переменные окружения в скрипте:
```bash
#!/bin/bash
env > /tmp/event-handler-env.log
echo "Message: ${message}" >> /tmp/event-handler-debug.log
```

2. Проверьте вывод скрипта:
```bash
journalctl -t event-handler
```

3. Добавьте отладочный вывод:
```python
import logging
logging.basicConfig(level=logging.DEBUG)
```

### Проблемы с syslog-identifier

Проверьте доступные идентификаторы:
```bash
journalctl -F SYSLOG_IDENTIFIER
```

Примеры реальных событий:
```bash
journalctl -t kernel -n 20
journalctl -t bgpd -n 20
journalctl -t sshd -n 20
```

### Скрипт не получает переменные

Проверьте конфигурацию:
```
show service event-handler event MY_EVENT
```

Добавьте вывод всех переменных в скрипт:
```bash
#!/bin/bash
env | grep -v PASSWORD >> /tmp/env-vars.log
```

## Безопасность и лучшие практики

### 1. Безопасность скриптов

Устанавливайте правильные права:
```bash
chown root:vyattacfg /config/scripts/handler.sh
chmod 750 /config/scripts/handler.sh
```

Избегайте хранения паролей в скриптах:
```bash
# Плохо
PASSWORD="secret123"

# Хорошо
PASSWORD="${PASSWORD_ENV_VAR}"
```

### 2. Ограничение выполнения

Добавьте таймауты в скрипты:
```bash
timeout 10 curl https://api.example.com/webhook
```

Используйте блокировки для предотвращения параллельного выполнения:
```bash
LOCK_FILE="/tmp/event-handler.lock"
if [ -e "$LOCK_FILE" ]; then
    echo "Already running"
    exit 0
fi
touch "$LOCK_FILE"
trap "rm -f $LOCK_FILE" EXIT
```

### 3. Обработка ошибок

Всегда обрабатывайте ошибки в скриптах:
```bash
#!/bin/bash
set -e  # Выход при ошибке
set -u  # Ошибка при использовании неопределенных переменных
set -o pipefail  # Ошибка в pipe

# Обработчик ошибок
trap 'echo "Error at line $LINENO"' ERR
```

Python:
```python
try:
    # Ваш код
    pass
except Exception as e:
    logging.error(f"Error: {e}")
    sys.exit(1)
```

### 4. Логирование

Всегда логируйте выполнение:
```bash
logger -t event-handler "Starting handler for event: $EVENT_NAME"
logger -t event-handler "Completed successfully"
```

### 5. Тестирование паттернов

Тщательно тестируйте regex перед применением:
```bash
# Сохраните лог в файл
journalctl -n 1000 > /tmp/test.log

# Тестируйте паттерн
grep -E 'ваш-regex' /tmp/test.log
```

### 6. Производительность

Оптимизируйте скрипты:
- Используйте легковесные команды
- Избегайте долгих операций
- Используйте фоновое выполнение для долгих задач:
```bash
long_running_task &
```

### 7. Мониторинг самих обработчиков

Создайте watchdog для мониторинга event handlers:
```bash
# Проверка что event-handler работает
systemctl status vyos-event-handler.service
```

### 8. Документирование

Документируйте каждый event handler:
```
set service event-handler event MY_EVENT description 'Monitors eth0 interface state and sends alerts'
```

### 9. Версионирование скриптов

Храните скрипты в git:
```bash
cd /config/scripts
git init
git add .
git commit -m "Initial event handler scripts"
```

### 10. Резервное копирование

Регулярно сохраняйте конфигурацию:
```
save
```

Бэкап скриптов:
```bash
tar -czf /config/scripts-backup-$(date +%Y%m%d).tar.gz /config/scripts/
```

## Примеры использования

### Автоматическое восстановление интерфейса

Скрипт автоматически перезапускает интерфейс при падении:

`/config/scripts/auto-recover-interface.sh`:
```bash
#!/bin/bash

INTERFACE="${INTERFACE:-eth0}"
MAX_RETRIES=3
RETRY_COUNT=0

logger -t event-handler "Interface $INTERFACE went down, attempting recovery"

while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
    sleep 5

    # Попытка поднять интерфейс
    vtysh -c "configure terminal" -c "interface $INTERFACE" -c "no shutdown"

    sleep 5

    # Проверка статуса
    if ip link show "$INTERFACE" | grep -q "state UP"; then
        logger -t event-handler "Interface $INTERFACE recovered successfully"
        exit 0
    fi

    RETRY_COUNT=$((RETRY_COUNT + 1))
    logger -t event-handler "Recovery attempt $RETRY_COUNT failed"
done

logger -t event-handler "Failed to recover interface $INTERFACE after $MAX_RETRIES attempts"
exit 1
```

### Динамическая блокировка IP при атаке

`/config/scripts/block-attack.sh`:
```bash
#!/bin/bash

MESSAGE="${message}"

# Извлечение IP адреса из сообщения (пример для SSH)
ATTACKER_IP=$(echo "$MESSAGE" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)

if [ -z "$ATTACKER_IP" ]; then
    logger -t event-handler "Could not extract IP from message"
    exit 1
fi

logger -t event-handler "Blocking attacker IP: $ATTACKER_IP"

# Добавление в firewall address-group
vbash -c "configure" \
      -c "set firewall group address-group BLOCKED_IPS address $ATTACKER_IP" \
      -c "commit" \
      -c "save"

logger -t event-handler "Successfully blocked $ATTACKER_IP"
```

### Автоматическое обновление DNS при изменении IP

`/config/scripts/update-dynamic-dns.py`:
```python
#!/usr/bin/env python3

import os
import re
import requests

def get_current_ip(message):
    """Извлечение IP адреса из сообщения"""
    ip_pattern = r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b'
    match = re.search(ip_pattern, message)
    return match.group(0) if match else None

def update_dns(ip_address):
    """Обновление DNS записи через API"""
    dns_provider_url = os.environ.get('DNS_API_URL')
    api_key = os.environ.get('DNS_API_KEY')
    hostname = os.environ.get('HOSTNAME')

    if not all([dns_provider_url, api_key, hostname]):
        print("DNS update configuration incomplete")
        return False

    try:
        response = requests.post(
            dns_provider_url,
            json={
                'hostname': hostname,
                'ip': ip_address,
            },
            headers={'Authorization': f'Bearer {api_key}'},
            timeout=10
        )
        return response.status_code == 200
    except Exception as e:
        print(f"Failed to update DNS: {e}")
        return False

def main():
    message = os.environ.get('message', '')
    ip = get_current_ip(message)

    if ip:
        print(f"Detected new IP: {ip}")
        if update_dns(ip):
            print("DNS updated successfully")
        else:
            print("Failed to update DNS")
    else:
        print("Could not extract IP address")

if __name__ == '__main__':
    main()
```

## Следующие шаги

- [SNMP](/docs/vyos/services/vyos-snmp/) - мониторинг через SNMP для интеграции с системами мониторинга
- [Syslog](/docs/vyos/system/vyos-syslog/) - настройка централизованного логирования
- [Scripting Guide](/docs/vyos/admin-guide/) - подробное руководство по созданию скриптов для VyOS

