graylog-deploy/vector-accel-ppp-setup.md
byrsapty 071d92000c Document Vector-side DHCP filtering to cut log volume before it hits Graylog
Motivated by live capacity math: 2 active NAS servers measured at ~634
bytes/document in Graylog and ~75 msg/s each; projected to 10+ servers of
similar profile that's ~38.5 GiB/day, which the current 50GB disk / 14-21
day retention can't hold. DHCP request/response chatter (Discover/Request/
Offer/Ack) is the bulk of that volume and isn't needed for RADIUS/
accounting analytics, so dropping it via a Vector `filter` transform
(before the packet ever leaves the NAS server) is the cheapest place to
cut it - no wasted network/disk/CPU on data nobody queries.

Also cross-referenced two things diagnosed live earlier: the
read_from: beginning cold-start replay burst, and where to look if a
filtered-out message type stops appearing (intentional, not a bug).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 15:43:51 +03:00

23 KiB
Raw Blame History

Vector: перетрансляція логів у Graylog (Debian)

Інструкція з встановлення та налаштування агента Vector для збору логів з окремих файлів (сервіси на кшталт accel-ppp, які не пишуть у syslog, а тільки у власний лог-файл) і пересилання їх на централізований Graylog по UDP. Використовується там, де сервіс не вміє писати напряму в syslog, або де потрібен більш гнучкий контроль над форматом і тегуванням повідомлень, ніж дає стандартний rsyslog.

Зміст

Огляд архітектури

/var/log/accel-ppp/accel-ppp.log ──┐
/var/log/freeradius/radius.log ────┼──▶  Vector  ──▶  UDP:5140  ──▶  Graylog
/var/log/<інший файл>.log ──────────┘   (read + tag + forward)      (Servers Syslog input)

Кожен лог-файл — це окреме джерело (source) у Vector. Кожне джерело проходить через своє перетворення (transform), яке додає тег і метадані. Усі перетворення збираються в одне призначення (sink), яке одним UDP-потоком шле все на Graylog. Додавання нового файлу логів = один новий source + один новий transform + один рядок у списку inputs існуючого sink — сам sink і адреса Graylog не міняються.

Передумови

  • Операційна система: Debian Linux (11/12)
  • Сервіс, що пише лог у файл (наприклад accel-ppp, freeradius)
  • Доступ до сервера під root або користувачем із sudo
  • Адреса Graylog-сервера: 10.254.254.202:5140 (UDP, вхід "Servers Syslog (RADIUS-accel-ppp)")
  • Порт 5140/udp відкритий між цим сервером і Graylog (перевірте firewall/маршрутизацію заздалегідь — Vector мовчки "губить" пакети, якщо порт недоступний, без явної помилки)

Крок 1. Встановлення Vector

  1. Додайте офіційний репозиторій Vector і встановіть його:

    bash -c "$(curl -sSfL https://setup.vector.dev)"
    sudo apt update
    sudo apt install vector -y
    
  2. Перевірте, що встановилось коректно:

    vector --version
    

Крок 2. Базова конфігурація (приклад: accel-ppp)

  1. Створіть конфігураційний файл:

    sudo nano /etc/vector/vector.yaml
    
  2. Вставте базову конфігурацію. Це робочий приклад для accel-ppp — використовуйте його як шаблон і довідку, коли додаватимете інші джерела в кроці 5:

    # ==========================================
    # 1. ДЖЕРЕЛА (Sources) — які файли читати
    # ==========================================
    sources:
      accel_ppp_log:
        type: "file"
        include:
          - "/var/log/accel-ppp/accel-ppp.log"
        read_from: "beginning"
    
    # ==========================================
    # 2. ПЕРЕТВОРЕННЯ (Transforms) — тегування джерела
    # ==========================================
    transforms:
      format_for_graylog:
        type: "remap"
        inputs:
          - "accel_ppp_log"
        source: |
          # Додаємо лише ім'я хоста спереду, як префікс — оригінальний
          # рядок логу accel-ppp лишається без змін. Саме під його формат
          # написані pipeline rules у Graylog (interface, RADIUS-атрибути
          # тощо), тож його не можна перекручувати.
          .message = "[" + get_hostname!() + "] " + to_string!(.message)
    
    # ==========================================
    # 3. ПРИЗНАЧЕННЯ (Sinks) — куди відправляти
    # ==========================================
    sinks:
      graylog_out:
        type: "socket"
        inputs:
          - "format_for_graylog"
        address: "udp://10.254.254.202:5140"
        mode: "udp"
        encoding:
          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. Перевірте синтаксис перед запуском:

    vector validate /etc/vector/vector.yaml
    

    Якщо є помилка — vector validate вкаже точний рядок і причину; не запускайте службу, поки ця команда не відповість без помилок.

Крок 2b. (Опційно) Фільтрація DHCP-шуму

Навіщо: accel-ppp при кожній оренді/оновленні DHCP пише повний обмін (recv [DHCPv4 Discover...], send [DHCPv4 Ack...] тощо) — це основна частина обсягу логів, а не RADIUS/accounting-дані, заради яких власне і збирається моніторинг. Порахували наживо на реальних цифрах (2 активні NAS-сервери, ~634 байти/повідомлення в Graylog): при масштабуванні до 10+ таких серверів це ~38.5 GiB/добу лише "сирих" даних — диск, розрахований на 14-21 день retention, заповниться за лічені дні. Прибирання DHCP на рівні Vector (до того, як пакет узагалі покине цей сервер) — найдешевший спосіб скоротити обсяг, бо не витрачається ні мережевий трафік, ні дисковий IO/CPU Graylog на індексацію того, що однаково ніхто не шукає.

Додайте filter-transform між format_for_graylog і sinks:

transforms:
  format_for_graylog:
    # ... як у кроці 2, без змін ...

  # Прибирає DHCP-обмін (Discover/Request/Offer/Ack) - основний обсяг
  # шуму, не потрібний для RADIUS/accounting-аналітики. Умова true =
  # повідомлення проходить далі; тут - "якщо НЕ містить маркер DHCPv4".
  drop_dhcp_noise:
    type: "filter"
    inputs:
      - "format_for_graylog"
    condition: '!contains(string!(.message), "[DHCPv4 ")'

sinks:
  graylog_out:
    type: "socket"
    inputs:
      - "drop_dhcp_noise"   # було "format_for_graylog" - тепер через фільтр
    address: "udp://10.254.254.202:5140"
    mode: "udp"
    encoding:
      codec: "text"

Перевірка після зміни:

vector validate /etc/vector/vector.yaml
sudo systemctl restart vector
sudo journalctl -u vector -f   # переконайтесь, що йдуть RADIUS-рядки, а DHCPv4 - ні

Якщо для якогось джерела DHCP-дані навпаки потрібні (наприклад, окремий DHCP-сервер, а не accel-ppp) — просто не додавайте drop_dhcp_noise у ланцюжок цього джерела; фільтр застосовується лише до того transform, який у нього inputs.

Крок 3. Права доступу (запуск від root)

Лог-файли на кшталт accel-ppp.log часто мають права 600 (читає лише власник, зазвичай root), тож стандартний користувач vector не зможе їх прочитати. Найпростіше рішення — запускати службу від root.

Альтернатива, якщо не хочете давати vector права root: додайте користувача vector у групу-власника файлу (usermod -aG <група> vector) і виставте на файл права 640. Це вужче за обсягом, але вимагає стежити за правами при кожному новому джерелі логів. Для простоти цей гайд іде шляхом root.

  1. Відкрийте редактор перевизначення systemd-юніта:

    sudo systemctl edit vector
    
  2. У порожні рядки вгорі файлу вставте:

    [Service]
    User=root
    Group=root
    
  3. Збережіть і закрийте (Ctrl+O, Enter, Ctrl+X).

Крок 4. Запуск та перевірка роботи

  1. Перечитайте конфігурацію systemd і запустіть Vector з автозавантаженням:

    sudo systemctl daemon-reload
    sudo systemctl enable --now vector
    
  2. Перевірте статус і логи в реальному часі:

    sudo systemctl status vector
    sudo journalctl -u vector -f
    

    Успішний результат — рядок виду:

    INFO source{...}: Found new file to watch. file=/var/log/accel-ppp/accel-ppp.log
    

    без жодних Permission denied.

  3. Згенеруйте тестовий рядок у файлі логу і перевірте, що він долетів до Graylog (System → Inputs → відповідний input → "Received messages", або Search з широким часовим діапазоном):

    echo "vector test line $(date)" | sudo tee -a /var/log/accel-ppp/accel-ppp.log
    

Крок 5. Додавання інших джерел логів

Щоб додати ще один лог-файл (наприклад, FreeRADIUS, або будь-який інший сервіс, що пише у файл), потрібні три зміни в /etc/vector/vector.yaml: новий source, новий transform, і додати назву цього transform у список inputs існуючого sink. Сам sink (адреса Graylog) лишається один — усі джерела йдуть через нього.

Шаблон

sources:
  <унікальнаазва_джерела>:
    type: "file"
    include:
      - "<повний шлях до файлу логів>"
    read_from: "beginning"

transforms:
  <унікальнаазва_transform>:
    type: "remap"
    inputs:
      - "<унікальнаазва_джерела>"
    source: |
      .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):

sinks:
  graylog_out:
    type: "socket"
    inputs:
      - "format_for_graylog"          # вже було (accel-ppp)
      - "<унікальнаазва_transform>"  # новий рядок
    address: "udp://10.254.254.202:5140"
    mode: "udp"
    encoding:
      codec: "text"

Правила іменування, щоб уникнути конфліктів при кількох джерелах:

  • назва source і transform мають бути унікальними в межах усього конфігураційного файлу (не тільки в межах одного сервісу);
  • tag — це те, за чим ви шукатимете в Graylog (tag:radius-server тощо), тож робіть його осмисленим і не повторюваним для різних сервісів.

Готовий приклад: додавання логу FreeRADIUS

sources:
  # ... accel_ppp_log вже є ...
  freeradius_log:
    type: "file"
    include:
      - "/var/log/freeradius/radius.log"
    read_from: "beginning"

transforms:
  # ... format_for_graylog вже є ...
  format_freeradius_for_graylog:
    type: "remap"
    inputs:
      - "freeradius_log"
    source: |
      .message = "[" + get_hostname!() + "] " + to_string!(.message)

sinks:
  graylog_out:
    type: "socket"
    inputs:
      - "format_for_graylog"
      - "format_freeradius_for_graylog"
    address: "udp://10.254.254.202:5140"
    mode: "udp"
    encoding:
      codec: "text"

Після будь-якої зміни конфігурації:

vector validate /etc/vector/vector.yaml   # спершу перевірити синтаксис
sudo systemctl restart vector             # застосувати
sudo journalctl -u vector -f              # переконатись, що нове джерело підхопилось

Якщо новий лог-файл має інші права доступу/власника — переконайтесь, що користувач, від якого запущено Vector (за кроком 3 — root), може його прочитати, інакше повторите проблему з кроку 3 для нового файлу.

Крок 6. Прибирання старих правил rsyslog

Якщо раніше для відправки логів цього файлу використовувався rsyslog (наприклад, через модуль imfile), після переходу на Vector варто прибрати дублюючі правила, щоб те саме повідомлення не потрапляло в Graylog двічі з різними форматами.

  1. Відкрийте конфігурацію rsyslog (/etc/rsyslog.conf або файли у /etc/rsyslog.d/).

  2. Знайдіть і видаліть/закоментуйте правила з модулем imfile, тегом, що відповідає файлу (наприклад accel-remote-only), і командою видалення повідомлення (~, щоб воно не йшло далі за замовчуванням).

  3. Перезапустіть rsyslog:

    sudo systemctl restart rsyslog
    

Діагностика проблем

Симптом Ймовірна причина Що перевірити
Permission denied у journalctl -u vector Vector не має прав читати лог-файл Крок 3 виконано? ls -la <файл> — хто власник і які права
Служба запущена, файл читається, але в Graylog нічого немає Порт 5140 недоступний з цього сервера (firewall/маршрутизація) nc -u -zv 10.254.254.202 5140 з цього сервера; tcpdump -i eth0 udp port 5140 на стороні Graylog
vector validate видає помилку Помилка синтаксису YAML або VRL у transform Читайте повідомлення про помилку — воно вказує точний рядок; перевірте відступи (YAML чутливий до пробілів)
Повідомлення доходять, але без полів 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); якщо побачите знову — перевірте, чи не відкотилось це правило
DHCP-рядки більше не з'являються в Graylog Це очікувано, якщо додано drop_dhcp_noise з кроку 2b Перевірте vector.yaml — якщо DHCP-дані все ж потрібні, приберіть цей transform з ланцюжка inputs sink'у
Алерт "abnormal message volume" щойно після першого запуску Vector на новому сервері read_from: "beginning" (крок 2) означає, що при першому старті Vector вичитує весь наявний лог-файл одразу, а не тільки нові рядки — одноразовий сплеск, не триваюча проблема Перевірте обсяг від цього джерела через кілька хвилин (gl2_remote_ip:<ip> у Search) — має впасти до звичайного рівня

Довідка: структура конфігурації

  • sources — звідки Vector бере дані. Тип file = читає (і "хвостить") вказаний файл, read_from: "beginning" = при першому запуску прочитати файл з початку (а не тільки нові рядки).
  • transforms (тип remap) — обробка даних мовою VRL (Vector Remap Language). У цьому гайді використовується лише конкатенація рядків ("[" + get_hostname!() + "] " + to_string!(.message)), щоб додати ідентифікацію хоста, не чіпаючи оригінальний формат рядка логу — саме під цей оригінальний формат написані pipeline rules у Graylog. to_string!() потрібен тому, що VRL вимагає явно гарантувати тип рядка перед конкатенацією (! означає "перервати обробку цього повідомлення, якщо не вдалось" — тут це станеться хіба що для зовсім нетипових вхідних даних).
  • sinks (тип socket, mode: "udp") — куди й як відправляти результат. Один sink може приймати від багатьох transforms одночасно (список inputs) — саме так додаються нові джерела логів без створення нового sink чи нової адреси.