ES 安全三件套

22 May 2026 – wusfe · 3 min read

ES 安全三件套

Elasticsearch 在 6.8/7.1 版本之前,安全功能是 X-Pack 付费版专属。但从 6.8 和 7.1 开始,基础安全功能免费开放,包括认证(Authentication)、授权(Authorization)和 TLS 加密。本文将逐一拆解这"安全三件套"的配置与实战。


1. 认证(Authentication)

ES 支持多种认证后端,按使用频率排序:

Realm 类型 适用场景 复杂度
Native Realm 内置用户,小规模部署
File Realm 静态用户列表,无网络依赖
LDAP 企业 AD 域
SAML 单点登录(SSO)
OIDC 对接 Okta/Keycloak 等
PKI 证书认证

Native Realm 配置

# elasticsearch.yml
xpack.security.enabled: true
xpack.security.authc.realms.native.native1:
  order: 0

设置密码

# 交互式设置内置用户密码
bin/elasticsearch-setup-passwords interactive

# 或者分别设置
bin/elasticsearch-reset-password -u elastic

创建自定义用户

# 通过 API 创建用户
POST /_security/user/logstash_writer
{
  "password": "changeme123",
  "roles": ["logstash_writer_role"],
  "full_name": "Logstash Writer"
}

LDAP 配置示例

xpack.security.authc.realms.ldap.ldap1:
  order: 0
  url: "ldaps://ldap.example.com:636"
  bind_dn: "cn=admin,dc=example,dc=com"
  bind_password: "admin_password"
  user_search:
    base_dn: "ou=users,dc=example,dc=com"
    filter: "(uid={0})"
  group_search:
    base_dn: "ou=groups,dc=example,dc=com"
  unmapped_groups_as_roles: false

2. 授权(Authorization):RBAC 模型

ES 的权限模型是标准的 RBAC:Role → Privilege → Resource

权限层级

层级 资源范围 示例
Cluster 集群级别 monitormanageall
Index 索引级别 readwritecreate_indexdelete
Document 文档级别 配合 query 做字段级过滤
Field 字段级别 {"field_security": {"grant": ["title", "price"]}}

实战:最小权限原则

场景 1:给 Logstash 只分配写入权限

POST /_security/role/logstash_writer_role
{
  "cluster": ["monitor", "manage_ilm"],
  "indices": [
    {
      "names": ["logs-*", "metrics-*"],
      "privileges": ["create_index", "index", "auto_configure"],
      "field_security": {
        "grant": ["*"]
      }
    }
  ]
}

注意:Logstash 不需要 read 权限,也不需要 delete 权限。权限越少越好。

场景 2:给 Kibana 只分配读取权限

POST /_security/role/kibana_readonly_role
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["logs-*", "product_*", "order_*"],
      "privileges": ["read", "view_index_metadata"],
      "field_security": {
        "grant": ["message", "timestamp", "level", "service"]
      },
      "query": {
        "bool": {
          "must_not": [
            { "term": { "sensitive": true } }
          ]
        }
      }
    }
  ]
}

这个例子展示了两个高级特性:

  • 字段级安全(Field Security):Kibana 用户只能看到 messagetimestamplevelservice 四个字段。
  • 文档级安全(Document Security):通过 query 过滤掉 sensitive: true 的文档。

场景 3:给开发者分配只读 + Dev Tools 权限

POST /_security/role/dev_role
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["dev-*"],
      "privileges": ["all"],
      "allow_restricted_indices": false
    }
  ]
}

权限速查表

操作 需要的索引权限
GET /index/_search read
POST /index/_doc create_docindex
PUT /index create_index
DELETE /index delete_index
GET /_cat/indices monitor(注意是 cluster 级别)

3. TLS 加密

TLS 分两层:

层级 配置项 用途
Transport TLS xpack.security.transport.ssl 节点间通信加密
HTTP TLS xpack.security.http.ssl 客户端到 ES 的通信加密

用 elasticsearch-certutil 生成证书

# Step 1: 生成 CA 证书
bin/elasticsearch-certutil ca
# 输出 elastic-stack-ca.p12

# Step 2: 用 CA 签发节点证书
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
# 输出 elastic-certificates.p12

# Step 3: 把 elastic-certificates.p12 复制到每个节点的 config 目录

配置 TLS

# elasticsearch.yml(每个节点都需配置)
xpack.security.enabled: true

# Transport TLS(节点间通信)
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

# HTTP TLS(客户端通信)
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: elastic-certificates.p12
xpack.security.http.ssl.truststore.path: elastic-certificates.p12

踩坑提醒:如果 verification_mode 设为 full(严格验证),证书中的 SAN(Subject Alternative Name)必须包含节点的主机名或 IP,否则节点无法通信。调试阶段可以先设 certificate,生产环境务必改为 full

客户端连接 HTTPS

# curl 连接 HTTPS 需要 -k(测试用)或 --cacert(生产用)
curl --cacert ca.crt -u elastic:password "https://localhost:9200/_cat/health?v"

# 也可以把用户名密码放到 Authorization header
curl --cacert ca.crt -H "Authorization: Basic $(echo -n 'elastic:password' | base64)" \
     "https://localhost:9200/_cat/indices?v"

4. API Key 替代密码认证

API Key 比密码更安全:可以限时、限权、单独吊销。

创建 API Key

POST /_security/api_key
{
  "name": "logstash_api_key",
  "role_descriptors": {
    "logstash_writer": {
      "cluster": ["monitor", "manage_ilm"],
      "indices": [
        {
          "names": ["logs-*"],
          "privileges": ["create_index", "index"]
        }
      ]
    }
  },
  "expiration": "30d"
}

返回:

{
  "id": "VuaCfGcBC9d6NxQfLhJy",
  "name": "logstash_api_key",
  "api_key": "kL4aPfTQShu1j3dGz8Kx8w",
  "encoded": "VuaCfGcBC9d6NxQfLhJy:azNkY2Rm..."  // Base64 编码后用于 Authorization header
}

使用 API Key

# Logstash 配置中使用 api_key
output {
  elasticsearch {
    hosts => ["https://es-node:9200"]
    api_key => "VuaCfGcBC9d6NxQfLhJy:kL4aPfTQShu1j3dGz8Kx8w"
    ssl => true
    cacert => "/etc/logstash/ca.crt"
  }
}

吊销 API Key

DELETE /_security/api_key
{
  "name": "logstash_api_key"
}

5. 安全配置检查清单

检查项 要求 命令
密码是否修改 默认密码 changeme 必须改 elasticsearch-setup-passwords
HTTPS 是否开启 生产必须开启 检查 elasticsearch.yml
transport TLS 是否开启 节点间通信必须加密 检查 elasticsearch.yml
是否禁用通配符 delete 生产禁 DELETE /* PUT /_cluster/settings {"persistent":{"action.destructive_requires_name":true}}
是否用最小权限 每个账户只给必要权限 审查 _security/role
API Key 是否设过期 长期 Key 需设 expiration 审查 _security/api_key

总结

ES 安全三件套的落地顺序建议是:

  1. 先开 TLS——加密所有通信,防止中间人攻击
  2. 再设认证——至少用 native realm,修改所有默认密码
  3. 最后细化授权——按最小权限原则创建角色、分配用户

安全不是"加完就忘"的一次性工作。定期审查用户权限、吊销不再使用的 API Key、审计慢查询中的敏感字段访问——这些才是安全运维的日常。