Table of Contents
Установка Elasticsearch, Logstash, и Kibana в Ubuntu 22.04
В руководстве описано установка версии elasticsearch-8.5.3
Краткое описание стека:
- Elasticsearch – используется для хранения, анализа, поиска по логам.
- Kibana – представляет удобную и красивую web панель для работы с логами.
- Logstash – сервис для сбора логов и отправки их в Elasticsearch. В самой простой конфигурации можно обойтись без него и отправлять логи напрямую в Elastic. Но с logstash это делать удобнее.
- Beats – агенты для отправки логов в Logstash или Elasticsearch. Они бывают разные. Для отправки данных из текстовых логов linux буду использовать Filebeat, а Winlogbeat для отправки логов из журналов Windows систем.
К этой связке еще добавляется Nginx, который проксирует соединения в Kibana.
Системные требования
Стек весьма прожорлив, для установки одиночного экземпляра с полным набором компонентов ELK необходимы следующие системные ресурсы:
минимальные | рекомендуемые | |
---|---|---|
CPU | 2 | 4+ |
Memory | 6 GB | 8+ GB |
Disk | 10 GB | 10+ GB |
Раньше для установки всех перечисленных компонентов необходимо было отдельно устанавливать Java1) на сервер. Сейчас в этом нет необходимости, так как Java уже включена в пакеты устанавливаемого ПО.
Установка и конфигурирование Elasticsearch
Установка с помощью apt
По умолчанию, компоненты Elasticsearch недоступны в репозиториях пакетов Ubuntu. Однако, их можно установить с помощью apt после добавления в список источников Elastic.
Все пакеты, подписаны ключом Elasticsearch, для защиты системы от подмены пакетов. Пакеты, которые были аутентифицированы с помощью ключа, будут считаться доверенными для пакетного менеджера. На этом шаге, мы импортируем общедоступный ключ GPG Elasticsearch и добавим список источников пакетов Elastic.
Если установка проводиться на debian, может потребоваться установка пакета apt-transport-https
:
sudo apt-get install apt-transport-https
Для начала воспользуемся cURL. Обратите внимание, что мы используем аргумент -fsSL
для того, чтобы заглушить весь прогресс и возможные ошибки (кроме сбоя сервера), а также разрешить cURL выполнять запрос в новом месте при перенаправлении. Вывод curl, передадим команде gpg –dearmor
, которая преобразует ключ в формат, необходимый apt для проверки загруженных пакетов.
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch |sudo gpg --dearmor -o /usr/share/keyrings/elastic.gpg
Затем добавим список источников Elastic в каталог sources.list.d
, где apt будет искать новые источники:
echo "deb [signed-by=/usr/share/keyrings/elastic.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-8.x.list
Строка [signed-by=/usr/share/keyrings/elastic.gpg]
указывает apt использовать ключ, загруженный нами ключ, для проверки информации о репозитории и файлах для пакетов Elasticsearch.
Далее обновляем списки пакетов, и устанавливаем Elastic:
sudo apt update && sudo apt install elasticsearch
Стоит обратить внимание на вывод установщика, в нем содержится пароль суперпользователя:
[...] The generated password for the elastic built-in superuser is : YnyQ=JmAOgXMu8cy9i8I [...]
Но есть нюансы!| Для некоторых регионов, при получении ключа, мы можем столкнуться вот с такой симпатичной ошибкой:
Failed to fetch https://artifacts.elastic.co/packages/8.x/apt/dists/stable/InRelease 403 Forbidden [IP: 34.120.127.130 443]
Как видим, нас не пускают. На текущий момент: 21 декабря 22 года, есть два решения. Либо ставим на сервер vpn, и выполняем вышеуказанную операцию. Либо скачиваем deb пакеты и устанавливаем из них (но в этом случае тоже понадобится vpn).
Установка deb пакетов
Пакет Debian для Elasticsearch v8.5.3 можно загрузить с сайта и установить следующим образом:
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.5.3-amd64.deb wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.5.3-amd64.deb.sha512 shasum -a 512 -c elasticsearch-8.5.3-amd64.deb.sha512 sudo dpkg -i elasticsearch-8.5.3-amd64.deb
Настройка Elasticsearch
После того как Elasticsearch установлен, перейдем к его настройке. Редактируем файл /etc/elasticsearch/elasticsearch.yml
, не забываем про sudo.
<WRAP center round info 95%>
Nota Bene! Файл конфигурации Elasticsearch имеет формат YAML, а это означает, необходимо сохранить формат отступа. Убедимся, что мы не добавили лишних пробелов при редактировании этого файла.
</WRAP>
Файл elasticsearch.yml
, содержит параметры конфигурации для кластера, узла, путей, памяти, сети, etc… Большинство из этих параметров предварительно настроены в файле, но мы можем менять их, в зависимости от потребности. В данной демонстрации, мы проведем настройку для одного сетевого узла.
Elasticsearch, слушает любой трафик на порт 9200. Нам нужно ограничить внешний доступ к нашему экземпляру Elasticsearch, чтобы третьи лица не смогли прочитать данные или отключить кластер Elasticsearch через REST API.
Для ограничения доступа, найдем директиву network.host
, снимем с нее комментарий, и установим ее значение на localhost
, а также директиву network.host
с аналогичным значением:
[...] network.host: localhost [...] http.host: 127.0.0.1 [...]
Мы указали localhost
, чтобы Elasticsearch прослушивал только свои интерфейсы. Если нужно, чтобы он прослушивал определенный интерфейс, то можно указать его ip вместо localhost
.
Это минимальные настройки, с которыми можно начать использовать Elasticsearch. Теперь давайте запустить Elasticsearch:
sudo systemctl start elasticsearch
Немного подождем, демон стартует не быстро.
И добавим демон в автозагрузку:
sudo systemctl enable elasticsearch
Смотрим, что получилось:
sudo netstat -tulnp | grep 9200 tcp6 0 0 127.0.0.1:9200 :::* LISTEN 7477/java
Elasticsearch повис на локальном интерфейсе. Причем я вижу, что он слушает ipv6, а про ipv4 ни слова. Но его он тоже слушает, так что все в порядке.
Проверим, работает ли сервис Elasticsearch, отправив HTTP-запрос:
curl -k --user elastic:YnyQ=JmAOgXMu8cy9i8I https://127.0.0.1:9200 { "name" : "elk", "cluster_name" : "elasticsearch", "cluster_uuid" : "VesikAE6TdGJpeUQldsY1g", "version" : { "number" : "8.5.3", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "4ed5ee9afac63de92ec98f404ccbed7d3ba9584e", "build_date" : "2022-12-05T18:22:22.226119656Z", "build_snapshot" : false, "lucene_version" : "9.4.2", "minimum_wire_compatibility_version" : "7.17.0", "minimum_index_compatibility_version" : "7.0.0" }, "tagline" : "You Know, for Search" }
Если по какой-то причине, пароль который был сгенерирован при инсталляции утерян, его можно восстановить с помощью команды:
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
Установка и настройка панели Kibana
Установка с помощью apt
Согласно официальной документации, Kibana следует устанавливать только после установки Elasticsearch. Установка в таком порядке гарантирует, что компоненты, от которых зависит каждый продукт, правильно установлены.
Поскольку, источник пакета Elastic уже был добавлен в предыдущем шаге, мы просто устанавливаем остальные компоненты стека Elastic с помощью apt:
sudo apt install kibana sudo systemctl enable kibana sudo systemctl start kibana
Установка deb пакетов
wget https://artifacts.elastic.co/downloads/kibana/kibana-8.5.3-amd64.deb shasum -a 512 kibana-8.5.3-amd64.deb sudo dpkg -i kibana-8.5.3-amd64.deb
По умолчанию, Kibana слушает порт 5601. Только не спешите его проверять после запуска. Кибана стартует долго. Подождем примерно минуту и проверяем:
netstat -tulnp | grep 5601 tcp 0 0 127.0.0.1:5601 0.0.0.0:* LISTEN 10156/node
Настройка Kibana
Поскольку Kibana настроена на прослушивание только на localhost, мы должны настроить обратный прокси-сервер, чтобы разрешить внешний доступ к нему. Для этого мы будем использовать Nginx, который уже должен быть установлен на вашем сервере.
Сначала, с помощью openssl, создадим административного пользователя Kibana, которого будем использовать для доступа к веб-интерфейсу Kibana. В качестве примера, мы назовем эту учетную запись kibanaadmin. Но, для обеспечения большей безопасности, рекомендуется выбрать нестандартное имя для пользователя, которое будет трудно угадать.
Следующая команда, создаст административного пользователя и пароль для Kibana и сохранит все в файле htpasswd.users
. Мы настроим Nginx так, чтобы он требовал эти данные при подключении:
echo "kibanaadmin:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users
Вводим и подтверждаем пароль в ответ на запрос.
Далее, создадим виртуальный хост Nginx. В качестве примера, мы назовём его example_domain
. Создадим и отредактируем файл /etc/nginx/sites-available/example_domain
:
server { listen 80; server_name example_domain; 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; } }
Включим созданную конфигурацию. Создаем ссылку:
sudo ln -s /etc/nginx/sites-available/example_domain /etc/nginx/sites-enabled/example_domain
Проверяем синтаксис конфига:
sudo nginx -t
Если с синтаксисом все ок, перезапускаем демон nginx:
sudo systemctl reload nginx
Перейдем непосредственно к панели Kibana
Файл с настройками Kibana располагается по пути – /etc/kibana/kibana.yml
.
Для начала, нам нужно настроить аутентификацию в elasticsearch. Для этого создадим пароль для встроенного пользователя kibana_system:
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u kibana_system
Сохраняем пароль и добавляем учетную запись в конфигурацию kibana:
elasticsearch.username: "kibana_system" elasticsearch.password: "DiJiZ0GibfN5*W+DMb3e"
Теперь нам нужно указать сертификат от центра сертификации, который использовал elasticsearch для генерации tls сертификатов. Напомню, что обращения он принимает только по HTTPS. Так как мы не устанавливали подтверждённый сертификат, будем использовать самоподписанный, который был сгенерирован автоматически во время установки elasticsearch. Все созданные сертификаты находятся в директории /etc/elasticsearch/certs. Скопируем их в /etc/kibana и настроим доступ со стороны веб панели:
cp -R /etc/elasticsearch/certs /etc/kibana chown -R root:kibana /etc/kibana/certs
Добавим этот CA в конфигурацию Kibana:
elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/certs/http_ca.crt" ]
И последний момент – указываем подключение к elasticsearch по HTTPS:
elasticsearch.hosts: ["https://localhost:9200"]
И перезапускаем демон:
systemctl restart kibana.service
Для просмотра статистики преходим по адресу http://example_domain/status
Для входа в панель управления, входим по адресу http://example_domain
. И используем учетную запись Elasticsearch. После входа, мы можем создать нового администратора. Учетная запись kibana_system
, созданная в этом разделе, это встроенная роль, используемая для подключения к Elasticsearch
При первом запуске, Kibana предлагает настроить источники для сбора логов. Это можно сделать, нажав на кнопу Add integrations. Но об этом, поговорим чуть позже.
Установка и настройка Logstash
Хотя Beats может отправлять данные непосредственно в базу данных Elasticsearch, обычно для обработки данных используется Logstash. Это позволяет нам более гибко собирать данные из разных источников, преобразовывать их в общий формат и экспортировать в другую базу данных.
Устанавливаем:
sudo apt install logstash systemctl enable logstash.service
Запускать сервис пока не будем, сначала его надо настроить. Основной файл конфигурации logstash /etc/logstash/logstash.yml
. Его не трогаем, а все настройки будем по смыслу разделять по разным конфигурационным файлам в директории /etc/logstash/conf.d
. Создаем первый конфиг input.conf
, который будет описывать приём информации с beats агентов.
input { beats { port => 5044 } }
Тут все просто. Указываем, что принимаем информацию на 5044 порту. Этого достаточно. Если нужно использовать ssl сертификаты для передачи логов по защищенным соединениям, здесь добавляются параметры ssl. В данном руководстве, данные собираются из закрытого периметра локальной сети, необходимости в использовании ssl нет.
Теперь укажем, куда будем передавать данные. Тут тоже все относительно просто. Создаем конфигуратор /etc/logstash/conf.d/output.conf
, который описывает передачу данных в Elasticsearch:
output { elasticsearch { hosts => "https://localhost:9200" index => "websrv-%{+YYYY.MM}" user => "elastic" password => "P@$$w0rd" cacert => "/etc/logstash/certs/http_ca.crt" } }
Рассмотрим конфигуратор выше. Все данные, передаем в elasticsearch по указанным индексом с маской в виде даты. Разбивка индексов по дням и по типам данным, удобна с точки зрения управления данными. Потом можно легко выполнять очистку данных по этим индексам. Для аутентификации, были указаны учетные данные elastic, но можно сделать отдельную учетку через Kibana (раздел Stack Management → Users). При этом можно создавать под каждый индекс свою учётную запись с разрешением доступа только к этому индексу.
Как и в случае с Kibana, для Logstash нужно указать CA, иначе он будет ругаться на не доверенный сертификат elasticsearch и откажется к нему подключаться. Копируем сертификаты и назначаем права:
cp -R /etc/elasticsearch/certs /etc/logstash chown -R root:logstash /etc/logstash/certs
Остается последний конфиг с описанием обработки данных – /etc/logstash/conf.d/filter.conf
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" ] } }
Разберем /etc/logstash/conf.d/filter.conf
подробнее. Первое, что делает этот фильтр, парсит логи nginx с помощью grok2), если указан соответствующий тип логов, и выделяет из лога ключевые данные, которые записывает в определенные поля, чтобы потом с ними было удобно работать. В документации к filebeat хорошо описаны модули, идущие в комплекте, которые все это и так уже умеют делать из коробки, нужно только подключить соответствующий модуль.
Модули filebeat работают только в том случае, если ему отправляются данные напрямую в Elasticsearch. На него тоже ставится соответствующий плагин, и мы получаем отформатированные данные с помощью elastic ingest. Но, у нас работает промежуточное звено – Logstash, который принимает данные. С ним плагины filebeat не работают, поэтому приходится отдельно в logstash парсить данные. Это не очень сложно, но, тем не менее. В некотором роде, это плата за удобства, которые дает logstash. Если у нас много разрозненных данных, то отправлять их напрямую в Elasticsearch не так удобно, как с использованием их обработки в Logstash.
Для фильтра grok, который использует Logstash, есть много дебаггеров (например такой), где можно посмотреть, как будут парситься наши данные. Посмотрим на примере одной строки для конфигуратора nginx. Например, возьмем такую строку из лога:
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, которое использовался в конфигураторе выше:
%{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 строить отчеты и делать выборки.
Дальше используется модуль date
для того, чтобы выделять дату из поступающих логов и использовать ее в качестве даты документа в elasticsearch. Делается это для того, чтобы не возникало путаницы, если будут задержки с доставкой логов. В системе сообщения будут с одной датой, а внутри лога будет другая дата. Неудобно разбирать инциденты.
В конце используется geoip
фильтр, который на основе ip адреса, полученного ранее с помощью фильтра grok и записали в поле remote_ip, определяет географическое расположение. Он добавляет новые метки и записывает туда географические данные. Для его работы используется база данных из файла /var/lib/logstash/plugins/filters/geoip/1669759580/GeoLite2-City.mmdb
. Она будет установлена вместе с logstash. Впоследствии, если мы захотим ее обновить, забрать ее можно вот с этого ресурса (требуется регистрация). Раньше она была доступна по прямой ссылке, но с 30-го декабря 2019 года правила изменились… Передаем на сервер, распаковываем и копируем файл GeoLite2-City.mmdb
в директорию /etc/logstash
. Теперь нужно в настройках модуля geoip
указать путь к файлу с базой. Добавляем в /etc/logstash/conf.d/filter.conf
:
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 база успешно добавлена будет вот эта строчка в логе:
[2021-10-18T12:52:07,118][INFO ][logstash.filters.geoip ][main] Using geoip database {:path=>"/etc/logstash/GeoLite2-City.mmdb"}
Установка Filebeat для отправки логов в Logstash
Установка проводится с учетом ранее подключенного репозитория:
sudo apt update && sudo apt install filebeat
После установки, редактируем конфигурационный файл /etc/filebeat/filebeat.yml
для отправки логов в logstash.
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: ["ip_host:5044"] xpack.monitoring: enabled: true elasticsearch: hosts: ["http://ip_host:9200"]
Некоторые пояснения к конфигуратору, так как он не совсем дефолтный и минималистичный. Мы его подвергли небольшой модификации для удобства. Во-первых, были разделены логи access
и error
с помощью отдельного поля type
, куда записываю соответствующий тип лога: nginx_access
или nginx_error
. В зависимости от типа меняются правила обработки в logstash.
Запускаем filebeat и добавляем в автозагрузку:
systemctl enable --now filebeat
[ELK]