前几天,一个项目组反馈甲方爸爸要求协查redis的一个安全漏洞CVE-2025-32023,并按要求整改。之前负责kubernetes集群的整体运维的同事离职了,这个需求就自然而然的流转到了我的手上。查看环境,得出以下信息:
redis cluster 集群解决方案
方案供应商:bitnami
镜像名称:redis-cluster
版本号:7.0.15
本次甲方提供的漏洞排查文件要求,需要将redis版本升级到redis 7.2.10及以上版本、redis 7.4.5及以上版本或redis 8.0.3及以上版本。所以简单粗暴的说,本次kubernetes集群中的redis cluster必须升级。
但是,bitnami在docker hub上只发布了7.2.5和7.4.3两个版本,不符合排查通知的要求。在github上找了一圈,也没有bitnami官方提供提供的Dokcerfile,本想投机取巧,反向解析redis-cluster镜像,导出Dockerfile,结果也不如人意。这么看来目前只有抛弃基于bitnami的快速解决方案了。
到处搜索了一下,发现OpsTree的 OT-CONTAINER-KIT项目提供了完整的redis、redis-exporter和redis-operator打包的Dockerfile,为本次CVE漏洞修复工作提供了可能。
ps: 本文编写时,redis官方在docker hub上发布的最新有效版本为:7.2.10、7.4.5和8.0.3;而OpsTree项目组在quay.io上发布的redis版本分别为7.2.9、7.4.4和8.0.2。那么我们需要自动动手丰衣足食。
首先按要求打包redis和redis-exporter
在一台安装了docker的主机上(使用nerdctl和podman的同学自行替换命令前缀,本次不另行说明)下载代码
git clone https://github.com/OT-CONTAINER-KIT/redis.git
代码克隆到本地后,先确认我们可以使用的redis和redis-exporter的最新版本
redis下载列表: https://download.redis.io/releases/
redis-exporter下载列表: https://github.com/oliver006/redis_exporter/releases
在上面两个软件列表中找到你需要打包的最新版本号
进行以下操作:
[root@demo redis]# cd redis [root@demo redis]# vim Makefile
将 REDIS_VERSION、REDIS_SENTINEL_VERSION、REDIS_EXPORTER_VERSION 三个环境变量修改成你需要打包的版本号,本问需要打包的版本分别是 7.2.10和1.74.0
REDIS_VERSION ?= v7.2.10 REDIS_SENTINEL_VERSION ?= v7.2.10 REDIS_EXPORTER_VERSION ?= v1.74.0
然后使用以下命令开始打包
[root@demo redis]# make build-redis [root@demo redis]# make build-redis-export
打包过程如未报错,可是使用docker命令查看打包好的镜像文件
docker images REPOSITORY TAG IMAGE ID CREATED SIZE quay.io/opstree/redis-exporter v1.74.0 5ec2f2ef33f0 3 days ago 9.87MB quay.io/opstree/redis v7.2.10 a2a80fdb16d6 3 days ago 36.7MB
最新版的redis-operator可以使用以下命令从 quay.io仓库拉取回本地
[root@demo redis]# docker pull quay.io/opstree/redis-operator:v0.21.0 v0.21.0: Pulling from opstree/redis-operator 35d697fe2738: Pull complete bfb59b82a9b6: Pull complete 4eff9a62d888: Pull complete a62778643d56: Pull complete 7c12895b777b: Pull complete 3214acf345c0: Pull complete 5664b15f108b: Pull complete 0bab15eea81d: Pull complete 4aa0ea1413d3: Pull complete da7816fa955e: Pull complete ddf74a63f7d8: Pull complete 3dfebf7e04b0: Pull complete Digest: sha256:a116737deaca6b33f1d32bbefd2818e8949f16cf732fec45e4ee1b58e57ae937 Status: Downloaded newer image for quay.io/opstree/redis-operator:v0.21.0 quay.io/opstree/redis-operator:v0.21.0 [root@demo redis]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE quay.io/opstree/redis-exporter v1.74.0 5ec2f2ef33f0 3 days ago 9.87MB quay.io/opstree/redis v7.2.10 a2a80fdb16d6 3 days ago 36.7MB quay.io/opstree/redis-operator v0.21.0 abaac4e523b6 2 weeks ago 47.1MB
升级过程需要的镜像文件准备好了,需要将镜像导出,并拷贝到内网(不含拷贝过程),执行以下命令
# 导出redis相关镜像 [root@source redis]# docker save -o docker-images-redis-operator-v0.21.0.tar \ quay.io/opstree/redis-exporter:v1.74.0 \ quay.io/opstree/redis:v7.2.10 \ quay.io/opstree/redis-operator:v0.21.0 # 导入redis相关镜像 [root@target redis]# docker load -i docker-images-redis-operator-v0.21.0.tar # 修改image标签 [root@target redis]# docker tag quay.io/opstree/redis-exporter:v1.74.0 <私有Registry URL>/opstree/redis-exporter:v1.74.0 [root@target redis]# docker tag quay.io/opstree/redis:v7.2.10 <私有Registry URL>/opstree/redis:v7.2.10 [root@target redis]# docker tag quay.io/opstree/redis-operator:v0.21.0 <私有Registry URL>/opstree/redis-operator:v0.21.0 [root@target redis]# docker push <私有Registry URL>/opstree/redis-exporter:v1.74.0 [root@target redis]# docker push <私有Registry URL>/opstree/redis:v7.2.10 [root@target redis]# docker push <私有Registry URL>/opstree/redis-operator:v0.21.0
由于需要升级的redis cluster集群被设置了网络隔离无法访问公网,所以需要一台能够访问公网的主机用于连接helm仓库并下载相关的helm包。
首先下载helm软件包
[root@source redis]# helm repo add ot-helm [root@source redis]# helm pull ot-helm/redis-operator [root@source redis]# helm pull ot-helm/redis-cluster # 查看下载结果 [root@source redis]# ll total 93336 -rw-r--r-- 1 root root 5028 Jul 14 15:39 helm-chart-redis-cluster-0.17.0.tgz -rw-r--r-- 1 root root 171417 Jul 14 10:08 helm-chart-redis-operator-0.21.2.tgz
将下载结果导入到内网后,需要修改以下信息。首先修改redis-operator中的values.yaml。
[root@target redis]# tar zxvf helm-chart-redis-operator-0.21.2.tgz redis-operator/Chart.yaml redis-operator/values.yaml redis-operator/templates/NOTES.txt redis-operator/templates/_helpers.tpl redis-operator/templates/cert-manager.yaml redis-operator/templates/mutating-webhook-configuration.yaml redis-operator/templates/operator-deployment.yaml redis-operator/templates/role-binding.yaml redis-operator/templates/role.yaml redis-operator/templates/service-account.yaml redis-operator/templates/service.yaml redis-operator/.gitignore redis-operator/README.md redis-operator/README.md.gotmpl redis-operator/crds/crds.yaml [root@target redis]# vim redis-operator/values.yaml --- redisOperator: name: redis-operator # 修改前 # imageName: ghcr.io/ot-container-kit/redis-operator/redis-operator # 修改后 imageName: <私有Registry URL>/opstree/redis-operator # 修改前 # imageTag: "" # 修改后 imageTag: "0.21.2" imagePullPolicy: Always imagePullSecrets: [] :x
再修改redis-cluster中的values.yaml
[root@target redis]# tar zxvf helm-chart-redis-cluster-0.17.0.tgz
redis-cluster/Chart.yaml
redis-cluster/values.yaml
redis-cluster/templates/_helpers.tpl
redis-cluster/templates/extra-config.yaml
redis-cluster/templates/follower-service.yaml
redis-cluster/templates/follower-sm.yaml
redis-cluster/templates/leader-service.yaml
redis-cluster/templates/leader-sm.yaml
redis-cluster/templates/redis-cluster.yaml
redis-cluster/README.md
redis-cluster/README.md.gotmpl
[root@target redis]# vim redis-cluster/values.yaml
---
redisCluster:
name: ""
clusterSize: 3
clusterVersion: v7
persistenceEnabled: true
# 修改前
# image: quay.io/opstree/redis
# 修改后
image: <私有Registry URL>/opstree/redis
# 修改前
# tag: v7.0.15
# 修改后
tag: v7.2.10
imagePullPolicy: IfNotPresent
imagePullSecrets: {}
# - name: Secret with Registry credentials
redisSecret:
# 修改前
# secretName: ""
# 修改后
secretName: "redis-secret"
# 修改前
# secretKey: ""
# 修改后
secretKey: "password"
……
redisExporter:
enabled: false
# 修改前
# image: quay.io/opstree/redis-exporter
# 修改后
image: <私有Registry URL>/opstree/redis-exporter
# 修改前
# tag: "v1.44.0"
# 修改后
tag: "v1.74.0"
imagePullPolicy: IfNotPresent
resources: {}
……
# 如果需要调整Pod的PVC,可按一下修改
storageSpec:
volumeClaimTemplate: #dump.rdb文件所在目录的大小
spec:
# storageClassName: standard
accessModes: ["ReadWriteOnce"]
resources:
requests:
# 修改前
# storage: 1Gi
# 修改后
storage: 10Gi
nodeConfVolume: true
nodeConfVolumeClaimTemplate: #配置文件所在目录的大小
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
# 修改前
# storage: 1Gi
# 修改后
storage: 10Gi
:x
修改完成后,执行以下命令:
[root@target redis]# helm install redis-operator ./redis-operator --namespace redis-cluster ... Release "redis-operator" does not exist. Installing it now. NAME: redis-operator LAST DEPLOYED: Mon Jul 14 14:42:23 2025 NAMESPACE: ot-operators STATUS: deployed REVISION: 1 TEST SUITE: None [root@target redis]# helm install redis-cluster ./redis-cluster --namespace redis-cluster ... Release "redis-cluster" does not exist. Installing it now. NAME: redis-cluster LAST DEPLOYED: Mon Jul 14 14:42:25 2025 NAMESPACE: ot-operators STATUS: deployed REVISION: 1 TEST SUITE: None
以上操作完成redis cluster部署完成,接下来验证redis cluster部署情况
[root@target redis]# kubectl get pods -n redis-cluster NAME READY STATUS RESTARTS AGE redis-cluster-follower-0 1/1 Running 0 149m redis-cluster-follower-1 1/1 Running 0 150m redis-cluster-follower-2 1/1 Running 0 151m redis-cluster-leader-0 1/1 Running 0 149m redis-cluster-leader-1 1/1 Running 0 150m redis-cluster-leader-2 1/1 Running 0 151m redis-operator-85fh4c5584-xptef 1/1 Running 0 210m [root@target redis]# kubectl get service -n redis-cluster NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE redis-cluster-follower ClusterIP 10.43.98.168 <none> 6379/TCP 2d15h redis-cluster-follower-additional ClusterIP 10.43.216.73 <none> 6379/TCP 2d15h redis-cluster-follower-headless ClusterIP None <none> 6379/TCP 2d15h redis-cluster-leader ClusterIP 10.43.207.60 <none> 6379/TCP 2d16h redis-cluster-leader-additional ClusterIP 10.43.41.212 <none> 6379/TCP 2d16h redis-cluster-leader-headless ClusterIP None <none> 6379/TCP 2d16h redis-cluster-master ClusterIP 10.43.67.117 <none> 6379/TCP 2d16h [root@target redis]# kubectl exec -it redis-leader-0 -- /bin/bash redis-cluster leader-0:/data$ redis-server --version Redis server v=7.2.10 sha=00000000:0 mallociemalloc-5.3.0 bits=64 build=a75cdb8c2a9e1100 redis-cluster leader-0:/data$ redis-cli -c -a <passsword> > cluster nodes 988d2db264614f4a91b6d1498d9211a6bfceec84 172.16.51.203:6379@16379,redis-cluster-follower-2 slave 4837b8391f01efc48cc3cf7fdce34656bc3015c8 0 1752804520000 13 connected 5d20f074e86043bbb21cc3e9f9bae66290781ac8 172.16.168.234:6379@16379,redis-cluster-follower-0 slave c954de5df9ed66c467295bb9d386e553a532687d 0 1752804520848 15 connected 207c90b481a7974d3e4b436159ea3be3bf486120 172.16.141.228:6379@16379,redis-cluster-follower-1 slave 555f169de0143dd0dc8b2c8771bb4e9c6d33c9a4 0 1752804520000 14 connected c954de5df9ed66c467295bb9d386e553a532687d 172.16.168.230:6379@16379,redis-cluster-leader-0 myself,master - 0 1752804518000 15 connected 0-5460 555f169de0143dd0dc8b2c8771bb4e9c6d33c9a4 172.16.141.247:6379@16379,redis-cluster-leader-1 master - 0 1752804519000 14 connected 5461-10922 4837b8391f01efc48cc3cf7fdce34656bc3015c8 172.16.51.204:6379@16379,redis-cluster-leader-2 master - 0 1752804519844 13 connected 10923-16383 > cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:15 cluster_my_epoch:15 cluster_stats_messages_ping_sent:412109 cluster_stats_messages_pong_sent:423894 cluster_stats_messages_fail_sent:15 cluster_stats_messages_auth-req_sent:5 cluster_stats_messages_mfstart_sent:1 cluster_stats_messages_sent:836024 cluster_stats_messages_ping_received:423889 cluster_stats_messages_pong_received:412108 cluster_stats_messages_fail_received:1 cluster_stats_messages_auth-req_received:2 cluster_stats_messages_auth-ack_received:3 cluster_stats_messages_received:836003 total_cluster_links_buffer_limit_exceeded:0
综上所述,整个redis cluster集群已经运行正常,kubernetes集群内pod使用域名访问redis,使用如下域名和端口:redis-cluster-leader.redis-cluster.svc.cluster.local:6379,集群外访问redis需要按照 opstree官方文档和opstree在 github上示例代码对实际环境进行适应性调整。
整体升级过程比较顺利,但是我不得不去在最后吐槽一个事情,这次甲方爸爸安全管理团队给出来的漏洞协查通报差点把我们弄得不知所措。协查通内容关键部分截图如下:

从截图上可以看到,“影响范围包括了8.0.3、7.2.10和7.4.5”,而修复建议又让我们“ 升级产品至 8.0.3、7.2.10、7.4.5、6.2.19 或之后的版本”。当我们刚拿到协查通报的时候,无脑的去翻redis的当前最新版。当我们发现redis官方没有发布高于 8.0.3、7.2.10和7.4.5以上版本的时候,大家一脸懵逼。只有老老实实回头去查CVE漏洞 CVE-2025-32023原文描述

CVE漏洞原文里面是“<”小于,小于,小于,被国内安全厂商无脑加码成了“<=”小于等于。同时redis官方又没有提供更高于这几个版本号的新版本,那还让我们如何修复? 还好在我们把实际情况同步给甲方爸爸后,甲方爸爸同意了我们提供的这个修复方案。在此,我想吐槽一下,咱们做漏洞修复,需要一个严谨科学的过程,作为发现问题和提供解决方案的第一线,安全厂商内部能不要无脑的层层加码,转载翻译一个CVE漏洞都能把真正可用的唯一解决方案一棒子打死在地上。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70042155/viewspace-3091121/ ,如需转载,请注明出处,否则将追究法律责任。