Thank you for reading this post, don't forget to subscribe!
1.Установка Elasticsearch
1.1.Настройка Elasticsearch
2.Установка Kibana
2.1.Настройка Kibana
3.Установка и настройка Logstash
4.Установка Filebeat и отправка логов в Logstash
5.Установка и настройка Winlogbeat
6.Настройка безопасности и авторизация в Kibana
7.Проксирование подключений к Kibana через Nginx
8.Автоматическая очистка индексов в elasticsearch
- Elasticsearch используется для хранения, анализа, поиска по логам.
- Kibana представляет удобную и красивую web панель для работы с логами.
- Logstash сервис для сбора логов и отправки их в Elasticsearch. В самой простой конфигурации можно обойтись без него и отправлять логи напрямую в еластик. Но с logstash это делать удобнее.
- Beats - агенты для отправки логов в Logstash или Elasticsearch. Они бывают разные. Я буду использовать Filebeat для отправки данных из текстовых логов linux и Winlogbeat для отправки логов из журналов Windows систем.
К этой связке еще добавляется Nginx, который проксирует соединения в Kibana. В самом простом случае он не нужен, но с ним удобнее. Можно, к примеру, добавить авторизацию или ssl сертификат, в nginx удобно управлять именем домена. В случае большой нагрузки, разные службы разносятся по разным серверам или кластерам. В своем примере я все установлю на один сервер. Схематично работу данной системы можно изобразить вот так:
Для установки одиночного инстанса с полным набором компонентов ELK необходимы следующие системные ресурсы.
минимальные | рекомендуемые | |
CPU | 2 | 4+ |
Memory | 6 Gb | 8+ Gb |
Disk | 10 Gb | 10+ Gb |
Некоторое время назад для тестовой установки ELK Stack достаточно было 4 Gb оперативной памяти. На текущий момент с версией 7.15 у меня не получилось запустить одновременно Elasticsearch, Logstash и Kibana на одной виртуальной машине с четырьмя гигабайтами памяти. После того, как увеличил до 6, весь стек запустился. Но для комфортной работы с ним нужно иметь не менее 8 Gb и 4 CPU. Если меньше, то виртуальная машина начинает тормозить, очень долго перезапускаются службы. Работать некомфортно.
В системных требованиях для ELK я указал диск в 10 Gb. Этого действительно хватит для запуска стека и тестирования его работы на небольшом объеме данных. В дальнейшем, понятное дело, необходимо ориентироваться на реальный объем данных, которые будут храниться в системе.
Установка Elasticsearch
Устанавливаем ядро системы по сбору логов - Elasticsearch. Его установка очень проста за счет готовых пакетов под все популярные платформы.
Centos 7 / 8
Копируем публичный ключ репозитория:
# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
Подключаем репозиторий Elasticsearch:
# mcedit /etc/yum.repos.d/elasticsearch.repo
1 2 3 4 5 6 7 8 |
[elasticsearch] name=Elasticsearch repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=0 autorefresh=1 type=rpm-md |
Приступаем к установке еластика:
# yum install --enablerepo=elasticsearch elasticsearch
В в завершении установки добавим elasticsearch в автозагрузку и запустим его с дефолтными настройками:
# systemctl daemon-reload
# systemctl enable elasticsearch.service
# systemctl start elasticsearch.service
Проверяем, запустилась ли служба:
# systemctl status elasticsearch.service
Проверим теперь, что elasticsearch действительно нормально работает. Выполним к нему простой запрос о его статусе.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# curl 127.0.0.1:9200 { "name" : "centos8", "cluster_name" : "elasticsearch", "cluster_uuid" : "XSsvp-nvTxi68TaEFN_OUg", "version" : { "number" : "7.15.1", "build_flavor" : "default", "build_type" : "rpm", "build_hash" : "83c34f456ae29d60e94d886e455e6a3409bba9ed", "build_date" : "2021-10-07T21:56:19.031608185Z", "build_snapshot" : false, "lucene_version" : "8.9.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } |
Все в порядке, сервис реально запущен и отвечает на запросы.
Ubuntu / Debian
Копируем себе публичный ключ репозитория:
# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
Если у вас нет пакета apt-transport-https, то надо установить:
# apt install apt-transport-https
Добавляем репозиторий Elasticsearch в систему:
# echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
Устанавливаем Elasticsearch на Debian или Ubuntu:
# apt update && apt install elasticsearch
После установки добавляем elasticsearch в автозагрузку и запускаем.
# systemctl daemon-reload
# systemctl enable elasticsearch.service
# systemctl start elasticsearch.service
Проверяем, запустился ли он:
# systemctl status elasticsearch.service
Проверим теперь, что elasticsearch действительно нормально работает. Выполним к нему простой запрос о его статусе.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# curl 127.0.0.1:9200 { "name" : "debian10", "cluster_name" : "elasticsearch", "cluster_uuid" : "zsYgZQSeY6uvhWCkFJPiAA", "version" : { "number" : "7.15.1", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "8ced7813d6f16d2ef30792e2fcde3e755795ee04", "build_date" : "2021-10-07T21:56:19.031608185Z", "build_snapshot" : false, "lucene_version" : "8.9.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } |
Если все в порядке, то переходим к настройке Elasticsearch.
Настройка Elasticsearch
Настройки Elasticsearch находятся в файле /etc/elasticsearch/elasticsearch.yml. На начальном этапе нас будут интересовать следующие параметры:
path.data: /var/lib/elasticsearch # директория для хранения данных
network.host: 127.0.0.1 # слушаем только локальный интерфейс
По умолчанию Elasticsearch слушает localhost. Нам это и нужно, так как данные в него будет передавать logstash, который будет установлен локально. Обращаю отдельное внимание на параметр для директории с данными. Чаще всего они будут занимать значительное место, иначе зачем нам Elasticsearch 🙂 Подумайте заранее, где вы будете хранить логи. Все остальные настройки я оставляю дефолтными. После изменения настроек, надо перезапустить службу:
# systemctl restart elasticsearch.service
Смотрим, что получилось:
1 2 |
# netstat -tulnp | grep 9200 tcp6 0 0 127.0.0.1:9200 :::* LISTEN 19788/java |
Elasticsearch повис на локальном интерфейсе. Причем я вижу, что он слушает ipv6, а про ipv4 ни слова. Но его он тоже слушает, так что все в порядке. Переходим к установке Kibana. Если вы хотите, чтобы elasticsearch слушал все сетевые интерфейсы, настройте параметр:
1 |
network.host: 0.0.0.0 |
Только не спешите сразу же запускать службу. Если запустите, получите ошибку:
1 2 3 4 |
[2021-10-18T10:41:51,062][ERROR][o.e.b.Bootstrap ] [centos8] node validation exception [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch. bootstrap check failure [1] of [1]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured |
Чтобы ее избежать, дополнительно надо добавить еще один параметр:
discovery.seed_hosts: ["127.0.0.1", "[::1]"]
Этим мы указываем, что хосты кластера следует искать только локально.
Установка Kibana
Дальше устанавливаем web панель Kibana для визуализации данных, полученных из Elasticsearch. Тут тоже ничего сложного, репозиторий и готовые пакеты есть под все популярные платформы. Репозитории и публичный ключ для установки Kibana будут такими же, как в установке Elasticsearch. Но я еще раз все повторю для тех, кто будет устанавливать только Kibana, без всего остального. Это продукт законченный и используется не только в связке с Elasticsearch.
Centos
Импортируем ключ репозитория:
# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
Добавляем конфиг репозитория:
# mcedit /etc/yum.repos.d/kibana.repo
1 2 3 4 5 6 7 8 |
[kibana-7.x] name=Kibana repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md |
Запускаем установку Kibana:
# yum install kibana
Добавляем Кибана в автозагрузку и запускаем:
# systemctl daemon-reload
# systemctl enable kibana.service
# systemctl start kibana.service
Проверяем состояние запущенного сервиса:
# systemctl status kibana.service
По умолчанию, Kibana слушает порт 5601. Только не спешите его проверять после запуска. Кибана стартует долго. Подождите примерно минуту и проверяйте.
1 2 |
# netstat -tulnp | grep 5601 tcp 0 0 127.0.0.1:5601 0.0.0.0:* LISTEN 20746/node |
Ubuntu/Debian
Установка Kibana на Debian или Ubuntu такая же, как и на центос - подключаем репозиторий и ставим из deb пакета. Добавляем публичный ключ:
# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
Добавляем рпозиторий Kibana:
# echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-7.x.list
Запускаем установку Kibana:
# apt update && apt install kibana
Добавляем Кибана в автозагрузку и запускаем:
# systemctl daemon-reload
# systemctl enable kibana.service
# systemctl start kibana.service
Проверяем состояние запущенного сервиса:
# systemctl status kibana.service
По умолчанию, Kibana слушает порт 5601. Только не спешите его проверять после запуска. Кибана стартует долго. Подождите примерно минуту и проверяйте.
1 2 |
# netstat -tulnp | grep 5601 tcp 0 0 127.0.0.1:5601 0.0.0.0:* LISTEN 1487/node |
Настройка Kibana
Файл с настройками Кибана располагается по пути - /etc/kibana/kibana.yml. На начальном этапе можно вообще ничего не трогать и оставить все как есть. По умолчанию Kibana слушает только localhost и не позволяет подключаться удаленно. Это нормальная ситуация, если у вас будет на этом же сервере установлен nginx в качестве reverse proxy, который будет принимать подключения и проксировать их в Кибана. Так и нужно делать в production, когда системой будут пользоваться разные люди из разных мест. С помощью nginx можно будет разграничивать доступ, использовать сертификат, настраивать нормальное доменное имя и т.д. Если же у вас это тестовая установка, то можно обойтись без nginx. Для этого надо разрешить Кибана слушать внешний интерфейс и принимать подключения. Измените параметр server.host, указав ip адрес сервера, например вот так:
server.host: "10.20.1.23"
Если хотите, чтобы она слушала все интерфейсы, укажите в качестве адреса 0.0.0.0. После этого Kibana надо перезапустить:
# systemctl restart kibana.service
Теперь можно зайти в веб интерфейс по адресу http://10.20.1.23:5601.
Можно продолжать настройку и тестирование, а когда все будет закончено, запустить nginx и настроить проксирование. Я настройку nginx оставлю на самый конец. В процессе настройки буду подключаться напрямую к Kibana. При первом запуске Kibana предлагает настроить источники для сбора логов. Это можно сделать, нажав на Add your data. К сбору данных мы перейдем чуть позже, так что можете просто изучить интерфейс и возможности этой веб панели
Периодически вы можете видеть в веб интерфейсе предупреждение:
server.publicBaseUrl is missing and should be configured when running in a production environment. Some features may not behave correctly.
Чтобы его не было, просто добавьте в конфиг Kibana параметр:
server.publicBaseUrl: "http://10.20.1.23:5601/"
Или доменное имя, если используете его.
Установка и настройка Logstash
Logstash устанавливается так же просто, как Elasticsearch и Kibana, из того же репозитория. Не буду еще раз показывать, как его добавить. Просто установим его и добавим в автозагрузку. Установка Logstash в Centos:
# yum install logstash
Установка Logstash в Debian/Ubuntu:
# apt install logstash
Добавляем logstash в автозагрузку:
# systemctl enable logstash.service
Запускать пока не будем, надо его сначала настроить. Основной конфиг logstash лежит по адресу /etc/logstash/logstash.yml. Я его не трогаю, а все настройки буду по смыслу разделять по разным конфигурационным файлам в директории /etc/logstash/conf.d. Создаем первый конфиг input.conf, который будет описывать прием информации с beats агентов.
1 2 3 4 5 |
input { beats { port => 5044 } } |
Тут все просто. Указываю, что принимаем информацию на 5044 порт. Этого достаточно. Если вы хотите использовать ssl сертификаты для передачи логов по защищенным соединениям, здесь добавляются параметры ssl. Я буду собирать данные из закрытого периметра локальной сети, у меня нет необходимости использовать ssl. Теперь укажем, куда будем передавать данные. Тут тоже все относительно просто. Рисуем конфиг output.conf, который описывает передачу данных в Elasticsearch.
1 2 3 4 5 6 7 |
output { elasticsearch { hosts => "localhost:9200" index => "nginx-%{+YYYY.MM.dd}" } #stdout { codec => rubydebug } } |
Что мы настроили? Передавать все данные в elasticsearch под указанным индексом с маской в виде даты. Разбивка индексов по дням и по типам данных удобна с точки зрения управления данными. Потом легко будет выполнять очистку данных по этим индексам. Я закомментировал последнюю строку. Она отвечает за логирование. Если ее включить, то все поступающие данные logstash будет отправлять дополнительно в системный лог. В centos это /var/log/messages. Используйте только во время отладки, иначе лог быстро разрастется дублями поступающих данных. Остается последний конфиг с описанием обработки данных. Тут начинается небольшая уличная магия, в которой я разбирался некоторое время. Расскажу ниже. Рисуем конфиг filter.conf.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
filter { if [type] == "nginx_access" { grok { match => { "message" => "%{IPORHOST:remote_ip} - %{DATA:user} \[%{HTTPDATE:access_time}\] \"%{WORD:http_method} %{DATA:url} HTTP/%{NUMBER:http_version}\" %{NUMBER:response_code} %{NUMBER:body_sent_bytes} \"%{DATA:referrer}\" \"%{DATA:agent}\"" } } } date { match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ] } geoip { source => "remote_ip" target => "geoip" add_tag => [ "nginx-geoip" ] } } |
Первое, что делает этот фильтр, парсит логи nginx с помощью grok, если указан соответствующий тип логов, и выделяет из лога ключевые данные, которые записывает в определенные поля, чтобы потом с ними было удобно работать. С обработкой логов у новичков возникает недопонимание. В документации к filebeat хорошо описаны модули, идущие в комплекте, которые все это и так уже умеют делать из коробки, нужно только подключить соответствующий модуль.
Модули filebeat работают только в том случае, если вы отправляете данные напрямую в Elasticsearch. На него вы тоже ставите соответствующий плагин и получаете отформатированные данные с помощью elastic ingest. Но у нас работает промежуточное звено Logstash, который принимает данные. С ним плагины filebeat не работают, поэтому приходится отдельно в logstash парсить данные. Это не очень сложно, но тем не менее. Как я понимаю, это плата за удобства, которые дает logstash. Если у вас много разрозненных данных, то отправлять их напрямую в Elasticsearch не так удобно, как с использованием предобработки в Logstash.
Для фильтра grok, который использует Logstash, есть удобный дебаггер, где можно посмотреть, как будут парситься ваши данные. Покажу на примере одной строки из конфига nginx. Например, возьмем такую строку из лога:
1 |
180.163.220.100 - travvels.ru [05/Sep/2021:14:45:52 +0300] "GET /assets/galleries/26/1.png HTTP/1.1" 304 0 "https://travvels.ru/ru/glavnaya/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" |
И посмотрим, как ее распарсит правило grok, которое я использовал в конфиге выше.
1 |
%{IPORHOST:remote_ip} - %{DATA:user} \[%{HTTPDATE:access_time}\] \"%{WORD:http_method} %{DATA:url} HTTP/%{NUMBER:http_version}\" %{NUMBER:response_code} %{NUMBER:body_sent_bytes} \"%{DATA:referrer}\" \"%{DATA:agent}\" |
Собственно, результат вы можете сами увидеть в дебаггере. Фильтр распарсит лог и на выходе сформирует json, где каждому значению будет присвоено свое поле, по которому потом удобно будет в Kibana строить отчеты и делать выборки. Только не забывайте про формат логов. Приведенное мной правило соответствует дефолтному формату main логов в nginx. Если вы каким-то образом модифицировали формат логов, внесите изменения в grok фильтр. Надеюсь понятно объяснил работу этого фильтра. Вы можете таким образом парсить любые логи и передавать их в еластикс. Потом на основе этих данных строить отчеты, графики, дашборды.
Дальше используется модуль date для того, чтобы выделять дату из поступающих логов и использовать ее в качестве даты документа в elasticsearch. Делается это для того, чтобы не возникало путаницы, если будут задержки с доставкой логов. В системе сообщения будут с одной датой, а внутри лога будет другая дата. Неудобно разбирать инциденты.
В конце я использую geoip фильтр, который на основе ip адреса, который мы получили ранее с помощью фильтра grok и записали в поле remote_ip, определяет географическое расположение. Он добавляет новые метки и записывает туда географические данные. Для его работы используется база данных из файла /usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-filter-geoip-6.0.3-java/vendor/GeoLite2-City.mmdb. Она будет установлена вместе с logstash. Впоследствии вы скорее всего захотите ее обновлять. Раньше она была доступна по прямой ссылке, но с 30-го декабря 2019 года правила изменились. База по-прежнему доступна бесплатно, но для загрузки нужна регистрация на сайте сервиса. Регистрируемся и качаем отсюда - https://dev.maxmind.com/geoip/geoip2/geolite2/#Download_Access. Передаем на сервер, распаковываем и копируем в /etc/logstash файл GeoLite2-City.mmdb. Теперь нам нужно в настройках модуля geoip указать путь к файлу с базой. Добавляем в /etc/logstash/conf.d/filter.conf:
1 2 3 4 5 6 |
geoip { database => "/etc/logstash/GeoLite2-City.mmdb" source => "remote_ip" target => "geoip" add_tag => [ "nginx-geoip" ] } |
Закончили настройку logstash. Запускаем его:
# systemctl start logstash.service
Можете проверить на всякий случай лог /var/log/logstash/logstash-plain.log, чтобы убедиться в том, что все в порядке. Признаком того, что скачанная geoip база успешно добавлена будет вот эта строчка в логе:
1 |
[2021-10-18T12:52:07,118][INFO ][logstash.filters.geoip ][main] Using geoip database {:path=>"/etc/logstash/GeoLite2-City.mmdb"} |
Теперь настроим агенты для отправки данных.
Установка Filebeat для отправки логов в Logstash
Установим первого агента Filebeat на сервер с nginx для отправки логов веб сервера на сервер с ELK. Ставить можно как из общего репозитория, который мы подключали ранее, так и по отдельности пакеты. Как ставить - решать вам. В первом случае придется на все хосты добавлять репозиторий, но зато потом удобно обновлять пакеты. Если подключать репозиторий не хочется, можно просто скачать пакет и установить его. Ставим на Centos.
# curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.15.1-x86_64.rpm
# rpm -vi filebeat-7.15.1-x86_64.rpm
В Debian/Ubuntu ставим так:
# curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.15.1-amd64.deb
# dpkg -i filebeat-7.15.1-amd64.deb
Или просто:
# yum install filebeat
# apt install filebeat
После установки рисуем примерно такой конфиг /etc/filebeat/filebeat.yml для отправки логов в logstash.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
filebeat.inputs: - type: log enabled: true paths: - /var/log/nginx/*-access.log fields: type: nginx_access fields_under_root: true scan_frequency: 5s - type: log enabled: true paths: - /var/log/nginx/*-error.log fields: type: nginx_error fields_under_root: true scan_frequency: 5s output.logstash: hosts: ["10.1.4.114:5044"] xpack.monitoring: enabled: true elasticsearch: hosts: ["http://10.1.4.114:9200"] |
Некоторые пояснения к конфигу, так как он не совсем дефолтный и минималистичный. Я его немного модифицировал для удобства. Во-первых, я разделил логи access и error с помощью отдельного поля type, куда записываю соответствующий тип лога: nginx_access или nginx_error. В зависимости от типа меняются правила обработки в logstash. Плюс, я включил мониторинг и для этого указал адрес elastichsearch, куда filebeat передает данные мониторинга напрямую. Показываю это для вас просто с целью продемонстрировать возможность. У меня везде отдельно работает мониторинг на zabbix, так что большого смысла в отдельном мониторинге нет. Но вы посмотрите на него, возможно вам он пригодится. Чтобы мониторинг работал, его надо активировать в соответствующем разделе в Management - Stack Monitoring.
И не забудьте запустить elasticsearch на внешнем интерфейсе. В первоначальной настройке я указал слушать только локальный интерфейс. Запускаем filebeat и добавляем в автозагрузку.
# systemctl start filebeat
# systemctl enable filebeat
Проверяйте логи filebeat в дефолтном системном логе. По умолчанию, он все пишет туда. Лог весьма информативен. Если все в порядке, увидите список всех логов в директории /var/log/nginx, которые нашел filebeat и начал готовить к отправке. Если все сделали правильно, то данные уже потекли в elasticsearch. Мы их можем посмотреть в Kibana. Для этого открываем web интерфейс и переходим в раздел Discover. Так как там еще нет индекса, нас перенаправит в раздел Managemet, где мы сможем его добавить.
Вы должны увидеть индекс, который начал заливать logstash в elasticsearch. В поле Index pattern введите nginx-* . Выберите имя поля для временного фильтра. У вас будет только один вариант - @timestamp, выбирайте его и жмите Create Index Pattern.
Новый индекс добавлен. Теперь при переходе в раздел Discover, он будет открываться по умолчанию со всеми данными, которые в него поступают.
Получение логов с веб сервера nginx на linux настроили. Подобным образом настраивается сбор и анализ любых логов. Можно либо самим писать фильтры для парсинга с помощью grok, либо брать готовые
Теперь сделаем то же самое для журналов windows.
Установка и настройка Winlogbeat
Для настройки централизованного сервера сбора логов с Windows серверов, установим сборщика системных логов winlogbeat. Для этого скачаем его и установим в качестве службы. Идем на страницу загрузок и скачиваем msi версию под вашу архитектуру - 32 или 64 бита. Запускаем инсталлятор и в конце выбираем открытие директории по умолчанию.
Создаем и правим конфигурационный файл winlogbeat.yml. Я его привел к такому виду:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
winlogbeat.event_logs: - name: Application ignore_older: 72h - name: Security - name: System tags: ["winsrv"] output.logstash: hosts: ["10.1.4.114:5044"] logging.level: info logging.to_files: true logging.files: path: C:/ProgramData/Elastic/Beats/winlogbeat name: winlogbeat.log keepfiles: 7 xpack.monitoring: enabled: true elasticsearch: hosts: ["http://10.1.4.114:9200"] |
В принципе, по тексту все понятно. Я беру 3 системных лога Application, Security, System (для русской версии используются такие же названия) и отправляю их на сервер с logstash. Настраиваю хранение логов и включаю мониторинг по аналогии с filebeat. Отдельно обращаю внимание на tags: ["winsrv"]. Этим тэгом я помечаю все отправляемые сообщения, чтобы потом их обработать в logstash и отправить в elasticsearch с отдельным индексом. Я не смог использовать поле type, по аналогии с filebeat, потому что в winlogbeat в поле type жестко прописано wineventlog и изменить его нельзя. Если у вас данные со всех серверов будут идти в один индекс, то можно tag не добавлять, а использовать указанное поле type для сортировки. Если же вы данные с разных среверов хотите помещать в разные индексы, то разделяйте их тэгами. Для того, чтобы логи виндовых журналов пошли в elasticsearch не в одну кучу вместе с nginx логами, нам надо настроить для них отдельный индекс в logstash в разделе output. Идем на сервер с logstash и правим конфиг output.conf.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
output { if [type] == "nginx_access" { elasticsearch { hosts => "localhost:9200" index => "nginx-%{+YYYY.MM.dd}" } } else if [type] == "nginx_error" { elasticsearch { hosts => "localhost:9200" index => "nginx-%{+YYYY.MM.dd}" } } else if "winsrv" in [tags] { elasticsearch { hosts => "localhost:9200" index => "winsrv-%{+YYYY.MM.dd}" } } else { elasticsearch { hosts => "localhost:9200" index => "unknown_messages" } } #stdout { codec => rubydebug } } |
Думаю, по тексту понятен смысл. Я разделил по разным индексам логи nginx, системные логи виндовых серверов и добавил отдельный индекс unknown_messages, в который будет попадать все то, что не попало в предыдущие. Это просто задел на будущее, когда конфигурация будет более сложная, можно будет ловить сообщения, которые по какой-то причине не попали ни в одно из приведенных выше правил. Я не смог в одно правило поместить оба типа nginx_error и nginx_access, потому что не понял сходу, как это правильно записать, а по документации уже устал лазить, выискивать информацию. Так получился рабочий вариант. После этого перезапустил logstash и пошел на windows сервер, запустил службу Elastic Winlogbeat 7.15.1.
Подождал немного, пока появятся новые логи на виндовом сервере, зашел в Kibana и добавил новые индексы. Напомню, что делается это в разделе Stack Management -> -> Index Patterns.
Добавляем новый индекс по маске winsrv-*.
Можно идти в раздел Discover и просматривать логи с Windows серверов.
У меня без проблем все заработало в том числе на серверах с русской версией Windows. Все логи, тексты в сообщениях на русском языке нормально обрабатываются и отображаются. Проблем не возникло нигде. На этом я закончил настройку ELK стека из Elasticsearch, Logstash, Kibana, Filebeat и Winlogbeat. Описал основной функционал по сбору логов. Дальше с ними уже можно работать по ситуации - строить графики, отчеты, собирать дашборды и т.д.
Настройка безопасности и авторизация в Kibana
Во время предыдущих настроек вы могли заметить информационные сообщения в веб интерфейсе, которые постоянно выскакивали. Текст их следующий:
Warning: 299 Elasticsearch-7.15.1-83c34f456ae29d60e94d886e455e6a3409bba9ed "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-minimal-setup.html to enable security."
Нас предупреждают, что в настоящий момент аутентификация не настроена, поэтому доступ к информации может получить любой желающий. Если для вас это не проблема и вы изолировали доступ к данным, к примеру, на уровне firewall, можете игнорировать эти сообщения. Далее я расскажу, как избавиться от этого предупреждения и настроить доступ к поиску elastic, а также информации в Kibana с помощью авторизации по пользователю и паролю.
Открываем конфиг кластера в файле elasticsearch.yml и добавляем туда параметр:
xpack.security.enabled: true
Перезапускаем службу elasticsearch:
systemctl restart elasticsearch
Если вы ранее не настраивали работу кластера по ssl, то скорее всего получите ошибку:
1 2 3 |
[ERROR][o.e.b.Bootstrap ] [centos8] node validation exception [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch. bootstrap check failure [1] of [1]: Transport SSL must be enabled if security is enabled on a [basic] license. Please set [xpack.security.transport.ssl.enabled] to [true] or disable security by setting [xpack.security.enabled] to [false] |
Для того, чтобы настройки xpack.security заработали, добавляем еще один параметр:
xpack.security.transport.ssl.enabled: true
Запускаем elasticsearch еще раз. Теперь он должен запуститься, но доступа к нему ни у кого не будет. Kibana будет показывать ошибку:
1 |
{"statusCode":503,"error":"Service Unavailable","message":"License is not available."} |
Нам нужно подготовить учётные данные, которые будем использовать для доступа к elasticsearch. Для этого запускаем утилиту elasticsearch-setup-passwords. По умолчанию она находится в папке /usr/share/elasticsearch/bin.
/usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
Данные пароли вам стоит сохранить, так как в открытом виде вы их больше нигде не увидите. Они вам понадобятся далее, для организации доступа к кластеру остальным компонентам стека.
Настраиваем парольный доступ к кластеру для Kibana, используя сгенерированный только что пароль. Для этого добавляем в конфиг kibana.yml параметры:
xpack.security.enabled: true
elasticsearch.username: "kibana_system"
elasticsearch.password: "JArsJZj10YC8LlPlQr4u"
После этого перезапустите службу и пробуйте зайти в веб интерфес. Вы должны увидеть окно авторизации. Чтобы попасть в веб интерфейс, необходимо использовать сгенерированную ранее учетную запись elastic !!! А не какую-либо другую.
Мы настроили доступ в Kibana по паролю. Управялть пользователями и ролями можно через веб интерфейс. Делается это в разделе Stack Management -> Users. Там можно как отредактировать встроенные учетные записи, так и добавить новые.
Сделаем это на примере пользователя для Logstash. Создадим отдельного юзера с правами на запись в нужные нам индексы. Для этого сначала создадим роль с соответствующими правами. Переходим в Roles и добавляем новую.
Набор индексов и права доступа к ним вы можете выбрать те, что вам нужны. Можно разделить доступ: одни могут только писать данные, другие удалять и т.д. После создания роли, добавьте пользователя и добавьте ему созданную ранее роль
Теперь нам нужно настроить Logstash для авторизации в кластере. В настоящий момент он не может отправлять данные. В логе у него ошибки, которые явно не указывают, в чем проблема, но мы это знаем и так.
[ERROR][logstash.outputs.elasticsearch][main][f8cdb7a9c640d0ed412a776071b8530fd5c0011075712a1979bee6c58b4c1d9f] Encountered a retryable error (will retry with exponential backoff) {:code=>401, :url=>"http://localhost:9200/_bulk", :content_length=>2862}
Открываем конфиг logstash, отвечающий за output и добавляем туда учетные данные для доступа в кластер. Выглядеть это будет примерно так:
1 2 3 4 5 6 7 8 |
output { elasticsearch { user => "logstash_nginx_rw" password => "gdhsgfadsfsdfgsfdget45t" hosts => "localhost:9200" index => "nginx-%{+YYYY.MM.dd}" } } |
После этого данные как и прежде начнут поступать из logstash в elasticsearch, только теперь уже с авторизацией по пользователю и паролю.
Проксирование подключений к Kibana через Nginx
Приведу пример конфига для передачи запросов с nginx в kibana. Я рекомендую использовать ssl сертификаты для доступа к Kibana. Даже если в этом нет объективной необходимости, надоедают уведомления браузеров о том, что у вас небезопасное подключение. Вот примерный конфиг nginx для проксирования запросов к Kibana с ограничением доступа по паролю:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
server { listen 443; server_name kibana.site.ru; ssl_certificate /etc/letsencrypt/live/kibana.site.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/kibana.site.ru/privkey.pem; location / { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/htpasswd.kibana; 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; } } |
Создаем файл для пользователей и паролей:
# htpasswd -c /etc/nginx/htpasswd.kibana kibanauser
Если утилиты htpasswd нет в системе, то установите ее:
# yum install httpd-tools
После этого выйдет запрос на ввод пароля. С помощью приведенной выше команды мы создали файл с информацией о пользователе и пароле kibanauser для ограничения доступа к web панели кибана. Если у вас настроена внутренняя авторизация в Kibana, то большого смысла делать примерно то же самое через nginx нет. Но это на ваше усмотрение. Auth_basic позволяет полностью скрыть информацию о том, какой сервис находится за авторизацией, что может быть очень актуально при прямом доступе к Kibana из интернета.
Автоматическая очистка индексов в elasticsearch
Некоторое время назад для автоматической очистки индексов в Elasticsearch необходимо было прибегать к помощи сторонних продуктов. Наиболее популярным был Curator. Сейчас в Kibana есть встроенный инструмент для очистки данных - Index Lifecycle Policies. Его не трудно настроить самостоятельно, хотя и не могу сказать, что там всё очевидно. Есть некоторые нюансы, так что я по шагам расскажу, как это сделать. Для примера возьму всё тот же индекс nginx-*, который использовал ранее в статье.
Настроим срок жизни индексов следующим образом:
- Первые 30 дней - Hot phase. В этом режиме индексы активны, в них пишутся новые данные.
- После 30-ти дней - Cold phase. В этой фазе в индексы невозможна запись новых данных. Запросы к этим данным имеют низкий приоритет.
- Все, что старше 90 дней удаляется.
Чтобы реализовать эту схему хранения данных, идем в раздел Stack Management -> Index Lifecycle Management и добавляем новую политику. Я её назвал Nginx_logs. Выставляем параметры фаз в соответствии с заданными требованиями.
Не уместилось полное изображение настроек, но, думаю, вы там сами разберётесь, что выбрать. Ничего сложного тут нет. Далее нам нужно назначить новую политику хранения данных к индексам. Для этого переходим в Index Management -> Index Templates и добавляем новый индекс. В качестве шаблона укажите nginx-*, все остальные параметры можно оставить дефолтными.
Теперь возвращаемся в Index Lifecycle Policies, напротив нашей политики нажимаем на + и выбираем только что созданный шаблон.
Проверяем свойства шаблона и убеждаемся в том, что Lifecycle Policies применилась.
Теперь ко всем новым индексам, созданным по этому шаблону, будет применяться политика хранения данных. Для уже существующих это нужно проделать вручную. Достаточно выбрать нужный индекс и в выпадающем списке с опциями выбрать нужное действие.
Такими несложными действиями можно настроить автоматическую очистку индексов встроенными инструментами Elasticsearch и Kibana. В некоторых случаях быстрее и удобнее воспользоваться Curator, особенно если нужно быстро реализовать много разных схем. Единый конфиг куратора выглядит более наглядным, но это уже вкусовщина и от ситуации зависит.
Часто задаваемые вопросы (FAQ)
Можно ли вместо filebeat использовать другие программы для сбора логов?
Да, можно. Наиболее популярной заменой filebeat является Fluentd. Она более функциональна и производительна. В некоторых случаях может взять на себя часть функционала по начально обработке данных. В итоге, можно отказаться от logstash.
Можно ли в данной связке обойтись без logstash?
Да, если вы просто собираете логи, без предварительной обработки и изменения, можно отправлять данные напрямую в elasticsearch. На нем их так же можно обработать с помощью grok фильтра в elastic node. Вариант рабочий, но не такой функциональный, как logstash.
Есть ли в elasticsearch какой-то штатный механизм очистки старых данных?
Да, есть такой механизм - Index Lifecycle Policies, который требует отдельной настройки в Kibana. Также можно использовать сторонний софт. Пример такого софта - curator.
Как штатно настроить tls сертификат в Kibana?
Проще всего использовать для этого nginx в режиме proxy_pass. С его помощью можно без проблем подключить бесплатные сертификаты от Let's Encrypt.
Какие минимальные системные требования для запуска ELK Stack?
Начать настройку можно с 2CPU и 6Gb RAM. Но для более ли менее комфортной работы желательно 8G RAM.