ElasticsearchNotes

第 31 章:安全与权限治理

zjc 于 2026-01-31 发布

这是《Elasticsearch 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Elasticsearch 常常保存搜索数据、日志、用户行为和业务分析结果,其中日志字段可能包含手机号、IP、请求头、授权 token,甚至数据库连接串。安全不是上线后补一项开关,而是从网络、传输、认证、授权、审计和数据分级六个层面同时治理。

31.1 安全边界

一个生产集群至少要明确:

谁能访问集群?
  -> TLS / VPN / 网络边界
谁能调用 API?
  -> 认证
能访问哪些索引?
  -> index privileges
能看到哪些文档?
  -> document level security
能看到哪些字段?
  -> field level security
做过什么操作?
  -> audit logging
数据保留多久?
  -> ILM / snapshot / compliance

常见风险:

风险 后果
集群裸奔公网 全量读写、删除索引
共享超级用户 无法定位误操作人
日志字段全量开放 泄露 token、手机号、IP
客户端明文传输 凭据和数据被窃听
任意 Dashboard 查询 一个大聚合拖垮集群
快照桶权限过宽 绕过 ES 权限读数据
API key 不轮换 长期凭据泄露

31.2 传输加密 TLS

生产环境应启用:

Elasticsearch 8.x 默认更强调安全,生产应使用受信任 CA 签发证书,而不是长期使用自动生成证书。

elasticsearch.yml 示例:

xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: full
xpack.security.transport.ssl.keystore.path: certs/es01.p12
xpack.security.transport.ssl.truststore.path: certs/truststore.p12

xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
xpack.security.http.ssl.truststore.path: certs/truststore.p12

把密码放入 keystore:

bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password

验证:

curl -vk https://localhost:9200

不要关闭主机名或节点证书校验。verification_mode: none 只适合临时排障,且必须在工单中记录恢复时间。

31.3 认证

常见认证方式:

方式 适合 注意
内置用户 运维和初始化 不用于应用共享
LDAP / Active Directory 企业统一账号 组映射要简洁
SAML / OIDC Kibana 登录 区分用户和机器
API key 服务集成 scope、过期、轮换
服务账号 应用写入 最小索引权限

创建本地用户:

POST /_security/user/search_app
{
  "password": "change-me",
  "roles": ["products_writer"],
  "full_name": "Search Application"
}

修改密码:

PUT /_security/user/search_app/_password
{
  "password": "new-password"
}

生产应用更推荐使用配置中心托管的密码或 API key,并定期轮换。

31.4 API Key

API Key 适合服务与服务之间的认证。

POST /_security/api_key
{
  "name": "search-app-prod",
  "expiration": "30d",
  "role_descriptors": {
    "products_writer": {
      "cluster": ["monitor"],
      "indices": [
        {
          "names": ["products-v3", "products-write"],
          "privileges": ["create_index", "write", "read"]
        }
      ]
    }
  }
}

返回:

{
  "id": "api_key_id",
  "encoded": "base64_api_key"
}

查询:

GET /_security/api_key?name=search-app-prod
POST /_security/_query_api_key
{
  "query": {
    "term": { "name": "search-app-prod" }
  }
}

失效:

DELETE /_security/api_key
{
  "id": "api_key_id"
}

治理要求:

31.5 角色与索引权限

创建角色:

POST /_security/role/products_writer
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["products-v3"],
      "privileges": ["write", "create_index", "view_index_metadata"]
    }
  ]
}

只读角色:

POST /_security/role/products_reader
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["products-read"],
      "privileges": ["read"]
    }
  ]
}

常用权限:

权限 说明
read 搜索和读取文档
write 写入文档
create_index 创建索引
delete_index 删除索引
manage 管理索引
view_index_metadata 查看 Mapping、settings
monitor 查看监控
manage_index_templates 管理模板

应用账号不应拥有:

31.6 文档级安全

Document Level Security 允许角色只看到满足查询条件的文档。

POST /_security/role/order_team_reader
{
  "indices": [
    {
      "names": ["orders-v3"],
      "privileges": ["read"],
      "query": {
        "term": { "team_id": "team_order" }
      }
    }
  ]
}

多租户示例:

"query": {
  "term": { "tenant_id": "tenant_1001" }
}

注意:

31.7 字段级安全

Field Level Security 控制角色可见字段。

POST /_security/role/logs_reader
{
  "indices": [
    {
      "names": ["logs-app-*"],
      "privileges": ["read"],
      "field_security": {
        "grant": [
          "@timestamp",
          "service.name",
          "log.level",
          "message",
          "trace.id"
        ],
        "except": []
      }
    }
  ]
}

也可以默认允许,排除敏感字段:

"field_security": {
  "grant": ["*"],
  "except": ["authorization", "token", "request.headers"]
}

建议:

31.8 Kibana 权限

Kibana 权限应按空间和功能收敛:

角色 权限
普通开发 指定空间的 read,能看到本团队索引
值班工程师 Discover、Dashboard、告警查看
SRE 集群监控、索引管理、有限写权限
数据分析 只读聚合空间
平台管理员 权限管理,但操作有审计

危险操作要分离:

Kibana Dashboard 也可能因为无时间范围查询导致集群压力,应通过空间、索引权限和默认查询约束共同治理。

31.9 审计日志

审计日志可以记录:

启用审计需要配置安全订阅和静态设置,具体配置随版本变化。原则:

即使不启用完整审计,也应至少保留:

  1. 管理操作工单;
  2. 索引删除审批;
  3. 角色变更记录;
  4. 快照仓库修改记录;
  5. 生产 API key 发放记录。

31.10 网络与访问控制

建议网络分层:

Internet
  -> WAF / VPN / Bastion
     -> Application
        -> Elasticsearch private subnet
           -> Data nodes

要求:

31.11 数据分级与脱敏

级别 示例 策略
公开 商品标题 常规权限
内部 服务日志 团队权限
敏感 用户 ID、IP 字段授权、脱敏
高敏 手机号、身份证、token 默认不落 ES

在 Ingest Pipeline 中兜底脱敏:

PUT _ingest/pipeline/sensitive-redact
{
  "processors": [
    {
      "script": {
        "lang": "painless",
        "source": """
          if (ctx.message != null) {
            ctx.message = ctx.message
              .replaceAll(/\\b\\d{17}[0-9Xx]\\b/, '<id_card>')
              .replaceAll(/\\b1[3-9]\\d{9}\\b/, '<mobile>');
          }
        """
      }
    }
  ]
}

脱敏应在应用输出和采集端优先完成,ES Pipeline 只作为最后防线。

31.12 安全基线检查

本章小结

安全体系的核心是最小权限和可追溯。网络边界决定能不能进来,TLS 决定传输是否安全,认证和角色决定能做什么,DLS/FLS 决定能看哪些数据,审计决定事后能不能追责。上线前先做安全基线检查,比事故后补救便宜得多。

思考题

  1. 应用账号为什么不能使用超级用户?
  2. DLS 和业务代码里的租户过滤有什么本质区别?
  3. API Key 应如何设计过期和轮换?
  4. 哪些日志字段不应进入 Elasticsearch?
  5. 删除索引这类高危操作应如何治理?