ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ElasticSearch集群安全加固实战:从证书到密码认证全流程

ElasticSearch集群安全加固实战:从证书到密码认证全流程 1. 为什么ElasticSearch集群必须做安全加固先说个我亲眼见过的真实案例。有次帮朋友排查一个数据平台的问题整套ELK架构跑得飞起业务方每天往集群里灌几千万条日志。我随手在浏览器里敲了一下那个ES节点的IP加9200端口结果直接弹出一大段JSON——集群名、节点列表、索引统计、分片状态全都暴露出来了更夸张的是用curl直接调用_search接口大数据量的业务索引数据就这么明晃晃躺在那里连个登录框都没有。这不是个例很多团队在搭建ElasticSearch集群时第一反应是把性能调优、分片规划、冷热架构搞得明明白白但安全配置往往被当成以后再说的待办项。尤其是纯内网部署的场景大家潜意识里觉得外网进不来就没问题可实际上内网从来不是百分百可信的环境——一个被人拿到内网权限的员工终端、一个配置不当的跳板机、一次供应链攻击都可能导致核心日志库被拖走。ElasticSearch里存的往往不只是日志。业务埋点数据、用户行为数据、系统监控指标、甚至数据库binlog同步过来的业务表数据都可能被索引进ES。这些数据一旦泄露就不是重启一下服务能解决的事。更别提还有一类更隐蔽的风险未授权访问者即使不偷数据也能通过_delete_by_query、_reindex这些接口对你的索引做不可逆的破坏操作。数据被删之前你根本不会意识到这个问题有多严重。ElasticSearch自身是提供了一套完整安全方案的就是X-Pack的安全模块。在7.x版本里它随默认发行版一起打包了基础的安全功能——TLS加密通信、用户名密码认证、角色权限控制——在免费的基本授权Basic License下就能用不需要额外花钱买白金版。也就是说从7.x开始ElasticSearch不能开安全功能是因为要收费这个论调已经站不住脚了。我们只需要动动配置文件、执行几条命令就能把集群从一个裸奔状态变成有认证、有加密、有审计的状态。这篇文章我按实际生产环境的标准走一遍完整流程从证书生成、节点互信配置、密码认证开启到Kibana安全接入全部覆盖。不管你是刚搭好一套三节点集群正在纠结下一步怎么弄还是集群已经跑了半年想回头补安全能力这套流程都适用。版本我以7.17.x为主线8.x的新特性会穿插着提一下方便不同版本的同学对照。2. 安全加固的整体思路先认证、再加密、后管控2.1 传输层加密与身份认证的关系很多人会把TLS证书和密码认证混为一谈觉得我都配了密码了为什么还要搞TLS或者反过来觉得既然都加密了密码是不是可以不设。这是两个维度的事解决的是完全不同的问题。TLS证书解决的是传输过程中数据不被窃听、不被篡改以及和你通信的节点确实是它声称的那个节点。举个例子一个三节点的ES集群节点A往节点B同步分片数据如果中间有三层交换机、负载均衡设备理论上这些设备都能抓包看到TCP报文里的明文数据。开了TLS之后数据在发送端加密、接收端解密链路中间能看到的最多只有一堆密文。这就像快递运输过程中用了带锁的密封箱运输车上的搬运工看不到里面装了什么东西。密码认证解决的是谁有权限访问这个系统。你连上ES的9200端口服务端会要求你先证明你是你——提供合法的用户名和密码组合或者提供有效的证书。这个环节拦的是人的访问。而TLS解决的节点互信问题是集群内部节点之间通信时的双向验证节点A必须拿出证书证明自己是集群的一员节点B才愿意和它建立传输层的加密连接。这两者的关系是叠加的不是二选一的。一个真正安全的ES集群需要在HTTP层REST API访问开启密码认证同时在内部分布式通信的Transport层开启TLS双向加密。这样才能既挡住外面的人又防住链路中的窃听者。2.2 免费授权下的安全功能边界在决定配置方案之前有必要了解一下7.x版本免费授权到底给了我们哪些安全能力免得配到一半发现某个功能弹了个license的报错。安全能力基础授权Free白金版Platinum/EnterpriseTLS传输加密支持支持用户名密码认证支持支持角色权限控制RBAC支持有简化限制完整支持字段级/文档级安全不支持支持单点登录/AD/LDAP集成不支持支持审计日志不支持支持自定义角色支持完整支持从表格能看出来免费版其实覆盖了最核心、最紧急的安全需求传输加密和身份认证。日常使用中给不同团队分不同的角色比如开发组只读权限、运维组管理权限这些在免费版里也能做到。如果后面业务方提出某字段只有特定角色能看这种精细化的需求再考虑升级授权也不迟。2.3 常规方案对比内置安全功能 vs 反向代理网关在做安全加固的时候业内还有另一条路在ES集群前面架一层Nginx或者HAProxy用代理层做SSL终结和HTTP Basic认证。这个方案在早期ES版本5.x、6.xX-Pack安全功能还得另装插件的时候很流行直到现在也有不少团队在用。如果你在纠结走哪条路我建议优先选择ES内置安全功能理由有三点。第一代理层方案只解决了HTTP层的入口认证但集群节点之间Transport层的通信仍然没有加密内网抓包依然能看到节点间同步的数据内容。第二代理层是单点如果只部署一个代理节点它挂了整个ES服务就全挂了部署多个又增加运维复杂度。第三ES内置的安全方案和集群状态本身就是打通的用户在Kibana上能直接管理系统用户、角色和API密钥整个管理闭环都在同一套体系里。当然代理层方案也不是一无是处。如果整个架构里ES之上本来就有一层网关做统一的流量管理顺手在那一层加个认证也不冲突。但如果你是专门为了安全才考虑加代理那完全没必要多此一举ES自己就能搞定。3. 动手之前的环境准备与配置规划3.1 节点规划与版本确认我这次以一套三节点集群为例三台Linux服务器每台16核32G内存磁盘是SSD操作系统是CentOS 7.9。三个节点的IP和角色划分如下节点IP地址角色数据盘挂载点node-1192.168.10.11master data/data1/elasticsearchnode-2192.168.10.12master data/data1/elasticsearchnode-3192.168.10.13master data/data1/elasticsearch生产环境我一般建议专用主节点和数据节点分离但测试环境为了省资源用这种混合角色也没问题。集群规模小时比如不到10个节点master和data混合部署是可以接受的重点是把master节点的minimum_master_nodes参数设对避免脑裂。版本方面我用的ElasticSearch 7.17.9。如果你用的是7.16以下或7.17以上版本配置项基本一致。如果直接上了8.x需要注意8.0默认就开启了安全功能并自动生成证书你需要做的是升级并适配而不是从零配置流程有差异。3.2 系统层面需要预检的几项配置在正式开始配置安全功能之前先把系统层面的几个基础项检查一遍。这些都是操作系统的硬性要求缺一个ES都起不来或者跑不稳。文件描述符限制ulimit -n需要是65535或更高ES在运行时会打开大量文件句柄索引文件、分段文件、translog文件默认1024肯定不够。检查方式是在启动ES的同一用户下执行ulimit -n注意root用户和普通用户看到的值可能不一样。禁用swap在/etc/sysctl.conf里设置vm.swappiness1然后执行sysctl -p生效。ES官方建议是vm.swappiness0但内核版本在3.5以上的建议值是1效果一样。如果不设置操作系统就可能把ES的堆内存换到磁盘上GC延迟直接飙升。线程数限制ulimit -u建议设置成4096以上ES内部的线程池会创建大量执行线程。vm.max_map_countES的索引数据大量使用mmap映射这个值至少要设到262144。不设置的话启动日志里会出现max virtual memory areas vm.max_map_count [65530] is too low的报错然后索引创建直接失败。文件系统挂载选项数据盘要检查挂载选项里有没有noatime避免每次文件访问都更新访问时间戳减少磁盘IO开销。可以用cat /etc/mtab | grep /data1确认。这些系统配置做完之后再用ulimit -a全面检查一遍当前用户的各项限制。我曾经遇到过一台新交付的机器Java环境、目录权限、配置文件全都对就是ES进程一直报unable to create native thread排查到最后发现是/etc/security/limits.conf里写错了用户名导致限制没生效。所以每一个环节都要亲自动手验证不能想当然。3.3 JDK版本与ES自带的JDK选择7.17.x版本的ElasticSearch默认要求JDK 11及以上。比较省心的做法是直接用ES发行包自带的JDK路径在解压目录下的jdk/子目录里。这样做的好处是版本绝对兼容坏处是如果需要调整JVM参数和系统自带的JDK混用时容易搞混。ES会通过JAVA_HOME环境变量去查找JDK如果没有设置JAVA_HOME它就会自动使用自带JDK。我个人建议保持这个默认行为不要画蛇添足去指定系统JDK。因为很多生产问题都出在我明明装了JDK 8为什么ES起不来或者JDK版本太新ES不兼容。监控类软件最忌讳的就是环境依赖不一致用自带JDK可以把这个变量直接消除。如果需要调整ES的JVM堆内存去config/jvm.options里改-Xms和-Xmx值别去改系统环境变量。堆内存的设置原则是不超过物理内存的50%且不超过32G。因为超过32G后JVM会关闭压缩指针同样的堆内存需要的物理内存反而更多性能和资源利用率都会下降。这套原则在8.x版本里同样适用。4. 证书体系的搭建从CA到节点证书全流程4.1 用elasticsearch-certutil生成CA证书ES自带了一个证书生成工具叫elasticsearch-certutil在安装目录的bin/下。这个工具可以帮我们完成CA创建、节点证书生成、证书格式转换这些操作全程交互式跟着提示走就行。16.x及之前的版本叫elasticsearch-certutil8.x版本里还有一个elasticsearch-certutil tls子命令功能更细分但核心用法一致。第一步是生成自签名的CA证书。在任意一个节点上执行cd /usr/local/elasticsearch-7.17.9 bin/elasticsearch-certutil ca执行后会提示输入输出文件名和密码。文件名默认是elastic-stack-ca.p12建议保持默认。密码可以设置也可以留空——如果你打算在后续节点证书中引用这个CA密码一定不要留空因为后面每个节点导入证书时都需要用到CA密码。但也要注意太复杂的密码会带来运维成本每次都要手动输入我建议设一个中等强度的密码记在团队的密码管理工具里。生成的elastic-stack-ca.p12是一个PKCS#12格式的密钥库文件里面包含了CA的私钥和自签名证书。这个文件是整个证书体系的信任根它的私钥一旦泄露等于你签发的所有证书都不再可信所以一定要放在安全的位置最好只有运维人员能访问。4.2 基于CA签发各个节点的证书有了CA之后下一步就是为每个ES节点签发独立的证书。这一步的指令长这样bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --dns node-1,localhost --ip 192.168.10.11,127.0.0.1 --name node-1 --out node-1.p12逐个参数解释一下--ca指定刚才生成的CA文件路径。--name证书名称建议用节点名方便日后排查问题时知道哪个节点在用哪张证书。--dns证书要绑定的主机名。如果ES节点之间通过主机名通信这里必须包含实际使用到的所有主机名。如果不确定至少把localhost加上。--ip证书要绑定的IP地址。ES节点间通信如果走IP那么所有会用到的IP都要列全包括127.0.0.1。--out生成的证书文件名。执行过程中同样会要求输入CA密码然后要求设置节点证书的密码。这里的关键点在于节点证书密码会写进ES配置文件里如果设得太复杂配置文件就会显得很臃肿而且每次增删节点都要找密码。所以这里我建议cert命令生成节点证书时把密码留空直接回车跳过。CA密码要设节点证书密码可以留空这个组合在生产环境里很常见。每个节点都要执行一次上面的命令生成各自的证书文件比如node-2节点生成node-2.p12。三个节点的证书生成完之后将每个节点的.p12文件和CA的.p12文件分别拷贝到对应节点的config/目录下。如果你是在一台机器上集中生成的拷贝时注意别把证书文件搞混。4.3 证书生成环节最容易踩的坑证书生成这个环节看起来简单但有几个隐形的坑是我反复踩过的证书的最小覆盖范围问题。ES节点间通信时互相验证的不只是你是不是持有CA签发的证书还会校验你证书里绑定的主机名或IP是否和你实际连接的主机名或IP一致。如果不一致TLS握手阶段就会报peer not authenticated。所以生成节点证书时--dns和--ip参数要尽量列全包括内网IP、外网IP、主机名、别名宁可多列不可少列。证书有效期的问题。默认生成的证书有效期是5年。对于大部分公司来说这个周期够用了但如果你是一个追求严谨的运维可以加--days参数指定天数比如--days 3650生成10年期证书。注意CA证书和节点证书的有效期是独立设定的CA的有效期最好比节点证书长。证书文件权限的问题。.p12文件包含私钥权限必须严格控制。拷贝到节点后执行一次chmod 600确保只有运行ES的用户能读写。我第一次配的时候忽略了这一步ES启动后报permission denied排查了半天才发现是文件权限不对。证书密码的传递问题。如果你确实在cert命令中设置了节点证书密码那么ES的配置文件里需要明文写上这个密码。这意味着每个能读到配置文件的人都能拿到证书密码。所以要么密码留空要么确保配置文件权限足够严格二选一没有中间态。5. ElasticSearch核心配置修改与安全功能启用5.1 elasticsearch.yml的关键参数说明证书就位后重点就转移到配置文件上了。编辑每个节点config/elasticsearch.yml需要在原有基础上追加下面这组配置。我以node-1为例逐段解释# 集群名称 cluster.name: es-prod-cluster # 节点名称 node.name: node-1 # 数据路径 path.data: /data1/elasticsearch # 日志路径 path.logs: /data1/elasticsearch/logs # 网络配置 network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 # 节点发现配置 discovery.seed_hosts: - 192.168.10.11:9300 - 192.168.10.12:9300 - 192.168.10.13:9300 cluster.initial_master_nodes: - node-1 - node-2 - node-3 # 开启安全功能 xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: node-1.p12 xpack.security.transport.ssl.truststore.path: node-1.p12分几个维度看。xpack.security.enabled: true是总开关开启后ES的HTTP层和Transport层都会启用安全校验此时没有合法凭证的请求一律被拒绝。xpack.security.transport.ssl.enabled: true是Transport层的TLS开关这个参数控制节点间通信的加密传输。xpack.security.transport.ssl.verification_mode有三个可选值none、certificate和full。none表示验证证书但忽略主机名certificate表示验证证书有效性和CA链但跳过主机名/IP校验full表示在certificate基础上额外校验主机名。生产环境你应该用full既然已经生成了带IP和DNS的证书就别浪费这个能力。如果你的证书里没有包含正确的主机名只能退而求其次用certificate。keystore.path和truststore.path指向节点证书文件。大多数情况下两者指向同一个文件即可因为这个.p12文件里既包含自己的私钥和证书keystore也包含CA证书作为truststore的信任锚。如果设置不一样keystore放自己的私钥证书truststore放CA证书也是可以的然后需要在xpack.security.transport.ssl.keystore.secure_password里指定访问密码。5.2 安全配置下HTTP层、Transport层有什么变化开启安全功能后即便只是设置xpack.security.enabled: true还没配置任何用户密码之前ES的HTTP层就已经拒绝一切curl访问了。这是因为安全模块默认会启用认证机制而此刻尚未创建任何用户等于一个能进门的都没有。此时如果直接启动集群日志里会出现类似这样的错误Transport SSL must be enabled if security is enabled. Please set [xpack.security.transport.ssl.enabled] to true ...意思很清楚既然安全功能开了Transport层的TLS也必须开。这个强制约束是为了防止一种情况——有人把HTTP密码认证配好了但节点间通信仍走明文导致内网抓包把集群内部流量看得一清二楚。ES宁可直接拒绝启动也不允许你留一个明文的旁路。第二个明显变化是集群节点发现环节。安全模式开启后节点之间的初始发现建立过程也走TLS握手验签逻辑因此三台节点的config/elasticsearch.yml里必须确保xpack.security.transport.ssl.truststore.path指向的CA链一致否则节点之间互相不信任会一直在日志里刷handshake failed集群永远无法变成绿色。第三个变化是Kibana、Logstash、Beats这些客户端连接ES时都需要主动提供用户名密码了。下一节我会重点演示Kibana的配置方式。如果你用的是Filebeat采集日志要在output.elasticsearch段里加username: elastic和password: xxxx否则数据就进不来。5.3 节点证书密码如何安全存储有些版本的证书在生成时可能不小心设置了密码或者流程要求必须有密码此时你需要在每台节点的config/elasticsearch.keystore里添加安全配置项。ES提供了一套类似Java KeyTool的机制用keystore关键词在elasticsearch.yml中引用但密码本身单独存储在elasticsearch.keystore里。操作方法是bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password执行后会提示你输入密码输入两次确认即可。这样密码就不会明文出现在elasticsearch.yml里即使别人看到配置文件也拿不到证书密码。唯一的风险是elasticsearch.keystore文件本身的权限也要管好默认是600权限。如果你生成的节点证书确实没有设密码那这两行配置可以不写。6. 密码认证的开启与用户的初始化6.1 用elasticsearch-setup-passwords初始化内置用户配置完成并成功启动集群后下一步就是初始化内置用户的密码。ES提供了一条命令来自动生成或手动设置所有内置用户的初始密码bin/elasticsearch-setup-passwords auto执行这条命令后会在终端打印出每个内置用户的随机密码类似这样Changed password for user [apm_system] Changed password for user [kibana_system] Changed password for user [logstash_system] Changed password for user [beats_system] Changed password for user [remote_monitoring_user] Changed password for user [elastic]为了截图留档建议把输出完整保存到一个安全文件里。你也可以用interactive参数来手动指定每个用户的密码bin/elasticsearch-setup-passwords interactive这个模式适合你有明确的密码策略要求比如公司统一要求密码符合复杂度规范、每季度强制更换。手动设置时建议把elastic这个超级管理员的密码设为强密码其他内置用户的密码可以相对短一些但也不能太弱。这些内置用户分别是干什么用的这里简单交代一下elastic超级管理员拥有所有权限Kibana登录和运维操作都靠它。kibana_systemKibana用来连接ES的内部账号Kibana会在配置文件中使用它。logstash_systemLogstash用来向ES上报自身监控数据的账号。beats_systemFilebeat、Metricbeat等Beats全家桶上报数据时用的账号。apm_systemAPM Server上报数据的账号。remote_monitoring_user跨集群监控功能专用账号。在7.x版本里你完全可以用elastic账号在Kibana里创建更多自定义角色和用户但这些内置用户是系统自带的改密码时最好通过上面的命令统一管理。6.2 配置Kibana连接与登录Kibana的接入是整个安全配置中最容易出问题的一环。配置文件在Kibana的config/kibana.yml需要修改的内容包括server.host: 0.0.0.0 server.port: 5601 # ES节点地址 elasticsearch.hosts: [http://192.168.10.11:9200, http://192.168.10.12:9200, http://192.168.10.13:9200] # Kibana连接ES的账号 elasticsearch.username: kibana_system elasticsearch.password: 你的kibana_system密码 # 如果ES的HTTP层也配了TLS需要加下面两行 elasticsearch.ssl.certificateAuthorities: [/path/to/ca.crt]这里有个容易忽略的细节Kibana要连接ES的9200端口如果你在ES的elasticsearch.yml里只开了Transport层的TLS而没开HTTP层的TLS即xpack.security.http.ssl.enabled默认为false那Kibana连接ES的地址仍然用http://就行。反过来如果你把HTTP层的TLS也开了那么ES的REST API就从http变成了https此时Kibana的elasticsearch.hosts必须改成https://同时配置elasticsearch.ssl.certificateAuthorities指向CA证书不然Kibana会报unable to verify the first certificate。从安全强度角度说HTTP层也建议开启TLS。但在实际生产环境中HTTP层后面往往还挂着负载均衡器或内网网关这部分加密可以交给网关去处理ES自身先保证Transport层加密和密码认证也是一个合理的折中方案。如果你的ES节点直接暴露在不可信网络那HTTP层的TLS绝对不能省。6.3 首次登录验证安全配置是否生效所有配置改完后重启ES集群和Kibana。Kibana启动后浏览器访问http://你的Kibana地址:5601如果前面的配置没问题你会看到一个登录界面输入elastic账号和密码就能进入控制台。再回到命令行验证一下HTTP层的效果curl http://192.168.10.11:9200此时返回的应该是一段401认证失败的JSON类似error:Unauthorized。这就对了说明未认证的请求已经被拦住了。再用带账号密码的方式访问curl -u elastic:你的密码 http://192.168.10.11:9200正常的话会返回一串包含cluster_name和tagline的JSON。这个对比测试是确认安全配置生效最快的方法。7. 集群节点间的TLS双向认证细节7.1 Transport层通信的完整握手流程ES节点与节点之间的通信走的是transport协议默认端口9300。开启TLS后一次正常的节点间通信包含以下步骤节点A发起TCP连接到节点B的9300端口。节点A出示自己的客户端证书就是前面生成的node-1.p12。节点B校验该证书是否由信任的CA签发证书是否过期证书绑定的主机名/IP是否与连接来源一致。校验通过后节点B也出示自己的证书节点A做同样的校验。双方确认彼此身份后协商出一套对称加密密钥后续数据传输都用这个密钥加密。这个过程就是TLS双向认证的完整闭环。任何一环不满足条件节点间的通信都会被拒绝。所以在排查问题时顺序很重要先看证书本身是否有效有效期、CA链是否一致再看主机名校验是否通过最后看网络层有没有被防火墙拦。有个比较典型的场景节点A配的truststore里只包含了CA证书但节点B的证书是由另一个CA签发的比如分别用两套不同的CA生成的证书那么两者就互相不信任。即使你有三个节点、配置文件一模一样只要CA不一致集群就永远连不起来。我遇到过有人从别的项目组拷了一份CA文件过来用折腾了一下午没搞明白为什么节点间TLS校验总失败最后查出来是CA文件被换过了。7.2 证书轮转计划的启动生产环境的证书有效期为1年或者5年到期前需要轮换。轮换的大致步骤是用原CA签发新的节点证书。将新证书分发到各节点并替换旧证书文件。逐个重启节点滚动重启让新证书生效。验证集群状态为绿色。证书轮换过程中有一个要注意的点旧证书过期前的几周浏览器和ES客户端可能就开始报警告了。不同用户对这个问题的感知阈值不同有的团队觉得没问题拖到最后一刻才换一旦证书真的过期所有TLS握手都会在瞬间失败整个集群被迫停摆。所以我的建议是把证书到期时间记在运维日历里提前一个月安排轮换留出充足的测试和缓冲时间。7.3 多集群间通信的安全配置如果你有两套集群之间需要做跨集群搜索或者跨集群复制CCS/CCR这两个集群之间也需要配置TLS互信。具体来说发起端集群在配置cluster.remote.alias.seeds时需要同时在该节点的信任列表中加入目标集群的CA证书。这部分配置相对复杂涉及的场景也比较少我今天先不展开细说了但你要知道这个入口在那里需要的时候能立刻找到方向。8. 常见故障排查与实践避坑8.1 启动失败的几类典型报错我把自己在实际运维中踩过的启动问题整理成了一张速查表方便你按图索骥报错信息可能原因解决办法Transport SSL must be enabled if security is enabled开启了安全功能但Transport层TLS开关未打开设置xpack.security.transport.ssl.enabled: trueunable to load KeyStore ... (password may be incorrect)节点证书密码和配置不一致或密码非空但未写入keystore检查elasticsearch.keystore是否添加了对应密码项PKIX path building failed信任链不完整truststore里没有根CA证书确认truststore.path指向包含CA的文件或单独传一个只含CA的truststorepeer not authenticatedTLS握手阶段证书校验失败检查证书中的--dns/--ip是否覆盖节点通信用到的所有地址handshake timed out证书校验通但网络不通或对端端口未监听检查防火墙/安全组是否放行9300端口的TCP连接Received fatal alert: certificate_unknown节点B不认识节点A的CA对比两个节点的CA文件确认同一套CA签发8.2 Kubernetes环境下的证书与配置注意事项如果你的ES集群是跑在Kubernetes里的使用helm chart部署配置路径会有些差异。大部分ES operator会通过Secret挂载证书文件并把配置注入到环境变量中。手动修改elasticsearch.yml在容器里是不持久的一旦Pod重建配置就会丢失正确做法是修改helm values文件或者通过ES operator的配置接口来声明。Kubernetes环境下的证书还有一个特殊点Pod的主机名和IP是动态变化的同一个Pod重启后IP可能就变了。因此在这种环境下证书里的--ip参数很难预先枚举全更多是依赖--dns选项配上Service名称或StatefulSet生成的稳定的DNS名称让校验模式走full时能通过主机名校验。如果你在这类环境下用的是静态IP绑定那每次重建Pod都可能触发证书校验失败。8.3 配置文件管理的一个教训在实际运维中ES配置出问题往往不是某个参数配错了而是多台节点之间配置不一致。比如node-1上xpack.security.transport.ssl.verification_mode配的是full而node-2配的是certificate这种差异在通信时会导致握手行为不一致表现为集群状态时好时坏。我的习惯做法是把三台节点的elasticsearch.yml做一次diff对比确保除了node.name和路径参数之外其余配置完全一致。你可以用diff命令快速比对也可以用配置管理工具Ansible、Chef、Puppet把配置统一模板化。在生产环境里用Ansible管理ES配置是个很成熟的做法所有节点共用同一份模板个别差异通过变量替换能最大程度避免人为配置漂移。8.4 从零恢复被误删的集群安全配置最后讲一个我亲历的极端情况。有次做变更时不小心把一台节点的config/目录整个删除了幸好备份在案。恢复的过程有个细节值得注意恢复配置文件后ES启动时可能会因为权限原因无法读取证书文件因为备份还原往往会把文件的user:group改掉而ES进程是以elasticsearch用户运行的。这种情况下执行chown -R elasticsearch:elasticsearch /usr/local/elasticsearch-7.17.9再重启ES进程就能恢复。类似的权限问题还可能出现在path.data目录和日志目录上凡是ES需要读写的路径都要确认归属用户正确。这个问题看着小真到恢复演练时能卡住一大批人。另外建议所有ES相关的配置文件和证书文件至少保留一份异地备份。集群本身是分布式的但配置文件往往是每个节点各一份节点损坏后靠其他节点把配置拼回来不是不行但代价太大。提前把配置文件纳入Git或者配置管理仓库才是更符合工程习惯的做法。9. 上线前必须做的五步自检清单行文至此核心配置流程已经完整了。最后把这个过程的验收清单列出来建议上线前逐项打勾所有节点的elasticsearch.yml里xpack.security.enabled、xpack.security.transport.ssl.enabled均为true且各节点配置内容一致。证书文件与CA文件已拷贝到所有节点权限为600属主为ES运行用户。elasticsearch-setup-passwords auto执行完成所有内置用户的密码已记录在安全位置。未带凭证的curl请求被401拒绝带-u elastic:密码的请求正常返回集群信息。Kibana能正常登录elastic账号可以访问Dev Toolskibana_system账号的连接配置无误。这套流程走完之后你的ES集群就从裸奔状态变成了一个具备传输层加密和身份认证的安全体系。用我常说的一句话来总结就是ElasticSearch本身就像一栋办公楼的钥匙系统没装安全的时候大门敞开着谁都能进配好TLS和密码认证之后门锁上了楼里的房间还有不同的权限级别不是谁拿着钥匙都能进所有门。我个人的体会是安全配置这件事一定要在集群刚搭好的时候就做千万别等到上线前最后一天再临时抱佛脚。配错的坑、重启的窗口、集群变红的紧张感所有这些都是可以提前消化掉的。如果你正在为刚搭好的ES集群做安全加固照着这篇文章一步一步来应该能少走不少弯路。
返回列表