49 · 安全:TLS、API Key、RBAC
阶段:第五阶段 / 运维进阶
ES:传输加密、身份认证、最小权限授权 | PostgreSQL:SSL、用户与角色、权限控制
1. 概念
Elasticsearch 生产安全通常是三层:
- TLS(传输加密):保护传输中数据,避免明文被窃听或篡改。
- Authentication(身份认证):你是谁(Basic、API Key、Token 等)。
- Authorization(权限授权 / RBAC):你能做什么(读哪些索引、写哪些索引、是否能管理集群)。
核心原则:先认证,再授权,默认拒绝,最小权限。
2. PostgreSQL 对照
| Elasticsearch | PostgreSQL |
|---|---|
| HTTP/Transport TLS | ssl=on+ 证书链 |
| API Key / Basic / Token | 用户名密码 + 连接参数 |
| Role + Privileges | Role + GRANT |
| DLS/FLS(文档/字段级权限) | 行级安全(RLS)/列权限 |
| 审计日志 | log_statement/ 审计扩展 |
3. 关键接口与命令(Dev Tools / API)
3.1 查看安全基础状态
GET /_security/_authenticate GET /_security/role GET /_security/user_authenticate可快速确认当前凭据身份与角色。- 线上排障时,先确认“我是谁”,再看“我能做什么”。
3.2 创建最小权限角色(示例)
PUT /_security/role/salesdata_reader { "cluster": ["monitor"], "indices": [ { "names": ["salesdata-*"], "privileges": ["read", "view_index_metadata"] } ] }3.3 创建绑定角色的用户(示例)
POST /_security/user/report_user { "password": "ReplaceWithStrongPassword!", "roles": ["salesdata_reader"], "full_name": "Report Readonly User" }3.4 创建 API Key(推荐给服务到服务调用)
POST /_security/api_key { "name": "integration-prod-writer", "role_descriptors": { "writer_scope": { "cluster": ["monitor"], "index": [ { "names": ["salesdata-*"], "privileges": ["create_index", "write", "create", "index"] } ] } } }返回会包含:
idapi_key(只返回一次,务必安全保存)encoded(可直接放Authorization: ApiKey <encoded>)
3.5 失效 API Key(泄露时立即处理)
DELETE /_security/api_key { "ids": ["<api_key_id>"] }4. TLS 实战要点
4.1 两条链路都要加密
- 节点间通信(transport):防止集群内部窃听或伪造节点。
- 客户端到 ES(http):防止应用调用链路明文泄露。
4.2 证书与主机名校验
- 证书
SAN必须覆盖实际访问域名或 IP。 - 客户端不要关闭主机名校验(禁用校验仅限本地临时排错)。
- 证书需有轮换策略,避免“到期即故障”。
4.3 常见错误定位
PKIX path building failed:证书链不完整或客户端不信任 CA。hostname verification failed:访问地址与证书 SAN 不匹配。received plaintext http traffic on an https channel:客户端用了 HTTP 访问 HTTPS 端口。
5. Spring Boot(Elasticsearch Java Client)调用示例
下面示例体现两件事:
1)使用 HTTPS;2)使用 API Key 认证(优先于硬编码用户名密码)。
importco.elastic.clients.elasticsearch.ElasticsearchClient;importco.elastic.clients.json.jackson.JacksonJsonpMapper;importco.elastic.clients.transport.ElasticsearchTransport;importco.elastic.clients.transport.rest_client.RestClientTransport;importorg.apache.http.Header;importorg.apache.http.HttpHost;importorg.apache.http.message.BasicHeader;importorg.elasticsearch.client.RestClient;publicclassEsClientFactory{publicElasticsearchClientcreate(Stringhost,intport,StringencodedApiKey){Header[]defaultHeaders=newHeader[]{newBasicHeader("Authorization","ApiKey "+encodedApiKey)};RestClientlowLevelClient=RestClient.builder(newHttpHost(host,port,"https")).setDefaultHeaders(defaultHeaders).build();ElasticsearchTransporttransport=newRestClientTransport(lowLevelClient,newJacksonJsonpMapper());returnnewElasticsearchClient(transport);}}建议:
encodedApiKey放到安全配置中心或密钥管理服务,不进 Git。- 按环境拆分 Key(dev/test/prod),并限制索引范围。
6. RBAC 设计建议(适合 SalesData 场景)
- 按职责拆角色:
reader、writer、ops,不要一个超管角色到处复用。 - 按索引前缀授权:例如
salesdata-*、salesdata-report-*分开。 - 限制集群级权限:普通业务账号通常只要
monitor,不给manage_security。 - 临时权限要过期:排障提权后必须回收。
- 审计关键操作:创建/删除 API Key、改角色、改用户要可追踪。
7. 坑与最佳实践
- 不要共享 API Key:每个服务和环境独立 Key,泄露影响可控。
- 不要长久不轮换:建立 Key 轮换与失效机制(例如 30/90 天)。
- 不要把密钥写进日志:脱敏
Authorization头与配置输出。 - 不要过度授权:
all权限最危险,优先精确到 index privilege。 - 不要忽略证书到期:把证书有效期纳入监控告警。
- 先验身份再验权限:排障顺序固定:
_authenticate-> role -> index privilege。
8. 最小化上线检查清单
- HTTP 与 transport 均开启 TLS
- 客户端只走
https - 业务服务改用 API Key(非 superuser)
- API Key 权限收敛到必须索引与动作
- 安全凭据不落库、不入日志、不入 Git
- 证书与 API Key 都有轮换与过期告警
- 安全相关操作有审计与回溯能力