灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

  • Redis

  • 高性能KV

  • TiDB

  • Elasticsearch

    • Elasticsearch 运维知识地图:从安装配置到排障加速恢复
    • Elasticsearch 集群安装:RPM 裸机生产部署 vs docker-compose 快速起集群
    • 给Elasticsearch集群添加用户密码
      • 1. 区分 Realm 类型
      • 2. 内置用户与密码初始化
        • 密码初始化工具
      • 3. 在已有集群上开启安全特性
        • 3.1 完整的开启顺序
        • 3.2 敏感值走 keystore,不要写进配置文件
        • 3.3 客户端侧的变化
      • 4. File Realm(本地用户)
        • 4.1 启用安全特性
        • 4.2 使用 CLI 工具创建用户(不要直接编辑 users 文件)
        • 4.3 定义角色权限
        • 4.4 验证
      • 5. External Realm(LDAP/AD/SAML/PKI)
        • 5.1 启用并配置 realm
        • 5.2 配置角色映射(role_mapping.yml)
        • 5.3 重启生效
      • 6. 第三种方式:API Key
        • 6.1 创建 API Key
        • 6.2 使用 API Key
        • 6.3 吊销 API Key
      • 7. 角色权限的最小化设计
        • 7.1 只读角色示例
        • 7.2 写入角色示例
        • 7.3 管理角色示例
      • 8. 为什么 transport.ssl 是必需的
      • 9. 常见错误
      • 10. 验证清单
    • Elasticsearch 分片和副本:容量怎么规划,改分片数为什么这么麻烦
    • Elasticsearch集群节点磁盘使用分配不均解决办法
    • Elasticsearch 索引模板与映射:Composable 模板、mapping 与动态模板
    • Elasticsearch 分页查询三种方案:from/size、search_after、scroll 怎么选
    • Elasticsearch字符串搜索方式
    • Elasticsearch使用wildcard字段模糊匹配
    • Elasticsearch 数据迁移方案对比:esm vs Logstash
    • Nginx Mirror 模块实现三套ES写入网关
    • ES排障两件套:慢查询日志阈值配置 + tcpdump 抓包看真实请求
    • ES 集群恢复太慢?三个参数加速节点/分片恢复
    • Elasticsearch 常用 DSL 语句(速查表)
    • ES 集群 Yellow 复盘:1023 个副本永远分配不出去,问题不在磁盘
  • 数据管道

  • 其他数据库

  • 数据库
  • Elasticsearch
灯下哥谭
2022-03-17
目录

给Elasticsearch集群添加用户密码

ES 7.x 默认裸奔,任何能连到 9200 端口的人都能执行 DELETE /index——因为在普及之初,ES 的设计假设是「运行在可信内网」。等到了发现需要认证时,往往不是「加个密码」那么简单:先得分清用户存在哪儿(本地 file realm 还是外部 LDAP/AD),两条路的配置方式完全不同,安全威胁模型也完全不同。

以下分两种情况说明:小集群用 file realm,对接企业身份体系用 external realm。在讲解配置之前,先理解几个关键概念。

版本说明

本文写于 2022-03,基于 Elasticsearch 7.x。
在 8.x 上的差异:安全特性默认开启,本文手动开启 xpack.security.enabled 并配置密码的步骤在 8.x 上已是默认行为,首次启动会自动生成密码;如需重置密码,命令 elasticsearch-reset-password 用法未变。

# 1. 区分 Realm 类型

Elasticsearch 支持多种用户域(realm):

  • File realm(本地文件):用户存在 ES_PATH_CONF/users 和 roles.yml,适合小规模固定用户
  • External realm(LDAP/AD/SAML/PKI):用户在外部系统,ES 只保存角色映射关系

不同 realm,配置方式完全不同——下文分两种情况说明。


# 2. 内置用户与密码初始化

ES 7.x 开启 xpack.security.enabled: true 后,会自动创建 5 个内置用户,用于集群内部组件通信和初始管理:

内置用户 用途 典型使用场景
elastic 超级管理员,拥有 cluster 级别全部权限 仅用于初始配置和紧急恢复,日常不要分发
kibana_system Kibana 连接 ES 时使用的身份 Kibana 配置中的 elasticsearch.username
logstash_system Logstash 监控数据写入 Logstash 配置中的 xpack.monitoring.elasticsearch.username
beats_system Beats 监控数据写入 Beats 配置中的 setup.kibana.username
apm_system APM Server 数据写入 APM Server 配置中的 output.elasticsearch.username

# 密码初始化工具

7.x 使用 elasticsearch-setup-passwords(在 8.x 中已移除):

# 交互式设置全部内置用户密码
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

# 批量自动设置(脚本用,输出到指定文件)
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto --batch > /etc/es_passwords.txt
1
2
3
4
5

8.x 首启自动生成密码,存储在控制台输出或指定文件中。如需重置(该命令在 7.x 不可用):

sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
1

# 3. 在已有集群上开启安全特性

重要

开启安全特性不能滚动进行,必须全集群停机后统一改配置再一起启动(full cluster restart)。

xpack.security.enabled 与 transport TLS 是集群级的通信协议变更。开了安全的节点和没开的节点无法互相通信,滚动重启会让集群在中途分裂成两半互相认不出来。这是开安全特性最容易低估的运维代价,要专门排变更窗口。

# 3.1 完整的开启顺序

  1. 为 transport 层生成并分发证书到所有节点
  2. 所有节点同时改配置:启用 xpack.security.enabled 和 transport TLS
  3. 停整个集群:systemctl stop elasticsearch 或 kill -TERM
  4. 一起启动所有节点
  5. 设置内置用户密码:elasticsearch-setup-passwords(7.x)或记下 8.x 自动生成的密码
  6. 逐个改客户端:Kibana、Logstash、Beats、业务方,全部加上认证

# 3.2 敏感值走 keystore,不要写进配置文件

密码、密钥等敏感值不要硬编码在 elasticsearch.yml 里,改用 elasticsearch-keystore:

# 添加敏感值
sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password

# 查看已有项
sudo /usr/share/elasticsearch/bin/elasticsearch-keystore list

# 删除(如需轮换)
sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove xpack.security.transport.ssl.keystore.secure_password
1
2
3
4
5
6
7
8

配置文件里用 ${VAR} 占位,如:

xpack.security.transport.ssl.keystore.password: ${KESTORE_PASSWORD}
1

keystore 是每个节点本地的文件,加完要同步到所有节点,然后重启该节点生效。

# 3.3 客户端侧的变化

开启安全特性后,所有 curl 都要带 -u user:pass 或 API Key:

curl -u elastic:<密码> http://localhost:9200/_cluster/health
1

8.x 还默认开启 HTTP 层 TLS,需要额外带 --cacert 或 --insecure:

curl -u elastic:<密码> --cacert /etc/elasticsearch/certs/ca.crt https://localhost:9200/_cluster/health
1

忘了带认证的表现是 401 Unauthorized,不是连接失败或超时。排查时别往网络问题上钻。


# 4. File Realm(本地用户)

# 4.1 启用安全特性

# /etc/elasticsearch/elasticsearch.yml
xpack.security.enabled: true
1
2

重启 ES 生效:

sudo systemctl restart elasticsearch
1

# 4.2 使用 CLI 工具创建用户(不要直接编辑 users 文件)

# 创建用户并设置密码(交互式)
sudo /usr/share/elasticsearch/bin/elasticsearch-users useradd my_user -r my_role -p

# 非交互式(脚本用)
sudo /usr/share/elasticsearch/bin/elasticsearch-users useradd my_user -r my_role -p <密码>
1
2
3
4
5

-r 指定角色,多个角色用逗号分隔。该命令会同时修改 users 和 users_roles 两个文件,无需重启即生效。

# 4.3 定义角色权限

编辑 ES_PATH_CONF/roles.yml:

my_role:
  cluster: ["monitor", "manage_index_templates"]
  indices:
    - names: ["logs-*"]
      privileges: ["read", "write", "create_index"]
1
2
3
4
5

角色变更无需重启,但已登录用户需重新认证才生效。

# 4.4 验证

# 验证用户存在且角色正确
curl -u my_user:<密码> http://localhost:9200/_security/_authenticate
1
2

# 5. External Realm(LDAP/AD/SAML/PKI)

外部域用户不保存在 ES 本地,ES 只维护「外部身份 ↔ ES 角色」的映射关系。

# 5.1 启用并配置 realm

# elasticsearch.yml
xpack.security.authc.realms.ldap.ldap1:
  order: 0
  url: "ldaps://ldap.example.com:636"
  bind_dn: "cn=admin,dc=example,dc=com"
  bind_password: "${LDAP_PASSWORD}"  # 用密钥库,不要明文
  user_search:
    base_dn: "ou=users,dc=example,dc=com"
    filter: "(cn={0})"
  group_search:
    base_dn: "ou=groups,dc=example,dc=com"
  files:
    role_mapping: "ES_PATH_CONF/role_mapping.yml"
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.2 配置角色映射(role_mapping.yml)

# 将 LDAP 组映射到 ES 角色
my_role:
  - "cn=ES_Admin,ou=groups,dc=example,dc=com"
  - "cn=DevOps,ou=groups,dc=example,dc=com"
1
2
3
4

注意:role_mapping.yml 仅用于外部域。File realm 用户不应出现在此文件中。

# 5.3 重启生效

外部 realm 配置变更需要重启 ES:

sudo systemctl restart elasticsearch
1

# 6. 第三种方式:API Key

对于程序化访问(如 CI/CD 流水线、数据同步任务),与其分配长期账号密码,不如使用 API Key:

  • 可设过期时间,减少泄露后长期有效带来的风险
  • 可单独吊销,不影响其他凭证
  • 权限精确到索引和动作,权限面更小

# 6.1 创建 API Key

curl -X POST "localhost:9200/_security/api_key" -u elastic:<密码> -H "Content-Type: application/json" -d '{
  "name": "daily-backup-job",
  "expiration": "30d",
  "role_descriptors": {
    "backup_role": {
      "cluster": ["monitor"],
      "indices": [
        {
          "names": ["logs-*"],
          "privileges": ["read"]
        }
      ]
    }
  }
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 6.2 使用 API Key

响应中包含 encoded 字段(id:api_key 的 base64),在请求头中使用:

curl -H "Authorization: ApiKey <base64_encoded_key>" http://localhost:9200/_cluster/health
1

# 6.3 吊销 API Key

# 通过 id 吊销
curl -X DELETE "localhost:9200/_security/api_key?id=<api_key_id>" -u elastic:<密码>

# 批量吊销(通过 name 或过期前吊销)
curl -X DELETE "localhost:9200/_security/api_key" -u elastic:<密码> -H "Content-Type: application/json" -d '{
  "name": "daily-backup-job"
}'
1
2
3
4
5
6
7

API Key 的权限边界在创建时就已经确定,scopes 精确到索引、动作,与调用者身份解耦。这是服务账号升级后的安全形态。


# 7. 角色权限的最小化设计

ES 权限模型分为 cluster 级别和 indices 级别:

  • Cluster 权限:创建索引、管理集群状态、查看监控等
  • Indices 权限:索引的读、写、删除、查看 mapping 等

给只读查询方分配 read + view_index_metadata 即可,不要给 all;写入方要 write + create_index 但不需要 delete。

# 7.1 只读角色示例

# roles.yml - 只读角色
logs_reader:
  cluster: ["monitor"]
  indices:
    - names: ["logs-*", "metrics-*"]
      privileges: ["read", "view_index_metadata"]
1
2
3
4
5
6
  • monitor:允许查看集群健康状态(_cluster/health)
  • read:查询文档
  • view_index_metadata:获取索引 mapping 和 settings

# 7.2 写入角色示例

# roles.yml - 写入角色
logs_writer:
  cluster: ["monitor", "manage_index_templates"]
  indices:
    - names: ["logs-*"]
      privileges: ["write", "create_index", "auto_configure"]
1
2
3
4
5
6
  • write:写入文档、批量导入
  • create_index:索引不存在时自动创建
  • auto_configure:支持动态模板映射(ES 7.7+)
  • 不给 delete:防止误删索引或文档

# 7.3 管理角色示例

# roles.yml - 管理角色(供运维人员)
logs_admin:
  cluster: ["monitor", "manage_ilm", "manage_index_templates", "cluster:admin/ingest/pipeline/put"]
  indices:
    - names: ["logs-*", ".ilm-*"]
      privileges: ["all"]
1
2
3
4
5
6

# 8. 为什么 transport.ssl 是必需的

重要

开启 xpack.security.enabled: true 后,必须同时配置 transport 层 TLS,否则认证形同虚设。

ES 节点间通过 transport 端口(默认 9300)通信。如果这个通道不加密且不要求证书认证,任何能连上 9300 的进程都能伪装成集群节点加入,继承集群的查询权限,甚至伪装成 master 下发分片分配指令。这就是「节点伪装(node impersonation)」攻击。

因此,安全加固的正常顺序是:

  1. 为 transport 层生成 CA 和节点证书(创建密钥库 elasticsearch.keystore)
  2. 在 elasticsearch.yml 中启用 transport 层加密和双向证书认证,要求所有节点信任同一 CA
  3. 在 elasticsearch.yml 中启用 http 层 TLS(对外 9200 端口)
  4. 最后 才启用 xpack.security.enabled: true,用内置工具初始化账号密码

原文件里那一堆 keystore、truststore、certificate_authorities 配置不是可选的安全增强,而是让认证真正生效的前提——没有它们,节点可被任意仿冒,账号密码等于没用。


# 9. 常见错误

错误 原因 修复
No user found 用 role_mapping.yml 给 file realm 用户配角色 File realm 直接用 elasticsearch-users 分配角色,不要改 role_mapping.yml
Incorrect password 直接 nano 编辑 users 文件后格式错误 始终用 elasticsearch-users CLI 工具操作
用户无权限 角色权限配置在 roles.yml 但用户未绑定 检查 users_roles 文件或 CLI 输出中的角色列表

# 10. 验证清单

# 1. 安全特性已启用
GET _cluster/settings?include_defaults=true&filter_path=defaults.xpack.security.enabled

# 2. 当前生效的 realm 列表
GET _security/_authenticate

# 3. 特定用户权限详情
GET _security/user/my_user

# 4. 角色权限定义
GET _security/role/my_role
1
2
3
4
5
6
7
8
9
10
11
#安全加固#Elasticsearch
上次更新: 9/11/2026

← Elasticsearch 集群安装:RPM 裸机生产部署 vs docker-compose 快速起集群 Elasticsearch 分片和副本:容量怎么规划,改分片数为什么这么麻烦→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式