Elasticsearch 安全加固实战:从零开始配置密码与集群防护
你有没有遇到过这样的场景?刚搭好的 Elasticsearch 集群,几分钟后就被挖矿程序“盯上”,索引里突然多了个xmr-stak的文档;或者在公网上一通扫描,发现某个/logs-*索引能直接GET下来几百万条敏感日志。
这并不是危言耸听——Elasticsearch 默认是“裸奔”的。
它设计之初追求的是快速部署和高可用性,因此安装即运行、无需认证。这种“友好”在开发环境很香,但在生产环境中无异于把数据库大门敞开。尤其当你用它存日志、用户行为数据甚至交易记录时,设置访问密码、启用加密通信已不再是“加分项”,而是底线要求。
本文不讲空泛理论,也不堆砌命令行截图。我会带你一步步走完一个真实生产级 Elasticsearch 安全集群的搭建流程,涵盖从证书生成、节点加密、账号体系到权限控制的每一个关键细节。目标只有一个:让你的集群真正“守得住”。
为什么不能只靠防火墙?
很多团队的第一反应是:“我把 ES 放内网,前面加个 Nginx 做 Basic Auth 不就行了吗?”
听起来合理,但问题不少:
- 权限太粗:Nginx 只能控制“能不能进”,无法判断“能看什么”。一个普通运维人员可能和管理员拥有同样的接口访问权。
- 凭据明文传输:HTTP Basic Auth 的用户名密码是以 Base64 编码形式发送的,抓包即可还原。
- 无审计能力:谁删了索引?什么时候发生的?Nginx 日志只能看到 IP 和路径,看不到具体操作者。
- 节点间仍暴露:即使 HTTP 层做了保护,节点之间的 9300 端口仍是明文通信,一旦网络被渗透,整个集群就沦陷了。
所以,真正的安全必须从原生层开始构建。而 Elasticsearch 自带的 X-Pack Security 模块,就是我们最可靠的选择。
✅ 划重点:elasticsearch设置密码 ≠ 给 Kibana 加登录页。它是整套身份认证 + 权限控制 + 通信加密的系统工程。
核心武器:X-Pack Security 到底能做什么?
别被“X-Pack”这个名字吓到,它早已不是收费插件了。从 6.8 版本起,Elastic 就把 Security、Monitoring 等功能免费开放给了所有人。
我们关心的核心能力只有四个字:控人、管权、加密、留痕。
控人:谁可以连接?
支持多种用户来源:
- 文件用户(.roles.yml,.users)——适合小规模;
- LDAP / Active Directory ——对接企业统一身份;
- SAML/OIDC ——实现单点登录;
- API Key ——服务间调用更安全。
管权:能干什么?
基于角色的访问控制(RBAC),细粒度到:
-集群级别:能否查看健康状态、创建模板、管理用户?
-索引级别:对orders-*能读不能写?对logs-dev完全不可见?
-字段级别:隐藏salary字段,仅允许特定角色查看;
-文档级别:通过查询条件限制可见范围,比如“只能看自己部门的数据”。
加密:传输是否安全?
双通道加密支持:
-Transport Layer(9300):节点之间通信加密,防窃听、防伪造;
-HTTP Layer(9200):客户端访问启用 HTTPS,杜绝中间人攻击。
留痕:操作是否可追溯?
开启审计日志后,以下行为都会被记录:
- 用户登录失败/成功;
- 删除索引、修改映射;
- 执行高危 API 请求;
- 来源 IP、时间戳、请求体摘要……
这些日志本身也可以被采集进 ELK,形成闭环监控。
第一步:为集群穿上“加密盔甲”——TLS 证书配置
没有加密的认证等于裸奔。哪怕你设置了密码,只要通信未加密,攻击者依然可以通过抓包获取你的凭证。
所以我们第一步不是设密码,而是先让节点之间用 TLS 说话。
使用elasticsearch-certutil自动生成证书
Elastic 提供了一个神器:certutil,它可以一键生成 CA 和节点证书。
1. 生成根证书(CA)
bin/elasticsearch-certutil ca --out config/certs/ca.p12 --pass ""这会生成一个名为ca.p12的 PKCS#12 格式证书包,作为你集群的信任根。
2. 为所有节点生成证书
bin/elasticsearch-certutil cert \ --ca config/certs/ca.p12 \ --ip 192.168.1.10,192.168.1.11,192.168.1.12 \ --dns es-node1,es-node2,es-node3,localhost \ --out config/certs/nodes.p12 \ --pass ""这里指定了节点的 IP 和 DNS 名称,确保 TLS 握手时主机名验证能通过。
3. 解压并分发证书
unzip nodes.p12 -d config/certs/你会得到每个节点对应的.crt和.key文件。将它们放入各节点的config/certs/目录下。
💡 小贴士:建议为每个节点单独签发唯一证书,避免共用密钥带来的横向扩散风险。
第二步:启用安全模块与双向加密
修改每个节点的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.key: certs/es-node1-key.pem xpack.security.transport.ssl.certificate: certs/es-node1-crt.pem xpack.security.transport.ssl.certificate_authorities: [ "certs/ca.pem" ] # 启用 HTTP 层 TLS(客户端加密) xpack.security.http.ssl.enabled: true xpack.security.http.ssl.key: certs/http-es-node1-key.pem xpack.security.http.ssl.certificate: certs/http-es-node1-crt.pem xpack.security.http.ssl.certificate_authorities: [ "certs/ca.pem" ] # 其他必要配置 cluster.name: my-secure-cluster node.name: es-node1 network.host: 0.0.0.0 discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"] cluster.initial_master_nodes: ["es-node1", "es-node2", "es-node3"]⚠️ 注意事项:
-transport.ssl和http.ssl最好使用不同的证书对,降低泄露影响面;
-certificate_authorities必须指向 CA 证书,否则节点无法相互信任;
- 若使用 PEM 格式,请确保私钥无密码保护(或配置ssl.key_passphrase)。
第三步:初始化内置用户密码
现在重启集群,你会发现日志中提示:
Security is enabled, but the built-in users have not been configured.这是因为虽然安全模块启用了,但默认用户还没有设密码。
这时候就要请出第二个工具:elasticsearch-setup-passwords。
方式一:自动生成(适合测试环境)
bin/elasticsearch-setup-passwords auto执行后会输出类似:
PASSWORD elastic = uElJYX7Gv9z2RkQxLmNp PASSWORD kibana_system = sKjWnBqT5oPmVcXeZaRt ...保存好这些密码!尤其是elastic用户,它是超级管理员账户。
方式二:交互式设置(推荐用于生产)
bin/elasticsearch-setup-passwords interactive你可以手动为以下内置用户设置强密码:
-elastic:超级用户,拥有全部权限;
-kibana_system:Kibana 连接专用;
-logstash_system:Logstash 写入专用;
-beats_system:Filebeat 等组件使用;
-apm_system:APM Server 使用;
-remote_monitoring_user:远程监控账户。
🔐 安全建议:
-elastic用户应离线保管,日常运维使用普通管理员账号;
- 所有密码必须符合复杂度策略(大小写+数字+符号,至少12位);
- 生产环境禁止使用auto模式,防止密码意外泄露。
第四步:创建业务用户与角色
内置用户解决的是“系统组件怎么连”的问题,而业务用户的管理才是“人怎么安全使用”的核心。
场景举例:给数据分析团队开通只读权限
我们需要创建一个角色data_analyst_role,允许其读取logs-*和metrics-*索引,但不能删除或写入。
1. 创建角色(通过 REST API)
PUT _security/role/data_analyst_role { "indices": [ { "names": ["logs-*", "metrics-*"], "privileges": ["read", "view_index_metadata"], "field_security": { "grant": ["@timestamp", "message", "level", "service.name"] }, "query": "{\"term\": {\"env\": \"prod\"}}" } ], "cluster": ["monitor"] }解释一下这个配置:
-privileges: 只读权限;
-field_security: 仅暴露必要字段,隐藏如user.token这类敏感信息;
-query: 强制添加过滤条件,用户即使想查dev环境也查不到;
-cluster.monitor: 允许查看集群健康状态。
2. 创建用户并绑定角色
PUT _security/user/analyst_li { "password": "StrongPass!2025", "roles": ["data_analyst_role"], "full_name": "Li Wei", "email": "liwei@company.com" }这样,用户analyst_li登录 Kibana 或调用 API 时,天然就被限制在“生产环境日志只读”的范围内。
第五步:配置 Kibana 安全连接
Kibana 是用户最常用的入口,必须同样做好安全加固。
编辑kibana.yml:
# 连接 ES 的用户名密码 elasticsearch.username: "kibana_system" elasticsearch.password: "your_kibana_system_password" # 启用 HTTPS 并信任 CA elasticsearch.hosts: ["https://es-node1:9200", "https://es-node2:9200"] elasticsearch.ssl.certificateAuthorities: ["/path/to/ca.pem"] # 启用 Kibana 登录界面 server.ssl.enabled: true server.ssl.key: /path/to/kibana.key server.ssl.certificate: /path/to/kibana.crt # 开启登录认证 xpack.security.enabled: true重启 Kibana 后,访问页面会跳转至登录页,输入你在_security/user中创建的账号即可进入。
高阶技巧与避坑指南
1. 如何避免密码硬编码?
把密码写在配置文件里显然不安全。更好的做法是使用keystore:
# 创建 keystore(首次) bin/elasticsearch-keystore create # 添加密码(自动加密存储) bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password # 在 elasticsearch.yml 中引用 xpack.security.http.ssl.keystore.password: ${xpack.security.http.ssl.keystore.secure_password}Kibana 也支持 secrets management,可结合 Hashicorp Vault 使用。
2. 节点无法加入集群?常见原因排查
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
节点启动报错handshake failed | 证书 CN/SAN 不匹配 | 检查--dns和--ip是否包含当前主机名 |
提示certificate trust failed | CA 证书未正确加载 | 确认certificate_authorities路径正确且文件可读 |
集群状态为RED | 主节点未正确选举 | 检查cluster.initial_master_nodes是否一致 |
3. 审计日志开启方式
在elasticsearch.yml中添加:
xpack.security.audit.enabled: true xpack.security.audit.logfile.events.include: ["access_denied", "access_granted", "connection_denied", "authentication_failed"] xpack.security.audit.logfile.events.exclude: ["anonymous_access_denied", "authentication_success"]日志将输出到logs/audit.log,可用于对接 SIEM 系统。
总结:一套安全集群的标准清单
当你完成以上步骤后,你的 Elasticsearch 集群应该满足以下标准:
✅ 所有节点间通信加密(Transport TLS)
✅ 外部访问强制 HTTPS(HTTP TLS)
✅ 内置用户均已设置强密码
✅elastic超级用户密码已妥善保管
✅ 业务用户按最小权限原则分配角色
✅ 敏感字段与文档已做访问隔离
✅ Kibana 已启用登录认证
✅ 审计日志已开启并定期归档
✅.security-*索引已纳入备份计划
写在最后
Elasticsearch 的强大在于它的开放与灵活,但也正因如此,安全责任更多落在了使用者身上。
设置密码只是起点,构建纵深防御体系才是终点。从网络隔离、证书管理到权限划分、行为审计,每一层都不可或缺。
希望这篇指南不仅能帮你完成一次成功的安全加固,更能建立起一种“默认不信任”的安全思维。毕竟,在今天的互联网环境下,不是“会不会被攻击”,而是“什么时候被攻击”。
如果你正在搭建或迁移集群,不妨现在就打开终端,运行第一条certutil命令——最好的安全实践,永远是马上开始的那一项。
📣 欢迎在评论区分享你的安全配置经验,或提出你在实施过程中遇到的具体问题,我们一起探讨解决方案。