ELK. авторизация в kibana. Kibana через Nginx. автоматическая очистка индексов

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 необ­хо­ди­мы сле­ду­ю­щие систем­ные ресурсы.

Систем­ные тре­бо­ва­ния для ELK Stack
мини­маль­ные реко­мен­ду­е­мые
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

При­сту­па­ем к уста­нов­ке еластика:

# yum install --enablerepo=elasticsearch elasticsearch

В в завер­ше­нии уста­нов­ки доба­вим elasticsearch в авто­за­груз­ку и запу­стим его с дефолт­ны­ми настройками:

# systemctl daemon-reload
# systemctl enable elasticsearch.service
# systemctl start elasticsearch.service

Про­ве­ря­ем, запу­сти­лась ли служба:

# systemctl status elasticsearch.service

Про­ве­рим теперь, что elasticsearch дей­стви­тель­но нор­маль­но рабо­та­ет. Выпол­ним к нему про­стой запрос о его статусе.

Все в поряд­ке, сер­вис реаль­но запу­щен и отве­ча­ет на запросы.

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 дей­стви­тель­но нор­маль­но рабо­та­ет. Выпол­ним к нему про­стой запрос о его статусе.

Если все в поряд­ке, то пере­хо­дим к настрой­ке 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

Смот­рим, что получилось:

Elasticsearch повис на локаль­ном интер­фей­се. При­чем я вижу, что он слу­ша­ет ipv6, а про ipv4 ни сло­ва. Но его он тоже слу­ша­ет, так что все в поряд­ке. Пере­хо­дим к уста­нов­ке Kibana. Если вы хоти­те, что­бы elasticsearch слу­шал все сете­вые интер­фей­сы, настрой­те параметр:

Толь­ко не спе­ши­те сра­зу же запус­кать служ­бу. Если запу­сти­те, полу­чи­те ошибку:

Что­бы ее избе­жать, допол­ни­тель­но надо доба­вить еще один параметр:

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

Запус­ка­ем уста­нов­ку Kibana:

# yum install kibana

Добав­ля­ем Киба­на в авто­за­груз­ку и запускаем:

# systemctl daemon-reload
# systemctl enable kibana.service
# systemctl start kibana.service

Про­ве­ря­ем состо­я­ние запу­щен­но­го сервиса:

# systemctl status kibana.service

По умол­ча­нию, Kibana слу­ша­ет порт 5601. Толь­ко не спе­ши­те его про­ве­рять после запус­ка. Киба­на стар­ту­ет дол­го. Подо­жди­те при­мер­но мину­ту и проверяйте.

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. Толь­ко не спе­ши­те его про­ве­рять после запус­ка. Киба­на стар­ту­ет дол­го. Подо­жди­те при­мер­но мину­ту и проверяйте.

Настройка 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 агентов.

Тут все про­сто. Ука­зы­ваю, что при­ни­ма­ем инфор­ма­цию на 5044 порт. Это­го доста­точ­но. Если вы хоти­те исполь­зо­вать ssl сер­ти­фи­ка­ты для пере­да­чи логов по защи­щен­ным соеди­не­ни­ям, здесь добав­ля­ют­ся пара­мет­ры ssl. Я буду соби­рать дан­ные из закры­то­го пери­мет­ра локаль­ной сети, у меня нет необ­хо­ди­мо­сти исполь­зо­вать ssl. Теперь ука­жем, куда будем пере­да­вать дан­ные. Тут тоже все отно­си­тель­но про­сто. Рису­ем кон­фиг output.conf, кото­рый опи­сы­ва­ет пере­да­чу дан­ных в Elasticsearch.

Что мы настро­и­ли? Пере­да­вать все дан­ные в elasticsearch под ука­зан­ным индек­сом с мас­кой в виде даты. Раз­бив­ка индек­сов по дням и по типам дан­ных удоб­на с точ­ки зре­ния управ­ле­ния дан­ны­ми. Потом лег­ко будет выпол­нять очист­ку дан­ных по этим индек­сам. Я заком­мен­ти­ро­вал послед­нюю стро­ку. Она отве­ча­ет за логи­ро­ва­ние. Если ее вклю­чить, то все посту­па­ю­щие дан­ные logstash будет отправ­лять допол­ни­тель­но в систем­ный лог. В centos это /var/log/messages. Исполь­зуй­те толь­ко во вре­мя отлад­ки, ина­че лог быст­ро раз­растет­ся дуб­ля­ми посту­па­ю­щих дан­ных. Оста­ет­ся послед­ний кон­фиг с опи­са­ни­ем обра­бот­ки дан­ных. Тут начи­на­ет­ся неболь­шая улич­ная магия, в кото­рой я раз­би­рал­ся неко­то­рое вре­мя. Рас­ска­жу ниже. Рису­ем кон­фиг filter.conf.

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

Моду­ли filebeat рабо­та­ют толь­ко в том слу­чае, если вы отправ­ля­е­те дан­ные напря­мую в Elasticsearch. На него вы тоже ста­ви­те соот­вет­ству­ю­щий пла­гин и полу­ча­е­те отфор­ма­ти­ро­ван­ные дан­ные с помо­щью elastic ingest. Но у нас рабо­та­ет про­ме­жу­точ­ное зве­но Logstash, кото­рый при­ни­ма­ет дан­ные. С ним пла­ги­ны filebeat не рабо­та­ют, поэто­му при­хо­дит­ся отдель­но в logstash пар­сить дан­ные. Это не очень слож­но, но тем не менее. Как я пони­маю, это пла­та за удоб­ства, кото­рые дает logstash. Если у вас мно­го раз­роз­нен­ных дан­ных, то отправ­лять их напря­мую в Elasticsearch не так удоб­но, как с исполь­зо­ва­ни­ем пре­до­б­ра­бот­ки в Logstash.

Для филь­тра grok, кото­рый исполь­зу­ет Logstash, есть удоб­ный дебаг­гер, где мож­но посмот­реть, как будут пар­сить­ся ваши дан­ные. Пока­жу на при­ме­ре одной стро­ки из кон­фи­га nginx. Напри­мер, возь­мем такую стро­ку из лога:

И посмот­рим, как ее рас­пар­сит пра­ви­ло grok, кото­рое я исполь­зо­вал в кон­фи­ге выше.

Соб­ствен­но, резуль­тат вы може­те сами уви­деть в дебаг­ге­ре. Фильтр рас­пар­сит лог и на выхо­де сфор­ми­ру­ет 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:

Закон­чи­ли настрой­ку logstash. Запус­ка­ем его:

# systemctl start logstash.service

Може­те про­ве­рить на вся­кий слу­чай лог /var/log/logstash/logstash-plain.log, что­бы убе­дить­ся в том, что все в поряд­ке. При­зна­ком того, что ска­чан­ная geoip база успеш­но добав­ле­на будет вот эта строч­ка в логе:

Теперь настро­им аген­ты для отправ­ки данных.

Установка 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.

Неко­то­рые пояс­не­ния к кон­фи­гу, так как он не совсем дефолт­ный и мини­ма­ли­стич­ный. Я его немно­го моди­фи­ци­ро­вал для удоб­ства. Во-пер­вых, я раз­де­лил логи 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. Я его при­вел к тако­му виду:

В прин­ци­пе, по тек­сту все понят­но. Я беру 3 систем­ных лога ApplicationSecuritySystem (для рус­ской вер­сии исполь­зу­ют­ся такие же назва­ния) и отправ­ляю их на сер­вер с logstash. Настра­и­ваю хра­не­ние логов и вклю­чаю мони­то­ринг по ана­ло­гии с filebeat. Отдель­но обра­щаю вни­ма­ние на tags: ["winsrv"]. Этим тэгом я поме­чаю все отправ­ля­е­мые сооб­ще­ния, что­бы потом их обра­бо­тать в logstash и отпра­вить в elasticsearch с отдель­ным индек­сом. Я не смог исполь­зо­вать поле type, по ана­ло­гии с filebeat, пото­му что в winlogbeat в поле type жест­ко про­пи­са­но wineventlog и изме­нить его нель­зя. Если у вас дан­ные со всех сер­ве­ров будут идти в один индекс, то мож­но tag не добав­лять, а исполь­зо­вать ука­зан­ное поле type для сор­ти­ров­ки. Если же вы дан­ные с раз­ных сре­ве­ров хоти­те поме­щать в раз­ные индек­сы, то раз­де­ляй­те их тэга­ми. Для того, что­бы логи вин­до­вых жур­на­лов пошли в elasticsearch не в одну кучу вме­сте с nginx лога­ми, нам надо настро­ить для них отдель­ный индекс в logstash в раз­де­ле output. Идем на сер­вер с logstash и пра­вим кон­фиг output.conf.

Думаю, по тек­сту поня­тен смысл. Я раз­де­лил по раз­ным индек­сам логи 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, то ско­рее все­го полу­чи­те ошибку:

Для того, что­бы настрой­ки xpack.security зара­бо­та­ли, добав­ля­ем еще один параметр:

xpack.security.transport.ssl.enabled: true

Запус­ка­ем elasticsearch еще раз. Теперь он дол­жен запу­стить­ся, но досту­па к нему ни у кого не будет. Kibana будет пока­зы­вать ошибку:

Нам нуж­но под­го­то­вить учёт­ные дан­ные, кото­рые будем исполь­зо­вать для досту­па к 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 и добав­ля­ем туда учет­ные дан­ные для досту­па в кла­стер. Выгля­деть это будет при­мер­но так:

После это­го дан­ные как и преж­де нач­нут посту­пать из logstash в elasticsearch, толь­ко теперь уже с авто­ри­за­ци­ей по поль­зо­ва­те­лю и паролю.

Проксирование подключений к Kibana через Nginx

При­ве­ду при­мер кон­фи­га для пере­да­чи запро­сов с nginx в kibana. Я реко­мен­дую исполь­зо­вать ssl сер­ти­фи­ка­ты для досту­па к Kibana. Даже если в этом нет объ­ек­тив­ной необ­хо­ди­мо­сти, надо­еда­ют уве­дом­ле­ния бра­у­зе­ров о том, что у вас небез­опас­ное под­клю­че­ние.   Вот при­мер­ный кон­фиг nginx для прок­си­ро­ва­ния запро­сов к Kibana с огра­ни­че­ни­ем досту­па по паролю:

Созда­ем файл для поль­зо­ва­те­лей и паролей:

# 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-*, кото­рый исполь­зо­вал ранее в статье.

Настро­им срок жиз­ни индек­сов сле­ду­ю­щим образом:

  1. Пер­вые 30 дней - Hot phase. В этом режи­ме индек­сы актив­ны, в них пишут­ся новые данные.
  2. После 30-ти дней - Cold phase. В этой фазе в индек­сы невоз­мож­на запись новых дан­ных. Запро­сы к этим дан­ным име­ют низ­кий приоритет.
  3. Все, что стар­ше 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.