
Вступительное слово
В первой и второй частях данной серии статей была описана процедура установки и настройки кластера Elasticsearch, Kibana и Logstash, но не был освящен вопрос безопасности.В этой статье я расскажу, как настроить шифрование трафика между узлами кластера Elasticsearch и его клиентам, шифрование трафика между Kibana и клиентами, покажу, как создавать роли и пользователей, а так же выдавать API ключи для доступа к кластеру Elasticsearch.
План действий
- "Включаем" безопасность.
- Настраиваем шифрование между узлами Elasticsearch.
- Настраиваем аутентификацию.
- Настраиваем шифрование клиентского трафика Elasticsearch.
- Подключаем Kibana к Elasticsearch.
- Настраиваем шифрование трафика между Kibana и клиентами.
- Создаем пользователей и роли.
- Настраиваем пользовательские сессии в Kibana.
- Настраиваем Logstash.
- Создаем API ключи.
"Включаем" безопасность
Чтобы использовать функции безопасности в Elasticsearch, их необходимо активировать. Для этого на каждом узле в файле конфигурации указывается следующая настройка:xpack.security.enabled: true
Настраиваем шифрование между узлами Elasticsearch
Следующим шагом необходимо настроить шифрование трафика между узлами Elasticsearch. Для этого выполняем несколько шагов:- Создаем CA (Certificate Authority) для кластера Elasticsearch:
Во время генерации корневого сертификата можно задать имя PKCS#12 файла, по умолчанию это elastic-stack-ca.p12 и пароль к нему.Для установки из пакетов Deb и RPM исполняемые файлы Elasticsearch лежат в каталоге /usr/share/elasticsearch/bin/. Для установки из архива - в каталоге $ES_HOME/bin/.
В примерах все команды выполнены из каталога /usr/share/elasticsearch/.
Для получения сертификата и ключа в PEM формате укажите ключ --pem. На выходе будет ZIP архив с .crt и .key файлами.
С помощью ключа --out можно указать каталог для создаваемого файла.
Полученный корневой сертификат (для PEM формата еще и ключ) надо переместить на все узлы кластера для генерации сертификата узла.
- Генерируем на каждом узле кластера сертификат и ключ:
Ключ --ca указывает путь к корневому сертификату CA в формате PKCS#12. Если сертификат и ключ были получены в PEM формате, то необходимо использовать ключи --ca-cert и --ca-key соответственно.
Ключи --dns и --ip добавляют проверку по имени узла и IP адресу и являются опциональными. Если вы указываете их, то укажите эти параметры для каждого узла.
Ключ --pass позволяет установить passphrase для ключа.
- Включаем TLS в файле конфигурации Elasticsearch:
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 и добавляем пароли от сертификатов(если они были заданы):
Для PKCS#12 формата:Ключ -p требуется для установки пароля keystone во время создания
./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
[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 |
./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
Попробуем сделать API запрос к любому узлу Elasticsearch с использованием учетной записи elastic и пароля к от неё:Второй раз elasticsearch-setup-passwords запустить не получится, так как bootstrap password изменился. Чтобы изменить пароль пользователям можно воспользоваться API.
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. Для этого делаем следующее:- Генерируем сертификат:
В процессе генерации необходимо определить:
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:
- Проверяем, что все работает по https:
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.ssl.certificateAuthorities: [ "/etc/kibana/elasticsearch-ca.pem" ]
В примере выше я использую адрес Coordinating only узла для балансировки нагрузки между Kibana и Elasticsearch, который был настроен в предыдущей части.
- Создаем keystore для хранения пользователя и пароля:
Команда выполняются из директории/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.password --allow-root
Можно использовать так же пользователя kibana, однако, он в системе считается устаревшим (deprecated).
- перезапускаем Kibana и проверяем открыв нужный адрес в браузере:

Для входа используем учетную запись elastic.
Как можно заменить, трафик между браузером и Kibana не шифруется.
Настраиваем шифрование трафика между Kibana и клиентами
Данная процедура максимально похожа на ту, которую выполняли для получения сертификатов для узлов Elasticsearch.- Получаем сертификат при помощи elsticsearch-certutil :
При необходимости можем использовать CA (Certificate Authority). В процессе генерации сертификата указываем пароль от CA, если используется, имя будущего сертификата и пароль к нему.
Через -dns и -ip указываем DNS имена и адрес Kibana.
- Указываем путь к сертификату в файле kibana.yml:
server.ssl.keystore.path: "/etc/kibana/kibana-certificate.p12"
server.ssl.truststore.path: "/etc/elasticsearch/elastic-stack-ca.p12"
Не забывайте о правах доступа, пользователь kibana должен иметь права на чтения.
- Включаем использование TLS:
- Добавляем пароли от сертификатов в keystore:
sudo ./bin/kibana-keystore add server.ssl.truststore.password --allow-root
- Перезагружаем Kibana и проверяем:

Теперь для подключения к Kibana используем https.
Создаем пользователей и роли
Ранее мы активировали встроенные учетные записи и сгенерировали для них пароли, но использовать пользователя elastic (superuser) не лучшая практика, поэтому рассмотрим, как создавать пользователей и роли к ним.Для примера создадим администратора Kibana. Открываем Menu > Management > Stack Management, выбираем Users и нажимаем Create user. Заполняем все поля и жмем Create User.

Или же можно воспользоваться 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"
}

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

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

Как видно, у данного пользователя не так много прав. Он может просматривать индексы logstash-logs*, строить графики, создавать панели и делать GET запросы к этому индексам через Dev Tools.
Настраиваем пользовательские сессии Kibana
- Закрываем неактивные сессии:
- Устанавливаем максимальную продолжительность одной сессии:
- Настраиваем интервал принудительной очистки данных о неактивных или просроченных сессиях из сессионного индекса:
Для всех параметров формат времени может быть следующим: ms | s | m | h | d | w | M | Y
Данные о сессии удаляются после того, как пользователь осуществляет закрытие сессии. Если не настроить закрытие неактивных сессий или не ограничить максимальную длительность сессии, то информация об этих сессиях будет накапливаться в сессионном индексе, и Kibana не сможет автоматически удалить данные.
Настраиваем Logstash
На данный момент Logstash не отправляет данные в кластер Elasticsearch, и чтобы это исправить, сделаем несколько настроек.- Создаем роль для подключения к кластеру:
Cluster privileges | manage_index_templates | Все операции над шаблонами индексов |
monitor | Read-only права на получение информации о кластере | |
Index privileges | create_index | Создание индексов |
write | Индексирование, обновление и удаление индексов | |
manage | Мониторинг и управление индексом | |
manage_ilm | Управление жизненным циклом индексов (IML) |
- Создаем пользователя для подключения к кластер:

- Создаем Logstash 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 плагине:
elasticsearch {
...
user => "${ES_USER}"
password => "${ES_PWD}"
}
}
- Настраиваем TLS в Logstash:
output {
elasticsearch {
...
ssl => true
cacert => '/etc/logstash/elasticsearch-ca.pem'
}
}
- Перезагружаем Logstash и проверяем новые записи в индексе

Создание API ключей
Для работы с Elasticsearch можно не только использовать учетные записи пользователей, но и генерировать API ключ. Для этого необходимо сделать POST запрос:POST /_security/api_key
В качестве параметров указывают:
name - имя ключа
role_descriptors - описание роли. Структура совпадает с запросом на создание роли.
expiration - Срок действия ключа. По умолчанию без срока действия.
Для примера заменим базовую аутентификацию в Logstash на API ключ.
- Создаем API ключ в Kibana Dev Tool:
{
"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:
- Указываем API ключ в конфигурационном файле конвейера:
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/