Изучаем ELK. Часть III — Безопасность

Kate

Administrator
Команда форума
99156f638cfaa3a71a8f3e880bc08abf.png

Вступительное слово​

В первой и второй частях данной серии статей была описана процедура установки и настройки кластера Elasticsearch, Kibana и Logstash, но не был освящен вопрос безопасности.

В этой статье я расскажу, как настроить шифрование трафика между узлами кластера Elasticsearch и его клиентам, шифрование трафика между Kibana и клиентами, покажу, как создавать роли и пользователей, а так же выдавать API ключи для доступа к кластеру Elasticsearch.

План действий​

  1. "Включаем" безопасность.
  2. Настраиваем шифрование между узлами Elasticsearch.
  3. Настраиваем аутентификацию.
  4. Настраиваем шифрование клиентского трафика Elasticsearch.
  5. Подключаем Kibana к Elasticsearch.
  6. Настраиваем шифрование трафика между Kibana и клиентами.
  7. Создаем пользователей и роли.
  8. Настраиваем пользовательские сессии в Kibana.
  9. Настраиваем Logstash.
  10. Создаем API ключи.

"Включаем" безопасность​

Чтобы использовать функции безопасности в Elasticsearch, их необходимо активировать. Для этого на каждом узле в файле конфигурации указывается следующая настройка:

xpack.security.enabled: true

Настраиваем шифрование между узлами Elasticsearch​

Следующим шагом необходимо настроить шифрование трафика между узлами Elasticsearch. Для этого выполняем несколько шагов:

  • Создаем CA (Certificate Authority) для кластера Elasticsearch:
./bin/elasticsearch-certutil ca
Для установки из пакетов Deb и RPM исполняемые файлы Elasticsearch лежат в каталоге /usr/share/elasticsearch/bin/. Для установки из архива - в каталоге $ES_HOME/bin/.
В примерах все команды выполнены из каталога /usr/share/elasticsearch/.
Во время генерации корневого сертификата можно задать имя PKCS#12 файла, по умолчанию это elastic-stack-ca.p12 и пароль к нему.

Для получения сертификата и ключа в PEM формате укажите ключ --pem. На выходе будет ZIP архив с .crt и .key файлами.

С помощью ключа --out можно указать каталог для создаваемого файла.

Полученный корневой сертификат (для PEM формата еще и ключ) надо переместить на все узлы кластера для генерации сертификата узла.
  • Генерируем на каждом узле кластера сертификат и ключ:
./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --ip 10.0.3.11 --dns es-node01
Ключ --ca указывает путь к корневому сертификату CA в формате PKCS#12. Если сертификат и ключ были получены в PEM формате, то необходимо использовать ключи --ca-cert и --ca-key соответственно.

Ключи --dns и --ip добавляют проверку по имени узла и IP адресу и являются опциональными. Если вы указываете их, то укажите эти параметры для каждого узла.

Ключ --pass позволяет установить passphrase для ключа.
  • Включаем TLS в файле конфигурации Elasticsearch:
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: full
xpack.security.transport.ssl.keystore.path: es-node01-cert.p12
xpack.security.transport.ssl.truststore.path: elastic-stack-ca.p12
Где:

xpack.security.transport.ssl.enabled - включаем TLS/SSL

xpack.security.transport.ssl.verification_mode - режим проверки сертификатов. none - проверка не выполняется, certificate - выполняется проверка сертификата без проверки имени узла и IP адреса, full - проверка сертификата, а также имени узла и адреса указанных в сертификате.

xpack.security.transport.ssl.keystore.path - путь к файлу с сертификатом и ключем узла.

xpack.security.transport.ssl.truststore.path - путь к доверенному сертификату (CA).

Если сертификаты CA и/или узла в формате PEM, то необходимо изменить последние два параметра на следующие:
xpack.security.transport.ssl.key - путь к закрытому ключу узла
xpack.security.transport.ssl.certificate - путь к сертификату узла
xpack.security.transport.ssl.certificate_authorities - список путей к сертифкатам CA.
  • Cоздаем keystore и добавляем пароли от сертификатов(если они были заданы):
./bin/elasticsearch-keystore create -p
Ключ -p требуется для установки пароля keystone во время создания
Для PKCS#12 формата:

./bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
Для PEM сертификата:

./bin/elasticsearch-keystore add xpack.security.transport.ssl.securekeypassphrase
Чтобы запустить Elasticsearch с keystore, на который установлен пароль, необходимо передать этот пароль Elasticsearch. Это делается с помощью файла на который будет ссылаться переменная ES_KEYSTORE_PASSPHRASE_FILE. После запуска файл можно удалить, но при каждом последующим запуске файл необходимо создавать.

echo "password" > /etc/elasticsearch/ks_secret.tmp
chmod 600 /etc/elasticsearch/ks_secret.tmp
sudo systemctl set-environment ES_KEYSTORE_PASSPHRASE_FILE=/etc/elasticsearch/ks_secret.tmp
  • Перезапускаем Elasticsearch
В логах Elasticsearch должны появится записи о создании кластера:

[INFO ][o.e.c.s.ClusterApplierService] [es-node01] master node changed {previous [], current [{es-node02}{L1KdSSwCT9uBFhq0QlxpGw}{ujCcXRmOSn-EbqioSeDNXA}{10.0.3.12}{10.0.3.12:9300}...
Если обратиться к API, то будет ошибка "missing authentication credentials for REST request". С момента включения функций безопасности для обращения к кластер необходимо пройти аутентификацию.

Настраиваем аутентификацию​

Elasticsearch имеет несколько встроенных пользователей:

ПользовательОписание
elasticСуперпользователь
kibana_systemИспользуется для коммуникации между Kibana и Elasticsearch
logstash_systemПользователь, которого использует Logstash сервер, когда сохраняет информацию в Elasticsearch
beats_systemПользователь, которого использует агент Beats, когда сохраняет информацию в Elasticsearch
apm_systemПользователь, которого использует APM сервер, когда сохраняет информацию в Elasticsearch
remote_monitoring_userПользователь Metricbeat, который используется при сборе и хранении информации мониторинга в Elasticsearch
Прежде чем воспользоваться перечисленными пользователями, необходимо установить для них пароль. Для этого используется утилита elasticsearch-setup-passwords. В режиме interactive для каждого пользователя необходимо ввести пароли самостоятельно, в режиме auto Elasticsearch создаст пароли автоматически:

./bin/elasticsearch-setup-passwords auto

Initiating the setup of passwords for reserved users elastic,apm_system,kibana,kibana_system,logstash_system,beats_system,remote_monitoring_user.
The passwords will be randomly generated and printed to the console.
Please confirm that you would like to continue [y/N]y


Changed password for user apm_system
PASSWORD apm_system = NtvuRYhwbKpIEVUmHsZB

Changed password for user kibana_system
PASSWORD kibana_system = ycXvzXglaLnrFMdAFsvy

Changed password for user kibana
PASSWORD kibana = ycXvzXglaLnrFMdAFsvy

Changed password for user logstash_system
PASSWORD logstash_system = vU3CuRbjBpax1RrsCCLF

Changed password for user beats_system
PASSWORD beats_system = c9GQ85qhNL59H2AXUvcA

Changed password for user remote_monitoring_user
PASSWORD remote_monitoring_user = wB320seihljmGsjc29W5

Changed password for user elastic
PASSWORD elastic = iOrMTBbfHOAkm5CPeOj7
Второй раз elasticsearch-setup-passwords запустить не получится, так как bootstrap password изменился. Чтобы изменить пароль пользователям можно воспользоваться API.
Попробуем сделать API запрос к любому узлу Elasticsearch с использованием учетной записи elastic и пароля к от неё:

curl -u 'elastic' -X GET "http://10.0.3.1:9200/_cluster/health?pretty"
Enter host password for user 'elastic':
{
"cluster_name" : "es_cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 4,
"number_of_data_nodes" : 3,
"active_primary_shards" : 9,
"active_shards" : 18,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
Как видно из примера все работает, но мы обращались через http, значит трафик между клиентом и кластером Elasticsearch не шифрованный.

Настраиваем шифрование клиентского трафика Elasticsearch​

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

  • Генерируем сертификат:
./bin/elasticsearch-certutil http
В процессе генерации необходимо определить:

1) Необходимо ли сгенерировать Certificate Signing Request (CSR). Потребуется, если сертификат будет выпускаться сторонним CA (Certificate Authority).

2) Использовать ли собственный CA (Certificate Authority). Если да, то указываем путь до ключа, которым будет подписаны будущие сертификаты.

3) Срок действия сертификата. По умолчанию 5 лет. Можно определить дни(D), месяцы (M), года (Y).

4) Как выпустить сертификат, на каждый узел или общий. Если все узлы имеют общий домен, то можно выпустить wildcard сертификат (например *.domain.local). Если общего домена нет и в будущем возможно добавление узлов, то необходимо генерировать на каждый узел, указав имя узла и его адрес. В будущем можно выпустить отдельный сертификат для нового узла.

На выходе получаем архив сертификатами, в моём случае со всеми сертификатам для каждого узла Elasticsearch, а так же сертификат для подключения Kibana к Elasticsearch:

.
├── elasticsearch
│ ├── es-nlb01
│ │ ├── README.txt
│ │ ├── http.p12
│ │ └── sample-elasticsearch.yml
│ ├── es-node01
│ │ ├── README.txt
│ │ ├── http.p12
│ │ └── sample-elasticsearch.yml
│ ├── es-node02
│ │ ├── README.txt
│ │ ├── http.p12
│ │ └── sample-elasticsearch.yml
│ └── es-node03
│ ├── README.txt
│ ├── http.p12
│ └── sample-elasticsearch.yml
└── kibana
├── README.txt
├── elasticsearch-ca.pem
└── sample-kibana.yml
В архиве также лежит инструкция по дальнейшим действиям с сертификатом (README.txt) и пример конфигурационного файла (sample-...yml).

Сертификат elasticsearch-ca.pem из директории kibana потребуется в следующем шаге.
  • Размещаем сертификаты на узлах и добавляем необходимые настройки в файле конфигурации:
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.keystore.path: "http.p12"
  • Добавляем пароль от сгенерированного сертификата в keystore:
./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
  • Проверяем, что все работает по https:
curl -u 'elastic' -k -X GET "https://10.0.3.1:9200/_cluster/health?pretty"
Enter host password for user 'elastic':
{
"cluster_name" : "es_cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 4,
"number_of_data_nodes" : 3,
"active_primary_shards" : 9,
"active_shards" : 18,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}

Подключаем Kibana к Elasticsearch​

Если сейчас обратиться к Kibana, то ответом будет "Kibana server is not ready yet".

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

  • В конфигурационном файле Kibana указываем ключ к сертификату elasticsearch-ca.pem(из предыдущего шага) и меняем протокол http на https:
elasticsearch.hosts: ['https://10.0.3.1:9200']
elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/elasticsearch-ca.pem" ]
В примере выше я использую адрес Coordinating only узла для балансировки нагрузки между Kibana и Elasticsearch, который был настроен в предыдущей части.
  • Создаем keystore для хранения пользователя и пароля:
sudo ./bin/kibana-keystore create --allow-root
Команда выполняются из директории/usr/share/kibana
Так как keystore будет создан в каталоге /etc/kibana/ , и keystone требуется файл конфигурации /etc/kibana/kibana.yml, то пользователю, запускающему команду, необходим доступ к этому каталогу и файлу. Я использую sudo и ключ --allow-root. Ключ необходим, так как запускать из под пользователя root нельзя.
Kibana keystore не имеет пароля. Для ограничения доступа используем стандартные средства Linux.
  • Добавляем пользователя kibana_system(встроенный пользователь Elasticsearch) и пароль учетной записи в Kibana keystore:
sudo ./bin/kibana-keystore add elasticsearch.username --allow-root
sudo ./bin/kibana-keystore add elasticsearch.password --allow-root
Можно использовать так же пользователя kibana, однако, он в системе считается устаревшим (deprecated).
  • перезапускаем Kibana и проверяем открыв нужный адрес в браузере:
Kibana
Kibana
Для входа используем учетную запись elastic.

Как можно заменить, трафик между браузером и Kibana не шифруется.

Настраиваем шифрование трафика между Kibana и клиентами​

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

  • Получаем сертификат при помощи elsticsearch-certutil :
./bin/elasticsearch-certutil cert -ca /etc/elasticsearch/elastic-stack-ca.p12 -name kibana-certificate -dns kibana01,10.0.3.1,127.0.0.1,localhost -ip 10.0.3.1
При необходимости можем использовать CA (Certificate Authority). В процессе генерации сертификата указываем пароль от CA, если используется, имя будущего сертификата и пароль к нему.

Через -dns и -ip указываем DNS имена и адрес Kibana.

  • Указываем путь к сертификату в файле kibana.yml:
Так как я использовал ранее полученный CA, то указываю путь и к нему (server.ssl.truststore.path).

server.ssl.keystore.path: "/etc/kibana/kibana-certificate.p12"
server.ssl.truststore.path: "/etc/elasticsearch/elastic-stack-ca.p12"
Не забывайте о правах доступа, пользователь kibana должен иметь права на чтения.
  • Включаем использование TLS:
server.ssl.enabled: true
  • Добавляем пароли от сертификатов в keystore:
sudo ./bin/kibana-keystore add server.ssl.keystore.password --allow-root
sudo ./bin/kibana-keystore add server.ssl.truststore.password --allow-root
  • Перезагружаем Kibana и проверяем:
Доступ к Kibana по https
Доступ к Kibana по https
Теперь для подключения к Kibana используем https.

Создаем пользователей и роли​

Ранее мы активировали встроенные учетные записи и сгенерировали для них пароли, но использовать пользователя elastic (superuser) не лучшая практика, поэтому рассмотрим, как создавать пользователей и роли к ним.

Для примера создадим администратора Kibana. Открываем Menu > Management > Stack Management, выбираем Users и нажимаем Create user. Заполняем все поля и жмем Create User.

Создание пользователя в Kibana
Создание пользователя в Kibana
Или же можно воспользоваться API. Делать запросы к кластеру можно через консоль Dev Tools инструмента Kibana. Для этого перейдите Menu > Management > Dev Tools. В открывшейся консоли можно писать запросы к Elasticsearch.

POST /_security/user/kibana_admin
{
"password" : "password",
"roles" : [ "kibana_admin" ],
"full_name" : "Kibana Administrator",
"email" : "kibana.administrator@example.local"
}
Создание пользователя kibana_admin через API
Создание пользователя kibana_admin через API
После создания пользователя, можно его использовать.

Роль kibana_admin не может создавать пользователей и роли. Для создания пользователей и роли необходима привилегия кластера manage_security. С перечнем всех встроенных ролей можно ознакомится тут.
Далее создадим роль для работы с данными в ранее созданном индексом logstash-logs*. Открываем Menu > Management > Stack Management. Слева выбираем Roles и нажимаем Create role. Настраиваем привилегии, указав в качестве индекса logstash-logs*:

Index privilegesreadRead only права на индекс
Предоставляем пользователю доступ к Kibana, для этого ниже наживаем Add Kibana privilege и выбираем требуемые привилегии:

d9438e762ebbe7e22f557e40d183cd5b.png

В поле Spaces указываю All spaces. Что такое Space (пространства) можно почитать на официальном сайте. В рамках данной серии статей Space будет описан в статье о Kibana dashboard.
Чтобы создать роль с привилегиями в Elasticsearch и Kibana через API, делаем запрос к Kibana:

curl -k -i -u 'elastic' -X PUT 'https://10.0.3.1:5601/api/security/role/logstash_reader' \
--header 'kbn-xsrf: true' \
--header 'Content-Type: application/json' \
--data-raw '{
"elasticsearch": {
"cluster" : [ ],
"indices" : [
{
"names": [ "logstash-logs*" ],
"privileges": ["read"]
}
]
},
"kibana": [
{
"base": [],
"feature": {
"discover": [
"all"
],
"visualize": [
"all"
],
"dashboard": [
"all"
],
"dev_tools": [
"read"
],
"indexPatterns": [
"read"
]
},
"spaces": [
"*"
]
}
]
}'
Создаем пользователя logstash_reader и связываем его с созданной ролью (это мы уже научились делать) и заходим данным пользователем в Kibana.

Главная страница Kibana для пользователя logstash_reader
Главная страница Kibana для пользователя logstash_reader
Как видно, у данного пользователя не так много прав. Он может просматривать индексы logstash-logs*, строить графики, создавать панели и делать GET запросы к этому индексам через Dev Tools.

Настраиваем пользовательские сессии Kibana​

  • Закрываем неактивные сессии:
xpack.security.session.idleTimeout: "30m"
  • Устанавливаем максимальную продолжительность одной сессии:
xpack.security.session.lifespan: "1d"
  • Настраиваем интервал принудительной очистки данных о неактивных или просроченных сессиях из сессионного индекса:
xpack.security.session.cleanupInterval: "8h"
Для всех параметров формат времени может быть следующим: ms | s | m | h | d | w | M | Y

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

Настраиваем Logstash​

На данный момент Logstash не отправляет данные в кластер Elasticsearch, и чтобы это исправить, сделаем несколько настроек.

  • Создаем роль для подключения к кластеру:
В Kibana открываем Menu > Management > Stack Management. Слева выбираем Roles и нажимаем Create role. Указываем имя роли и настраиваем привелегии:

Cluster privileges
manage_index_templatesВсе операции над шаблонами индексов
monitorRead-only права на получение информации о кластере
Index privileges
create_indexСоздание индексов
writeИндексирование, обновление и удаление индексов
manageМониторинг и управление индексом
manage_ilmУправление жизненным циклом индексов (IML)
  • Создаем пользователя для подключения к кластер:
Открываем Menu > Management > Stack Management, выбираем Users и нажимаем Create user. Заполняем требуемые данные, указав в качестве роли созданную выше роль.

Создание пользователя logstash_user
Создание пользователя logstash_user
  • Создаем Logstash keystore, и добавляем туда пользователя и пароль от него:
# Создаем keystore с паролем
set +o history
export LOGSTASH_KEYSTORE_PASS=mypassword
set -o history
sudo /usr/share/logstash/bin/logstash-keystore create --path.settings /etc/logstash/

# Добавляем данные
sudo /usr/share/logstash/bin/logstash-keystore add ES_USER --path.settings /etc/logstash/
sudo /usr/share/logstash/bin/logstash-keystore add ES_PWD --path.settings /etc/logstash/
  • Настраиваем аутентификацию в output плагине:
output {
elasticsearch {
...
user => "${ES_USER}"
password => "${ES_PWD}"
}
}
  • Настраиваем TLS в Logstash:
Для подключения по https к Elasticsearch необходимо настроить использование ssl и установить .pem сертификат, который был получен для Kibana.

output {
elasticsearch {
...
ssl => true
cacert => '/etc/logstash/elasticsearch-ca.pem'
}
}
  • Перезагружаем Logstash и проверяем новые записи в индексе
Проверку можно сделать в Kibana через Discovery, как делали в прошлой статье, или через API:

Dev Tools - Console в Kibana
Dev Tools - Console в Kibana

Создание API ключей​

Для работы с Elasticsearch можно не только использовать учетные записи пользователей, но и генерировать API ключ. Для этого необходимо сделать POST запрос:

POST /_security/api_key
В качестве параметров указывают:

name - имя ключа

role_descriptors - описание роли. Структура совпадает с запросом на создание роли.

expiration - Срок действия ключа. По умолчанию без срока действия.

Для примера заменим базовую аутентификацию в Logstash на API ключ.

  • Создаем API ключ в Kibana Dev Tool:
POST /_security/api_key
{
"name": "host_logstash01",
"role_descriptors": {
"logstash_api_writer": {
"cluster": ["manage_index_templates", "monitor"],
"index": [
{
"names": ["logstash-logs*"],
"privileges": ["create_index", "write", "manage", "manage_ilm"]
}
]
}
},
"expiration": "365d"
}
Получаем следующий результат:

{
"id" : "979DkXcBv3stdorzoqsf",
"name" : "host_logstash01",
"expiration" : 1644585864715,
"api_key" : "EmmnKb6NTES3nlRJenFKrQ"
}
  • Помещаем ключ в формате id:api_key в Keystore:
sudo /usr/share/logstash/bin/logstash-keystore add API_KEY --path.settings /etc/logstash/
  • Указываем API ключ в конфигурационном файле конвейера:
output {
elasticsearch {
hosts => ["https://10.0.3.11:9200","https://10.0.3.12:9200","https://10.0.3.13:9200"]
index => "logstash-logs-%{+YYYY.MM}"
ssl => true
api_key => "${API_KEY}"
cacert => '/etc/logstash/elasticsearch-ca.pem'
}
}
Информацию по ключам можно получить в Kibana Menu > Management > API Keys или через API запрос:

GET /_security/api_key?name=host_logstash01

{
"api_keys" : [
{
"id" : "9r8zkXcBv3stdorzZquD",
"name" : "host_logstash01",
"creation" : 1613048800876,
"expiration" : 1613049520876,
"invalidated" : false,
"username" : "elastic",
"realm" : "reserved"
}
]
}

Заключение​

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


Источник статьи: https://habr.com/ru/post/540606/
 
Сверху