Найти тему
Nag.news

Стек ELK - современный инструментарий мониторинга сети

Многолетнее использование rsyslog для хранения log-сообщений сетевого оборудования, и loganalyzer для их отображения, обозначило необходимость поиска, соответствующей современным требованиям, альтернативы. В результате анализа различных решений был сделан выбор в пользу open-source компонентов стека ELK.

Основными его элементами являются: Elasticsearch (search engine – для хранения и быстрого поиска структурированных данных), Logstash (collector – для приема в различном формате данных, их фильтрации и преобразования, и последующей отправки в различные базы данных) и Kibana (инструмент для визуализации), которые и составляют акроним ELK.

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

Расмотрим вариант установки ELK, его конфигурации, приема log-сообщений от сетевого оборудования, их обработки, создания графиков и таблиц, единого дашборда для отображения.

В качестве хоста для разворачивания стека был выбран Ubuntu Server 18.04 LTS, недавно обновленная до 7.7.0 версия ELK, сетевое оборудование Juniper. В отношении последнего, сразу оговорюсь, взято для примера). На самом деле обрабатывать сообщения, имеющие текстовый формат, в Logstash можно любые (любых вендоров).

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

Итак...

1) Обновляем пакеты операционной системы.

sudo apt-get update
sudo apt-get upgrade

2) Устанавливаем WEB-сервер nginx.

sudo apt install nginx -y

Проверяем nginx, введя в адресной строке браузера адрес хоста, на котором он установлен.

3) Устанавливаем Java.

sudo apt install default-jre -y
sudo apt install default-jdk -y

4) Установку Elasticsearch выполняем из репозитория (при этом следует отметить, что существует несколько вариантов установки).

Загрузка и установка ключей.

sudo wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

Установка пакета apt-transport-https.

sudo apt-get install apt-transport-https

Добавление репозитория в sources.list.

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list

Установка Elasticsearch.

sudo apt-get update && sudo apt-get install elasticsearch

Редактирование файла конфигурации Elasticsearch.

sudo nano /etc/elasticsearch/elasticsearch.yml

В нем необходимо заменить network.host: 192.168.0.1 на network.host: localhost

Было:
network.host: 192.168.0.1
Стало:
network.host: localhost

Запуск Elasticsearch.

sudo service elasticsearch start

Проверка статуса Elasticserach.

sudo service elasticsearch status

-2

Включение юнита Elasticserach в автозагрузку.

sudo systemctl enable elasticsearch

Проверка статуса через XGET:

curl -X GET localhost:9200

-3

5) Установка Kibana из репозитория, добавленного в sources.list ранее.

sudo apt-get update && sudo apt-get install kibana

Изменение конфигурации для kibana:

sudo nano /etc/kibana/kibana.yml

Было:

server.port: 5601

Стало:

server.port: 5601

Было:

server.host: "localhost"

Стало:

server.host: "localhost"

Было:

elasticsearch.hosts: ["http://localhost:9200"]

Стало:

elasticsearch.hosts: ["http://localhost:9200"]

Запуск Kibana.

sudo service kibana start
sudo service kibana status

-4

Включение юнита Kibana в автозагрузку.

sudo systemctl enable kibana

6) Создание учётной записи и проверка пользователя nginx (Важно! Opensource-ные пакеты ELK не предоставляют инструментов безопасности).

echo "lab:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users

Проверяем наличие пользователя в nginx:

cat /etc/nginx/htpasswd.users

7) Создаем файл с виртуальным сайтом для веб-сервера Nginx, выполнив команду.

sudo nano /etc/nginx/sites-available/elk

8) В этот файл добавляем следующую информацию:

server {
listen 80;
server_name <внешний IP-адрес веб-сервера>;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd.users;
location / {
proxy_pass http://localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Сохраняем изменения, используя сочетание клавиш CTRL+O, и завершаем редактирование, используя сочетание клавиш CTRL+X.

9) Активируем новую конфигурацию Nginx, выполнив команду.

sudo ln -s /etc/nginx/sites-available/elk /etc/nginx/sites-enabled/

10) Перезагружаем Kibana, выполнив команду.

sudo systemctl restart kibana

11) Перезагружаем веб-сервер Nginx, выполнив команду.

sudo systemctl restart nginx

12) Проверяем синтаксис конфигурационного файла nginx не отсутствие ошибок, выполнив команду.

sudo nginx -t

13) Установливаем Logstash.

sudo apt install logstash

14) Создаем конфигурационный файл для Logstash.

sudo nano /etc/logstash/conf.d/networklogs.conf

Вносим в него данные.

input {
udp {
port => 1514
type => "syslog"
tags => junos
add_field => {"_index_name" => "syslog"}
}
}

filter {
grok{
patterns_dir => ["/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns"]
match => {
"message" => [
"%{DATESTAMP:time_syslog} %{HOSTNAME:hostname} %{MSGSOURCE:msg_source}: %%{FACILITY:facility}-%{SEVERITY:severity}: %{MSGTEXT:msgtext}",
"%{DATESTAMP:time_syslog} %{HOSTNAME:hostname} %{MSGSOURCE:msg_source}: %%{FACILITY:facility}-%{SEVERITY:severity}-%{TAG:tag}: %{MSGTEXT:msgtext}",
"%{DATESTAMP:time_syslog} %{HOSTNAME:hostname} : %%{FACILITY:facility}-%{SEVERITY:severity}: %{MSGSOURCE:msgsource} %{TAG:tag}: %{MSGTEXT:msgtext}",
"%{DATESTAMP:time_syslog} %{HOSTNAME:hostname} : %%{FACILITY:facility}-%{SEVERITY:severity}: %{MSGTEXT:msgtext}",
"%{DATESTAMP:time_syslog} %{HOSTNAME:hostname} %{MSGTEXT:msgtext}"
]
}
}

mutate {
gsub => [
"severity", "0", "emergency",
"severity", "1", "alert",
"severity", "2", "critical",
"severity", "3", "error",
"severity", "4", "warning",
"severity", "5", "notice",
"severity", "6", "info",
"severity", "7", "any"
]
}
}

Enable stdout for debug
output {
if [type] == "syslog" {
stdout {
codec => rubydebug }
}
}

output {
# if [type] == "syslog" {
# elasticsearch {
# hosts => ["127.0.0.1:9200"]
# index => "juniperlogs"
# }
# }
#}

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

Из доступных фильтров используем grok, позволяющий парсить по regex.

Logstash содержит большое количество патернов для парсинга входящих данных. К сожалению, для распарсивания логов Juniper готовых нет.

Создаем файл сами:

sudo nano /usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/juniper-log

И вносим туда данные индексов и соответсвующих им регулярных выражений:

ID \d+
DATESTAMP (\w{3}\s+\d+ \d{2}:\d{2}:\d{2})
HOSTNAME (\w+\d+)
MSGSOURCE \S+
FACILITY \w+
SEVERITY \d
TAG \w+
MSGTEXT (\S+|\s+)+

Сохраняем файл.

15) Выполняем конфигурацию маршрутизаторов Juniper для отправки log-сообщений в Logstash.

lab@PE3# show system syslog
user * {
any emergency;
}
host 10.0.192.17 {
any any;
port 1514;
source-address 10.0.192.21;
explicit-priority;
}

Explicit-priority позволяет добавлять уровни facility и severity в формат обычных лог сообщений.

16) Проверяем корректность созданного конфигурационного файла для Logstash (ключ -t в конце строки).

sudo /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/networklogs.conf -t

Вывод:

-5

17) Запускаем logstash с нашим конфигурационным файлом.

sudo /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/networklogs.conf

В консоли на stdout отображаются поступающие лог-сообщения с маршрутизатора:

-6

18) Прерываем тест с помощью Ctrl+C.

19) Редактируем конфигурационный файл Logstash для отправки структурированных сообщений в Elasticsearch.

sudo nano /etc/logstash/conf.d/networklogs.conf

В нем необходимо закомментировать блок с stdout, и расскомментировать блок elasticsearch.

Было:

Enable stdout for debug
output {
if [type] == "syslog" {
stdout {
codec => rubydebug }
}
}

output {
# if [type] == "syslog" {
# elasticsearch {
# hosts => ["127.0.0.1:9200"]
# index => "juniperlogs"
# }
# }
#}

Стало:

Enable stdout for debug
output {
# if [type] == "syslog" {
# stdout {
# codec => rubydebug }
# }
#}

output {
if [type] == "syslog" {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "juniperlogs"
}
}
}

Сохраняем изменения и закрываем файл.

20) Запускаем Logstash.

sudo systemctl start logstash

21) Проверяем статус.

sudo systemctl status logstash

-7

22) Включаем юнит Logstash в автозагрузку:

sudo systemctl enable logstash

22) Запускаем Kibana в браузере используя ранее созданную в nginx учётную запись.

-8

23) Создаем индексы в Elasticsearch для принимаемых с Logstash структурированных сообщений.
Открываем:

Management/Index patterns/Create index pattern

В поле Index pattern указываем juniperlogs* и нажимаем Next step

-9

Выбираем на втором шаге в поле Time Filter field name параметр @timestamp и нажимаем кнопку Create index pattern. В результате получаем индексы значений в Elasticsearch.

24) 

-10

Прежде чем приступить к редактированию созданных индексов, созданию графиков, дашбордов, изменим тему Kibana на темную (Dark mode).

-11

Сохраняем изменения, нажав на кнопку Save changes внизу.

25) Изменяем параметры отображения на дашбордах для некоторых из индексов.

-12
-13

26) Создаем таблицу контроля за действиями сетевых инженеров на сетевом оборудовании.
Для этого слева на панели откроем вкладку Discover, добавим необходимые для отображения поля и включим фильтры для индекса msgtext по значениям user и command:

-14

Сохраняем таблицу под именем JuniperUserCommands.

27) Создаем таблицу отображения основных логов на сетевом оборудовании. Откроем снова вкладку Discover и добавим для отображения поля hostname, severity, message.

Создадим фильтры для исключения низкоприоритетных сообщений any, info, notice и сообщений о перерасчете label-switch-path.

Сохраним таблицу под названием JuniperLogsRealtime.

-15

28) Создадим несколько графиков для нашего дашборда. Открываем вкладку Visualize и нажимаем кнопку Create new visualization. Из предложенных вариантов графиков выберем Pie (круговая диаграмма).

-16

Сохраним график с названием JuniperLogsSeverityPie.

И еще несколько графиков гистограмм с различными фильтрами для отображения различных событий.

-17

График JuniperLogsSeverityHistogram. Его предназначение следует из названия.

-18

График JuniperProtocolsHistogram предназначен для отображения изменения состояния протоколов.

-19

График JuniperLogSeverityCriticalHistogram отображает количество событий степеней Emergency, Critical и Alert.

-20

JuniperLogAlarmHistogram для отображения аварийных сообщений типа Alarm.

-21

JuniperIfdHistogram предназначен для отображения изменений состояния сетевых интерфейсов.

29) Создадим сам дашборд и разместим на нем созданные графики и таблицы. Ниже приведен пример одного из вариантов.

-22

Период отображения можно установить как для дашборда в целом, так и для каждого из графиков в отдельности. Рекомендуемый refresh interval – 2 – 4 секунды. После сохранения скомпанованного дашборда доступно его отображение в режиме Full Screen. Редактирование любого из графиков и таблиц доступно из дашборда. Клик по событию на одном из графиков предоставляет возможность отображения по фильтру данного события на остальных графиках и в таблицах.

Таким образом, open-source вариант ELK позволяет создать соответствующую современным потребностям систему мониторинга сети.