mcpField
E
elasticsearch-security-troubleshooting

elasticsearch-security-troubleshooting

github.com/elastic安全6022.9k 次安装今天更新
代码仓库

关于 elasticsearch-security-troubleshooting

elasticsearch-security-troubleshooting 是用于排查和解决 Elasticsearch 安全问题的技能,供集群管理员和运维人员按症状执行诊断。它覆盖认证、权限、TLS、API 密钥、角色映射、Kibana 登录及许可证锁定,并采用收集、诊断、解决的流程。

主要功能

  1. 01诊断 401 与 403 错误
  2. 02排查 TLS 与证书问题
  3. 03检查 API 密钥状态和权限
  4. 04分析角色映射问题
  5. 05处理 Kibana 登录和许可证锁定

适用场景

  1. 01定位凭据导致的认证失败
  2. 02查明用户缺少索引访问权限的原因
  3. 03排查证书或 TLS 握手错误
  4. 04恢复许可证到期后的访问

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elastic/agent-skills --skill elasticsearch-security-troubleshooting

安装后在 Claude Code 中输入/elasticsearch-security-troubleshooting确认已加载。

附带文件references/api-reference.md

详细介绍

Elasticsearch 安全故障排查

诊断并解决常见的 Elasticsearch 安全问题。本技能提供结构化的分诊工作流,用于处理身份验证失败、授权错误、TLS 问题、API 密钥问题、角色映射不匹配、Kibana 登录失败以及许可证过期导致的锁定。

有关身份验证方法和 API 密钥管理,请参阅 elasticsearch-authn 技能。有关角色、用户和角色映射,请参阅 elasticsearch-authz 技能。有关许可证管理,请参阅 elasticsearch-license 技能。

有关诊断 API 端点,请参阅 references/api-reference.md。

**部署说明:**自管理、ECH 和 Serverless 部署中的诊断 API 可用性各不相同。详情请参阅 部署兼容性。

待完成事项

  • 诊断 HTTP 401 身份验证失败
  • 诊断 HTTP 403 权限被拒绝错误
  • 排查 TLS/SSL 握手或证书错误
  • 调查过期或无效的 API 密钥
  • 调试未授予预期角色的角色映射
  • 修复 Kibana 登录失败、重定向循环或 CORS 错误
  • 从许可证过期导致的锁定中恢复
  • 确定用户为何无法访问特定索引

前提条件

项目描述
Elasticsearch URL集群端点(例如 https://localhost:9200 或 Cloud 部署 URL)
身份验证任意有效凭据,即使权限最低,也能访问集群
集群权限只读诊断需要 monitor;修复需要 manage_security

请向用户询问任何缺失的值。如果用户完全无法通过身份验证,请从 TLS 和证书错误或许可证过期恢复开始。

诊断工作流

根据症状跳转到相应部分:

症状部分
HTTP 401,authentication_exception身份验证失败
HTTP 403,security_exception,访问被拒绝授权失败
SSL/TLS 握手错误,证书被拒绝TLS 和证书错误
API 密钥被拒绝、已过期或不起作用API 密钥问题
角色映射未授予预期角色角色映射问题
Kibana 登录故障、重定向循环、CORS 错误Kibana 身份验证问题
所有用户均被锁定、付费功能已禁用许可证过期恢复

每个部分都遵循收集 - 诊断 - 解决模式。

诊断工具集

在任何安全问题调查开始时使用这些 API:

curl <auth_flags> "${ELASTICSEARCH_URL}/_security/_authenticate"

确认身份、领域和角色。如果此请求因 401 而失败,问题出在身份验证。

curl <auth_flags> "${ELASTICSEARCH_URL}/_xpack"

确认安全功能是否已启用(features.security.enabled)。如果安全功能已禁用,所有安全 API 都会返回错误。

curl -X POST "${ELASTICSEARCH_URL}/_security/user/_has_privileges" \
  <auth_flags> \
  -H "Content-Type: application/json" \
  -d '{
    "index": [
      { "names": ["'"${INDEX_PATTERN}"'"], "privileges": ["read"] }
    ]
  }'

测试经过身份验证的用户是否拥有特定权限,无需 manage_security。

curl <auth_flags> "${ELASTICSEARCH_URL}/_license"

检查许可证类型和状态。付费许可证过期后,付费领域和功能将被禁用。

身份验证失败(401)

401 响应表示 Elasticsearch 无法验证调用方的身份。

收集信息
curl -v <auth_flags> "${ELASTICSEARCH_URL}/_security/_authenticate" 2>&1

-v 标志会显示标头和响应正文。请查找:

  • WWW-Authenticate 标头——指明集群接受哪些身份验证方案。
  • 响应正文中的 authentication_exception——reason 字段会说明失败原因。
诊断
症状可能原因
unable to authenticate user用户名或密码错误
unable to authenticate with provided credentials凭据与链中的任何 realm 都不匹配
user is not enabled原生用户账户已禁用
token is expiredAPI 密钥或 bearer token 已过期
没有 WWW-Authenticate 标头安全功能可能已禁用;检查 GET /_xpack

如果用户通过外部 realm(LDAP、AD、SAML、OIDC)进行身份验证,realm 链的顺序很重要。Elasticsearch 会按配置顺序尝试各个 realm,并在首次匹配时停止。如果优先级较高的 realm 在到达预期 realm 之前拒绝了凭据,身份验证就会失败。

解决
原因操作
凭据错误验证用户名/密码或 API 密钥值。参见 elasticsearch-authn。
用户已禁用PUT /_security/user/{name}/_enable。参见 elasticsearch-authz。
API 密钥已过期创建新的 API 密钥。参见 API 密钥问题。
Realm 链顺序检查 elasticsearch.yml 中的 realm 顺序(仅适用于自行管理的部署)。
安全功能已禁用在 elasticsearch.yml 中启用 xpack.security.enabled: true 并重启。
付费 realm 在许可证过期后许可证已过期——参见许可证过期恢复。

授权失败(403)

403 响应表示用户已通过身份验证,但缺少所需的权限。

收集信息

测试操作所需的具体权限:

curl -X POST "${ELASTICSEARCH_URL}/_security/user/_has_privileges" \
  <auth_flags> \
  -H "Content-Type: application/json" \
  -d '{
    "index": [
      { "names": ["logs-*"], "privileges": ["read", "view_index_metadata"] }
    ],
    "cluster": ["monitor"]
  }'

响应包含一个 has_all_requested 布尔值以及按资源划分的详细信息。

另请检查用户的有效角色:

curl <auth_flags> "${ELASTICSEARCH_URL}/_security/_authenticate"

检查 roles 数组和 authentication_realm,确认该用户是你预期的用户。

诊断
症状可能原因
对索引而言,has_all_requested: false角色缺少所需的索引权限
对集群而言,has_all_requested: false角色缺少所需的集群权限
用户拥有的角色少于预期上次更新时角色数组被替换(而非合并)
API 密钥对之前允许的操作返回 403API 密钥权限是一个快照——角色变更不会应用到已有密钥
操作创建后不会应用到已有密钥
解决
原因处理方法
缺少索引权限将该权限添加到角色中,或创建新角色。参见 elasticsearch-authz。
缺少集群权限添加集群权限。参见 elasticsearch-authz。
更新时角色被替换先获取当前角色,再使用完整数组更新。参见 elasticsearch-authz。
API 密钥权限过期使用更新后的 role_descriptors 创建新的 API 密钥。参见 elasticsearch-authn。

TLS 和证书错误

TLS 错误会导致客户端完全无法建立连接。

收集信息
curl -v --cacert "${CA_CERT}" "https://${ELASTICSEARCH_HOST}:9200/" 2>&1 | head -30

请留意:

  • SSL certificate problem: unable to get local issuer certificate — CA 不受信任。
  • SSL certificate problem: certificate has expired — 证书已过有效期。
  • SSL: no alternative certificate subject name matches target host name — 主机名不匹配。

如需深入检查(仅限自管理):

openssl s_client -connect "${ELASTICSEARCH_HOST}:9200" -showcerts </dev/null 2>&1

这会显示完整的证书链、到期日期和主题备用名称。

诊断
错误消息可能原因
unable to get local issuer certificate缺少 CA 证书或 CA 证书不正确
certificate has expired服务器证书或 CA 证书已过期
no alternative certificate subject name matches证书 SAN 中不包含该主机名
self-signed certificate信任存储中没有自签名证书
SSLHandshakeException(Java 客户端)信任存储缺少 CA 证书或密码错误
解决
原因处理方法
CA 证书不正确使用 --cacert 指定正确的 CA,或将其添加到系统信任存储中。
证书已过期使用 elasticsearch-certutil 重新生成证书(自管理)。
主机名不匹配使用正确的 SAN 条目重新生成证书。
自签名证书将 CA 证书分发给所有客户端,或使用公开受信任的 CA。
临时解决方法使用 curl -k / --insecure 跳过验证。不适用于生产环境。

在 ECH 上,TLS 由 Elastic 管理 — 证书错误通常表示客户端未使用正确的 Cloud 端点 URL。在 Serverless 上,TLS 完全由系统管理且对用户透明。

API 密钥问题

收集信息

获取密钥的元数据:

curl "${ELASTICSEARCH_URL}/_security/api_key?name=${KEY_NAME}" <auth_flags>

检查响应中的 expiration、invalidated 和 role_descriptors。

诊断
症状可能原因
使用密钥时返回 401密钥已过期或已失效
对本应允许的操作返回 403创建密钥时使用的 role_descriptors 权限不足
派生密钥没有访问权限API 密钥创建了另一个 API 密钥 — 派生密钥没有权限
密钥对部分索引有效,但对其他索引无效role_descriptors 的作用范围太窄
解决
原因操作
密钥已过期创建具有适当 expiration 的新密钥。请参阅 elasticsearch-authn。
密钥已失效创建新密钥。失效的密钥无法恢复。
范围错误创建具有正确 role_descriptors 的新密钥。请参阅 elasticsearch-authn。
派生密钥问题改用用户凭据调用 POST /_security/api_key/grant。请参阅 elasticsearch-authn。

角色映射问题

角色映射会为来自外部域的用户授予角色。如果映射未生效,用户虽然能够通过身份验证,却不会获得任何角色。

收集信息
curl <auth_flags> "${ELASTICSEARCH_URL}/_security/_authenticate"

记下 username、authentication_realm.name 和 roles 数组。

curl <auth_flags> "${ELASTICSEARCH_URL}/_security/role_mapping"

列出所有映射,并检查其 rules 和 enabled 字段。

诊断
症状可能原因
用户的 roles 数组为空没有映射与该用户的属性匹配
用户获得了错误的角色更早匹配了其他映射,或规则范围过宽
映射存在,但未生效enabled 为 false
Mustache 模板生成了错误的角色名称模板语法错误或属性值与预期不符

将用户的 authentication_realm.name 和 groups(来自 _authenticate)与每个映射的 rules 进行比较, 找出不匹配之处。

解决
原因操作
没有匹配的规则更新映射规则,使其匹配用户的域和属性。
映射已禁用在映射上设置 "enabled": true。
模板错误使用已知属性值测试 Mustache 模板。请参阅 elasticsearch-authz。
规则范围过宽添加 all / except 条件以缩小匹配范围。请参阅 elasticsearch-authz。

Kibana 身份验证问题

缺少 kbn-xsrf 标头

所有会修改数据的 Kibana API 请求都需要 kbn-xsrf 标头:

curl -X PUT "${KIBANA_URL}/api/security/role/my-role" \
  <auth_flags> \
  -H "kbn-xsrf: true" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

如果缺少该标头,Kibana 会返回 400 Bad Request,并显示 "Request must contain a kbn-xsrf header"。

SAML/OIDC 重定向循环

常见原因:

  • elasticsearch.yml 中的 xpack.security.authc.realms.saml.*.sp.acs 或 idp.metadata.path 配置不正确。
  • IdP 与 Elasticsearch 节点之间存在时钟偏差(SAML 断言有有效时间窗口)。
  • Kibana 的 server.publicBaseUrl 与 SAML ACS URL 不匹配。

验证 SAML 域配置:

curl <auth_flags> "${ELASTICSEARCH_URL}/_security/_authenticate"

如果这会通过非 SAML 域返回有效用户,则说明请求未到达 SAML 域。请检查域链顺序。

Kibana 无法连接 Elasticsearch

Kibana 日志显示 Unable to retrieve version information from Elasticsearch nodes。请验证 kibana.yml 中的 elasticsearch.hosts 设置指向可访问的端点,并确认凭据(elasticsearch.username / elasticsearch.password 或 elasticsearch.serviceAccountToken)有效。

许可证过期恢复

付费许可证过期后,集群会进入安全关闭状态:付费域(SAML、LDAP、AD、PKI)将停止工作,通过这些域进行身份验证的用户会被锁定。原生域和文件域仍可正常工作。

快速排查
curl <auth_flags> "${ELASTICSEARCH_URL}/_license"

如果 license.status 为 "expired",请继续进行恢复。

恢复步骤

请按照 elasticsearch-license 技能中的详细恢复工作流操作。关键的第一步取决于 部署类型:

部署方式第一步
自行管理使用基于文件的用户(elasticsearch-users CLI)或原生用户登录。
ECH联系 Elastic 支持,或通过 Cloud 控制台续订。
Serverless不适用——许可完全由 Elastic 管理。

示例

用户查询日志时收到 403

症状:“我搜索 logs-* 时收到 403。”

  1. 验证身份:
curl -u "joe:${PASSWORD}" "${ELASTICSEARCH_URL}/_security/_authenticate"

响应显示 "roles": ["viewer"]。

  1. 测试权限:
curl -X POST "${ELASTICSEARCH_URL}/_security/user/_has_privileges" \
  -u "joe:${PASSWORD}" \
  -H "Content-Type: application/json" \
  -d '{"index": [{"names": ["logs-*"], "privileges": ["read"]}]}'

响应为:"has_all_requested": false——viewer 角色不包含对 logs-* 的 read 权限。

  1. 修复:创建 logs-reader 角色并将其分配给 Joe。请参阅 elasticsearch-authz。
API 密钥停止工作

症状:“我的 API 密钥从昨天开始返回 401。”

  1. 检查密钥:
curl -u "admin:${PASSWORD}" "${ELASTICSEARCH_URL}/_security/api_key?name=my-key"

响应显示 "expiration": 1709251200000——密钥已过期。

  1. 修复:创建具有合适 expiration 的新 API 密钥。请参阅 elasticsearch-authn。
SAML 登录重定向到错误页面

症状:“点击 Kibana 中的 SSO 按钮后,页面重定向到了错误页面。”

  1. 使用非 SAML 方法进行身份验证,检查 SAML realm 是否可访问:
curl -u "elastic:${PASSWORD}" "${ELASTICSEARCH_URL}/_security/_authenticate"
  1. 验证 Elasticsearch 节点是否可以访问 IdP 元数据 URL(自行管理):
curl -s "${IDP_METADATA_URL}" | head -5
  1. 检查时钟偏差——SAML 断言对时间很敏感。确保所有节点都配置了 NTP。
  2. 验证 kibana.yml 中的 server.publicBaseUrl 是否与 IdP 中配置的 SAML ACS URL 一致。
许可证过期后用户无法登录

症状:“没有人能登录 Kibana。我们使用 SAML。”

  1. 检查许可证:
curl -u "admin:${PASSWORD}" "${ELASTICSEARCH_URL}/_license"

响应显示 "status": "expired"、"type": "platinum"。

  1. 付费许可证过期后,SAML realm 会被禁用。请按照 elasticsearch-license 中的恢复步骤操作: 使用基于文件的用户或原生用户登录,然后上传续订后的许可证,或恢复为 basic。

指南

始终从 _authenticate 开始

将 GET /_security/_authenticate 作为第一步诊断操作。一次调用即可显示用户的身份、realm、角色和 身份验证类型。仅凭此响应通常就能发现大多数问题。

尽早检查许可证

在调查 realm 或权限问题之前,使用 GET /_license 验证许可证是否有效。付费许可证过期会禁用 realm 和功能,导致出现类似配置错误的症状。

手动检查前先使用 _has_privileges

不要阅读角色定义并手动推算有效访问权限,而应使用 POST /_security/user/_has_privileges 直接测试特定权限。这样更快,也会考虑角色组合、DLS 和 FLS。

避免使用超级用户凭据

切勿使用内置的 elastic 超级用户进行日常故障排查。创建专用管理员用户或具有 manage_security 权限的 API 密钥。仅在初始设置和紧急恢复时使用 elastic 用户。

不要在生产环境中绕过 TLS

使用 curl -k 或 --insecure 会跳过证书验证,并掩盖真实的 TLS 问题。仅将其用于初步 诊断,然后修复根本的证书问题。

部署兼容性

不同部署类型所提供的诊断工具和 API 各不相同。

工具 / API自行管理ECH无服务器
_security/_authenticate是是是
_security/user/_has_privileges是是是
_xpack是是有限
_license是是(读取)不可用
_security/api_key (GET)是是是
_security/role_mapping是是是
elasticsearch-users CLI是不可用不可用
节点上的 openssl s_client是不可用不可用
Elasticsearch 日志是通过 Cloud UI通过 Cloud UI

ECH 说明:

  • 无法访问节点,因此无法使用 elasticsearch-users CLI,也无法直接检查日志或证书。
  • TLS 由 Elastic 管理 — 证书错误通常表示端点 URL 不正确。
  • 使用 Cloud 控制台检查日志和部署配置。

无服务器说明:

  • 不提供许可 API,因此不会发生与许可证相关的锁定。
  • 不存在原生用户 — 身份验证问题在组织级别处理。
  • TLS 完全由系统管理,且对用户透明。

评论

支持 Markdown