2.8 Elasticsearch-安全加固:TLS 1.3 传输加密、RBAC、API Key、IP 白名单

在这里插入图片描述
2.8 Elasticsearch-安全加固:TLS 1.3 传输加密、RBAC、API Key、IP 白名单
——把“裸奔”的集群塞进三层防弹衣


  1. 背景:为什么 9200 端口不能再裸奔
    上一篇我们把 8.x 集群从 7.x 滚动升级完毕,xpack 默认已开启,但只是“有”安全功能,远未到“够用”。
    渗透测试报告里三条红线:
  2. 传输层抓包可直接拿到索引明文;
  3. 使用超级管理员 elastic 账号每天跑批;
  4. 9200 对全网 0.0.0.0/0 开放。
    本章给出一份可直接落地的“三层防弹衣”方案,全部基于 8.x 原生能力,零商业授权,30 min 内可全量灰度。

  1. 防弹衣第 1 层:TLS 1.3 传输加密
    目标:node-to-node、node-to-client 全链路强制 TLS1.3,禁用一切 RSA 密钥交换,把握手时间压到 1-RTT,CPU 消耗降 18%。

1.1 证书规划(ECDSA 双证书链)
├── root-ca.crt(secp384r1,20 年)
├── node-ca.crt(secp256r1,5 年,只做中间签发)
└── 每节点三张实体证书:
├── transport.crt (OID:1.3.6.1.5.5.7.3.1 + 1.3.6.1.5.5.7.3.2)
├── http.crt (SAN 含节点 IP、DNS、k8s SVC)
└── admin.crt (供运维 CLI 用,O=admin,OU=ops)

1.2 签发脚本(cfssl 一次性批量)
cat <<EOF | cfssl gencert -ca=node-ca.crt -ca-key=node-ca-key.pem -config=tls-config.json - | cfssljson -bare es-node-1
{
“CN”: “es-node-1.transport”,
“hosts”: [“10.0.0.21”,“es-node-1”,“localhost”,“127.0.0.1”],
“key”: { “algo”: “ecdsa”, “size”: 256 }
}
EOF

1.3 elasticsearch.yml 关键段
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.client_authentication: required
xpack.security.transport.ssl.supported_protocols: [TLSv1.3]
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.supported_protocols: [TLSv1.3]
xpack.security.http.ssl.cipher_suites: [
“TLS_AES_256_GCM_SHA384”,
“TLS_CHACHA20_POLY1305_SHA256”
]

1.4 灰度顺序

  1. 先滚动重启 data 节点,再重启 master;
  2. 观察 GET _nodes/stats/transport 确认未回落 TLSv1.2;
  3. 用 openssl s_client -tls1_3 测试 9200,确认 ServerTempKey 为 X25519。

  1. 防弹衣第 2 层:RBAC 最小权限模型
    目标:让“每天跑批的脚本”拿不到 delete_index 权限,让“Kibana 只读用户”看不到 .security 索引。

2.1 角色设计(YAML 即 cat 角色文件)

1. 应用写角色:只允许写指定别名

app_writer:
cluster: [ ‘monitor’ ]
indices:
- names: [ ‘app-logs-*’ ]
privileges: [ ‘create_index’,‘write’,‘create’ ]
field_security:
grant: [ ‘@timestamp’,‘msg’,‘level’ ]

2. 开发只读角色

dev_readonly:
cluster: [ ‘monitor/main’ ]
indices:
- names: [ ‘app-logs-','metrics-’ ]
privileges: [ ‘read’,‘view_index_metadata’ ]
query: ‘{“term”:{“team”:{“value”:“dev”}}}’

3. 备份角色:只能 snapshot

backup_role:
cluster: [ ‘create_snapshot’,‘manage’ ]
indices:
- names: [ ‘*’ ]
privileges: [ ‘read’,‘view_index_metadata’ ]

2.2 用户组映射(LDAP/AD 免维护)
xpack.security.authc.realms.active_directory.ad1:
domain_name: corp.example.com
user_search.filter: “(sAMAccountName={0})”
group_search.base_dn: “OU=Elastic,DC=corp,DC=example,DC=com”
files.role_mapping: /etc/elasticsearch/role_mapping.yml

role_mapping.yml 片段
dev_readonly:

  • “CN=elastic-dev,OU=Groups,DC=corp,DC=example,DC=com”
    app_writer:
  • “CN=elastic-app,OU=Groups,DC=corp,DC=example,DC=com”

2.3 审计日志
xpack.security.audit.enabled: true
xpack.security.audit.outputs: [ index, logfile ]
xpack.security.audit.index.events.include: [ authentication_success, authentication_failed, access_granted, access_denied ]


  1. 防弹衣第 3 层:API Key + IP 白名单
    目标:让“跑批脚本”不再存 elastic 明文密码,且即使 key 泄露,也只能在指定网段使用。

3.1 创建最小权限 API Key
POST /_security/api_key
{
“name”: “logstash-7-17-write”,
“role_descriptors”: {
“logstash_writer”: {
“cluster”: [“monitor”,“manage_index_templates”],
“index”: [
{
“names”: [“logstash-*”],
“privileges”: [“create”,“write”,“create_index”]
}
]
}
},
“expiration”: “90d”,
“metadata”: { “owner”: “logstash-team”, “env”: “prod” }
}

返回:
{
“id”: “QcYtv40Bop7cWX0lr5dG”,
“api_key”: “x3bEzZfGQFeSpG7F1E8xdw”,
“encoded”: “UWNZdHY0MEJvcDdjVVgwbHI1ZEc6eDNiRXpaZkdRRmVTcEc3RjFFOHhkdz09”
}

3.2 IP 白名单(8.x 原生支持)
在 elasticsearch.yml 追加
xpack.security.http.filter.enabled: true
xpack.security.http.filter.allow: [ “10.0.0.0/8”, “192.168.10.0/24” ]
xpack.security.http.filter.deny: [ “0.0.0.0/0” ]

说明:

  • 该过滤在 HTTP 层第一环生效,比 SG 插件早,性能损耗 <1%;
  • 支持 x-forwarded-for,只需加 xpack.security.http.filter.allow_forwarded: true

3.3 轮换与吊销

30 天滚动轮换脚本

GET /_security/api_key?name=logstash-7-17-write
POST /_security/api_key/QcYtv40Bop7cWX0lr5dG/_invalidate

新 key 推入 Vault,老 key 在 5 min 宽限期后自动失效。


  1. 灰度 checklist(生产直接复制打钩)

[ ] 1. 所有节点 openssl s_client -connect node:9300 -tls1_3 握手成功
[ ] 2. GET _ssl/certificates 返回无 RSA 证书
[ ] 3. 用普通用户跑 DELETE app-logs-2023 返回 403
[ ] 4. 用 API Key 在 10.0.0.0/8 外访问 9200 返回 403
[ ] 5. Kibana → Stack Management → Security → Audit 出现“access_denied”事件
[ ] 6. 集群整体 QPS 下降 ❤️%,GC 无异常


  1. 常见坑 5 连击

  2. 滚动重启后集群 RED:transport 证书 SAN 漏掉 master 节点 DNS,导致选主失败。

  3. Kibana 无法登录:role_mapping.yml 缩进用了 tab,AD 组名大小写敏感。

  4. logstash 报 401:API Key 放进了 keystore,但 pipeline 里把 id 拼成了 “id:api_key” 格式,正确是 “user:{user}:user:{pass}” 即 “id:api_key”。

  5. IP 白名单把自己 ban 了:改完未留跳板机,需通过 transport 9300 端口执行 curl -XPOST localhost:9200/_cluster/settings 关闭 filter。

  6. 升级后 cipher 套件不兼容 JDK8:8.x 默认只留 TLS1.3,需升级 JDK≥11;旧客户端可额外开启 TLSv1.2 过渡,但须把 cipher 白名单收紧到 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 等 3 套。


  1. 小结

TLS1.3 解决“路上裸奔”,RBAC 解决“权限裸奔”,API Key+IP 白名单解决“凭证裸奔”。
三步全部原生集成,无需重启集群即可回滚;配合审计与 Vault 轮换,便可把 Elasticsearch 塞进三层防弹衣,让安全团队从“反复打补丁”变成“一次性验收”。
更多技术文章见公众号: 大城市小农民

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔丹搞IT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值