Всем привет, хочу поделиться своим опытом по реализации сбора syslog с маршрутизаторов Juniper. Изначально хотел использовать под эту задачу zabbix так, как он уже используется в рабочей сети как основная система мониторинга, но после анализа различных источников на эту тему, понял, что он просто не справится с такой нагрузкой. Исходя из этого, было принято решения использовать инструменты заточенные под сбор логов. Первое что пришло в голову, это связка promtail-loki-grafana так, как она достаточно быстро и просто реализуема. Всё бы ничего, но в процессе отладки, promtail не удавалось распарсить syslog с маршрутизаторов. Погуглив ошибку, выяснилось, что маршрутизаторы отправляют syslog с небольшим отклонением от формата RFC, заложенного в promtail. Таким образом, новая задача состояла в преобразовании syslog к надлежащему виду, с помощью какого-либо инструмента, и таким инструментом стал Vector. Vector отлично подходит для работы с логами сетевых устройств. После определения новой связки: vector-loki-grafana, я приступил к созданию конфигурационных файлов для vector и loki.

vector.toml

data_dir = "/var/lib/vector"

[sources.syslog_514]
type = "syslog"
address = "0.0.0.0:514" # порт для приема syslog с устройств Juniper
mode = "udp"

[sources.syslog_515]
type = "syslog"
address = "0.0.0.0:515" # порт для приема syslog с устройств Cisco
mode = "udp"

[transforms.filter_severity]
type = "filter"
inputs = [ "syslog_514", "syslog_515" ]
condition = """
!includes(["debug"], .severity)
"""

[transforms.check_labels]
type = "remap"
inputs = ["filter_severity"]
source = '''
if !exists(.host) || !exists(.severity) {
  log("Missing required fields: host or severity", level: "error")
  abort
}

if is_string(.host) {
  .host = replace!(.host, "/", "_")
} else {
  host_str, err = to_string(.host)
  if err != null {
    log("Failed to convert host to string: " + err, level: "error")
    host_str = "unknown_host"
  }
  log("Host is not a string: " + host_str, level: "error")
  .host = "unknown_host"  # Значение по умолчанию
}

'''

[sinks.my_sink_id]
type = "loki"
inputs = [ "check_labels" ]
endpoint = "http://localhost:3100"

  [sinks.my_sink_id.encoding]
  codec = "json"

  [sinks.my_sink_id.labels]
  host = "{{ host }}" # для отображения syslog по каждому хосту
  severity = "{{ severity }}" # для отображения syslog по уровням важности
  log_type = "all_logs"  # для отображения syslog всех хостов

[sinks.file_syslog]
type = "file"
inputs = [ "filter_severity" ]
healthcheck = true
path = "/var/log/vector/vector-%Y-%m-%d.log"

  [sinks.file_syslog.encoding]
  codec = "text"  # Указываем кодировку для файлового вывода

loki-config.yaml

auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

common:
  instance_addr: 127.0.0.1
  path_prefix: /tmp/loki
  storage:
    filesystem:
      chunks_directory: /tmp/loki/chunks
      rules_directory: /tmp/loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

query_range:
  results_cache:
    cache:
      embedded_cache:
        enabled: true
        max_size_mb: 100

schema_config:
  configs:
    - from: 2020-10-24
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

ruler:
  alertmanager_url: http://localhost:9093

После подготовки основных конфигурационных файлов, я приступил к развертыванию непосредственно самих инструментов. Наиболее быстрым и удобным решением для этого, является использование docker-compose.

Docker-compose.yml

services:
    loki:
      image: grafana/loki:3.2.1
      container_name: loki
      ports:
        - "3100:3100"
      volumes:
        - ./:/mnt/config
      command: -config.file=/mnt/config/loki-config.yaml # Указание конфигурационного файла
      restart: unless-stopped
    grafana:
      hostname: grafana
      environment:
        - GF_PATHS_PROVISIONING=/etc/grafana/provisioning
        - GF_AUTH_ANONYMOUS_ENABLED=true
        - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
        - TZ=${SYSTEM_TIMEZONE:-Europe/Moscow}
      image: grafana/grafana:latest
      ports:
        - "3000:3000"
    vector:
      image: timberio/vector:latest-alpine  # Официальный образ Vector
      container_name: vector
      restart: unless-stopped
      ports:
        - "514:514/udp"  # Порт для syslog Juniper
        - "515:515/udp"  # Порт для syslog Cisco
      volumes:
        - ./vector.toml:/etc/vector/vector.toml  # Подключение конфигурации
      environment:
        - VECTOR_CONFIG=/etc/vector/vector.toml  # Указание конфигурационного файла

Инициировал запуск контейнеров с помощью команды: "docker-compose up -d", из директории в которой располагается конфигурационный файл docker-compose.yml. После того как, все контейнеры подгрузились, проверил их состояние: "docker ps -a".

После развертывания можно убедится в корректности функционирования каждого сервиса. Работоспособность grafana, проверяется по адресу: "http://localhost:3100/". Проверка loki осуществляется с помощью выполнения HTTP-запроса к API Loki: http://localhost:3100/ready.

Ожидаемый ответ:

ready

Проверку работы vector, я осуществлял посредством анализа логов контейнера: "docker logs vector".

Теперь, когда все необходимые инструменты развернуты, остается произвести конфигурацию сетевых устройств, для отправки их syslog на сокет vector. В маршрутизаторах и коммутаторах juniper достаточно прописать следующие команды:

set system syslog host <ip-адрес vector> any any
set system syslog host <ip-адрес vector> port 514
set system syslog host <ip-адрес vector> facility-override local7
set system syslog host <ip-адрес vector> structured-data

Изменить конфигурацию можно двумя способами:

1) Подключиться к устройству и прописать вручную

2) Написать playbook, и с помощью Ansible изменить конфигурацию

Я выбрал второй вариант, так как изменять конфигурацию на каждом устройстве вручную, достаточно долгое занятие, особенно в крупных сетях.

Примерный вариант используемого мной playbook:

---
- name: "logs"
  hosts: junos
  connection: local
  gather_facts: no
  collections: juniper.device

  tasks:
      - name: "logs"
        junipernetworks.junos.junos_config:
          lines:
            - "set system syslog host <ip-сервера> any any"
            - "set system syslog host <ip-сервера> port 514"
            - "set system syslog host <ip-сервера> facility-override local7"
            - "set system syslog host <ip-сервера> structured-data"
          commit: yes

В целях проверки, отправляемых сетевыми узлами syslog, можно на стороне сервера с помощью команды: "sudo tcpdump -i any port 514" осуществить прослушивание порта.

В целом, система уже собирает логи, остается только решить задачу визуализации данных , посредством создания dashboard в Grafana, но тут как говорится: "на вкус и цвет товарищей нет". Поэтому, я покажу какие варианты панелей на мой взгляд имеют место быть. Но для начала, необходимо подключить Loki к Grafana, как новый источник данных. Заходим в Grafana по адресу http://<ip-сервера>:3000, переходим в вкладку "Connections" и выбираем "Data sources" - "+ Add new data source". Далее, с помощью поисковой строки находим и выбираем "Loki", в случае если grafana и loki располагаются на одном устройстве, достаточно указать указать в разделе Connection url: http://localhost:3100, в противном случае указать ip-сервера на котором развернут Loki. После чего сохраняем новый источник данных "save & test".

Panel №1. Вывод Logs

Переходим в "Dashboards" - "New" - "New dashboard" - "Add Visualization" - "Loki"

1 - Выбираем тип Logs; 2 - Задаем название panel; 3 - Включаем временные метки; 4 - Создаем запрос. Результатом запроса будет вывод всех syslog со всех устройств. После чего обновляем значение "Run query", получаем вывод syslog и сохраняем.

Далее добавляем средства поиска и фильтрации, выводимых syslog.

Переходим в выделенную красным цветом, вкладку - "Dashboard settings" - "Variables" - "Add variable" и действуем как показано ниже.

Проделываем аналогичные действия по созданию поля метки "Severity". После этого добовляем filter, как показано на рисунке ниже.

В результате проделанных действий, получается панель с выводом syslog и поисковой системой с фильтрацией.

панель с выводом syslog и поисковой системой
панель с выводом syslog и поисковой системой

Panel №2. Bar gauge and Pie chart

Панель отображения статистики хоста создается согласно следующего изображения.

Настройка панели отображения статистики хоста
Настройка панели отображения статистики хоста

Пример запроса:

sum by(severity) (
    count_over_time({host="RLIK-Krasnoyrsk-Olive"} [$__range])
)

Точное имя хоста можно взять при выборе метки в режиме "Builder"

С аналогичной информативностью представляется возможным, построить и круговую диаграмму "Pie chart"

Настройка круговой диаграммы "Pie chart"
Настройка круговой диаграммы "Pie chart"

Пример запроса аналогичный, отличаться будет только имя хоста или использование метки для анализа всех syslog. На основе информации представленной выше вы можете собрать dashboard как на изображении ниже, исходя из своих интересов.

Dashboard - syslog
Dashboard - syslog

Заключение

Таким образом, используя инструменты Vector, Loki и Grafana, посредством не сложных манипуляций можно собрать достаточно хорошую систему сбора и анализа логов с сетевых устройств. Благодаря грамотной конфигурации Vector и правильно составленного dashboard в Grafana вы сможете: своевременно выявлять сетевые сбои и проблемы, отслеживать производительность, обнаруживать атаки и многое другое, что поможет вам успешно заниматься администрированием сети.

Комментарии (0)