Безопасность: пользователи, роли и API-ключи

В Elasticsearch 8 безопасность включена по умолчанию с самого первого запуска — в отличие от более ранних версий, где её нужно было включать вручную. Это означает: без аутентификации кластер не ответит ни на один запрос, а весь трафик шифруется по TLS. Разберём, из чего состоит эта модель доступа и как с ней работать.


Три кита безопасности ES 8

Модель безопасности строится на трёх уровнях, которые работают вместе:

1. TLS — шифрует весь трафик: между клиентом и нодой (HTTP, порт 9200) и между нодами в кластере (transport, порт 9300). Сертификаты генерируются автоматически при первом старте.

2. Аутентификация — «кто ты?». Проверяет личность через логин/пароль, токен или API-ключ.

3. Авторизация (RBAC) — «что тебе можно?». Определяет, к каким индексам и операциям у пользователя есть доступ через роли.

flowchart TD Client(["Клиент / приложение"]) TLS["TLS-шифрование\n(HTTP 9200)"] Auth["Аутентификация\n(кто ты?)"] RBAC["Авторизация RBAC\n(что тебе можно?)"] ES[("Elasticsearch\nиндекс / данные")] Client -->|"Запрос по HTTPS"| TLS TLS --> Auth Auth -->|"Логин/пароль\nили API-ключ"| RBAC RBAC -->|"Роли и привилегии\n→ разрешить / отклонить"| ES style TLS fill:#e8f4fd,stroke:#4a90d9 style Auth fill:#fff3cd,stroke:#f0ad4e style RBAC fill:#d4edda,stroke:#28a745 style ES fill:#f8d7da,stroke:#dc3545
flowchart TD
    Client(["Клиент / приложение"])
    TLS["TLS-шифрование\n(HTTP 9200)"]
    Auth["Аутентификация\n(кто ты?)"]    
    RBAC["Авторизация RBAC\n(что тебе можно?)"]
    ES[("Elasticsearch\nиндекс / данные")]

    Client -->|"Запрос по HTTPS"| TLS
    TLS --> Auth
    Auth -->|"Логин/пароль\nили API-ключ"| RBAC
    RBAC -->|"Роли и привилегии\n→ разрешить / отклонить"| ES

    style TLS fill:#e8f4fd,stroke:#4a90d9
    style Auth fill:#fff3cd,stroke:#f0ad4e
    style RBAC fill:#d4edda,stroke:#28a745
    style ES fill:#f8d7da,stroke:#dc3545
Три уровня безопасности: TLS → аутентификация → авторизация (RBAC)

При первом запуске ES самостоятельно генерирует:

  • TLS-сертификаты для HTTP и транспортного слоя.
  • Случайный пароль для встроенного суперпользователя elastic.
  • Enrollment-токен (действует 30 минут) для подключения Kibana.

Всё это выводится в консоль при старте — важно сохранить пароль elastic сразу. Если потеряли, сбросить можно командой:

# В контейнере или на ноде
bin/elasticsearch-reset-password -u elastic

Встроенные пользователи

Elasticsearch поставляется с несколькими встроенными пользователями. Их нельзя удалить, но можно (и нужно) настроить пароли перед боевым использованием.

ПользовательНазначение
elasticСуперпользователь с полным доступом ко всему кластеру. Используйте только для первоначальной настройки.
kibana_systemСлужебный аккаунт для подключения Kibana к ES. Не предназначен для прямой работы.
logstash_systemДля хранения мониторинговых данных Logstash.
beats_systemДля Beats (Filebeat, Metricbeat и т. д.).
apm_systemДля APM-сервера.
remote_monitoring_userДля Metricbeat при сборе метрик мониторинга.

Важный момент: встроенные пользователи (кроме elastic при первом старте) не имеют пароля по умолчанию — их нужно установить явно, прежде чем использовать. Сделать это можно через API:

POST /_security/user/kibana_system/_password
{
  "password": "сильный_пароль_здесь"
}

Правило хорошего тона: не используйте elastic для запросов из приложения. Создайте отдельного пользователя с минимально необходимыми правами — это называется принципом минимальных привилегий.

Check yourself
Зачем вообще нужны отдельные встроенные пользователи вроде `kibana_system`, если есть суперпользователь `elastic`? Что было бы плохого в том, чтобы Kibana подключалась к ES под `elastic`?

Создание собственных пользователей

Для сотрудников и приложений создаются пользователи в «native realm» — встроенном хранилище учётных записей ES.

POST /_security/user/anna
{
  "password": "секретный_пароль",
  "roles": ["viewer"],
  "full_name": "Anna Ivanova",
  "email": "anna@example.com"
}

Посмотреть всех пользователей:

GET /_security/user

Изменить пароль:

POST /_security/user/anna/_password
{
  "password": "новый_пароль"
}

Удалить пользователя:

DELETE /_security/user/anna

Роли и RBAC

RBAC (Role-Based Access Control) — модель, при которой права назначаются не напрямую пользователю, а через роли. Пользователь получает одну или несколько ролей, роль описывает что именно разрешено.

ES поставляется с рядом встроенных ролей:

РольЧто даёт
superuserПолный доступ ко всему. Только для администратора.
editorПолный доступ к Kibana + чтение индексов.
viewerТолько чтение — Kibana и индексы.
kibana_adminПолный доступ ко всем пространствам Kibana.
snapshot_userСоздание снапшотов, без права восстановления.
monitoring_userЧтение мониторинговых данных.

Однако для реальных приложений встроенных ролей часто недостаточно. Создаём свою роль:

PUT /_security/role/catalog_reader
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["products", "categories"],
      "privileges": ["read", "view_index_metadata"]
    }
  ]
}

Эта роль даёт доступ только к индексам products и categories, только на чтение. Назначим её пользователю:

POST /_security/user/search_app
{
  "password": "сложный_пароль",
  "roles": ["catalog_reader"]
}

Привилегии на уровне индексов (index privileges) определяют гранулярно, что можно делать с каждым индексом. Наиболее используемые:

  • read — поиск и получение документов.
  • write — создание, обновление и удаление документов.
  • index — только индексация (без удаления).
  • create_index — создание индекса.
  • manage — изменение настроек и маппинга.
  • all — всё перечисленное.

Привилегии на уровне кластера (cluster privileges) управляют административными операциями:

  • monitor — чтение метрик и состояния кластера.
  • manage — изменение настроек кластера.
  • manage_index_templates — работа с шаблонами индексов.
  • manage_security — управление пользователями, ролями и API-ключами.
Check yourself
Вы создали роль с правами `read` на индекс `products` и назначили её пользователю. Сможет ли этот пользователь: 1. Выполнить запрос `GET /products/_search`? 2. Выполнить `PUT /products/_doc/1 {...}`? 3. Выполнить `GET /_cluster/health`?

API-ключи: безопасный доступ для приложений

Для бэкенд-приложений использовать логин/пароль в коде — плохая практика: пароль может утечь, его сложно ротировать, и при компрометации придётся сбрасывать его везде. Правильное решение — API-ключи.

API-ключ — это отдельный токен доступа, который:

  • можно выдать с ограниченными правами (уже не важно, что делать может его владелец-пользователь);
  • легко инвалидировать, не затрагивая другие ключи или пароль пользователя;
  • можно снабдить сроком действия;
  • можно отслеживать отдельно (какой ключ что делал).

#### Создание API-ключа

POST /_security/api_key
{
  "name": "search-service-key",
  "expiration": "90d",
  "role_descriptors": {
    "catalog_access": {
      "cluster": ["monitor"],
      "indices": [
        {
          "names": ["products", "categories"],
          "privileges": ["read"]
        }
      ]
    }
  },
  "metadata": {
    "service": "search-backend",
    "team": "platform"
  }
}

Ответ:

{
  "id": "VuaCfGcBCdbkQm-e5aOx",
  "name": "search-service-key",
  "expiration": 1735689600000,
  "api_key": "ui2lp2axTNmsyakw9tvNnw",
  "encoded": "VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw=="
}

Поле encoded — это уже готовая строка Base64(id:api_key). Сохраните api_key — он показывается только один раз. Потеряли — только инвалидировать и создавать новый.

#### Использование API-ключа

В запросах передаётся в заголовке Authorization:

curl -H "Authorization: ApiKey VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==" \
     https://localhost:9200/products/_search

В Kibana Dev Tools этот заголовок можно передать через настройки запроса, но для Dev Tools обычно достаточно логина через интерфейс Kibana.

#### Управление ключами

Посмотреть свои ключи:

GET /_security/api_key?name=search-service-key

Посмотреть все ключи кластера (нужна привилегия manage_security):

GET /_security/api_key

Инвалидировать ключ (например, при увольнении сотрудника или компрометации):

DELETE /_security/api_key
{
  "ids": ["VuaCfGcBCdbkQm-e5aOx"]
}
Check yourself
Вы создали API-ключ для бэкенда с правами только на чтение индекса `products`. Пользователь, под которым создавался ключ, имеет роль суперпользователя. Сможет ли этот ключ удалить индекс `products`?

Права для запросов мониторинга

В статье про мониторинг мы активно использовали _cluster/health и _cat-API. Чтобы эти запросы работали у пользователя без роли superuser, ему нужна либо встроенная роль monitoring_user, либо кластерная привилегия monitor в кастомной роли:

PUT /_security/role/ops_reader
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": [".monitoring-*", ".kibana*"],
      "privileges": ["read"]
    }
  ]
}

Место TLS в защите кластера

TLS решает две задачи, которые аутентификация и авторизация не решают:

1. Шифрование в транзите — никто не перехватит логин/пароль или содержимое документов «на проводе».

2. Верификация ноды — при добавлении новой ноды в кластер enrollment-токен и сертификат CA гарантируют, что к кластеру присоединилась именно та нода, а не посторонний сервер.

ES 8 автоматически генерирует самоподписанный CA и сертификаты. Для продакшена стоит заменить их на сертификаты от доверенного удостоверяющего центра (Let's Encrypt или корпоративного CA), но для старта и dev-окружения автогенерируемые работают «из коробки».


Типичный сценарий: настройка доступа с нуля

Предположим, вы разворачиваете поисковый бэкенд для каталога товаров. Вот минимальная последовательность:

# 1. Создать роль с ограниченным доступом
PUT /_security/role/catalog_search
{
  "cluster": [],
  "indices": [
    {
      "names": ["products"],
      "privileges": ["read"]
    }
  ]
}

# 2. Создать API-ключ для бэкенда (без привязки к конкретному пользователю,
#    права ограничены role_descriptors в самом ключе)
POST /_security/api_key
{
  "name": "catalog-backend-prod",
  "expiration": "365d",
  "role_descriptors": {
    "catalog_search": {
      "cluster": [],
      "indices": [
        {
          "names": ["products"],
          "privileges": ["read"]
        }
      ]
    }
  }
}

# 3. Создать пользователя для администратора каталога
POST /_security/user/catalog_admin
{
  "password": "StrongPass123!",
  "roles": ["catalog_search", "snapshot_user"]
}

Бэкенд-сервис использует API-ключ. Администратор — свой логин/пароль через Kibana. Суперпользователь elastic — только для экстренных случаев.


Quick recall
Чем RBAC отличается от выдачи прав напрямую пользователю?
Quick recall
Какой встроенный пользователь используется только для первоначальной настройки?
Quick recall
Что произойдёт, если отправить запрос к ES 8 без учётных данных?

См. также