ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 一个漏洞引发的升级 —— redis cluster in kubernetes

一个漏洞引发的升级 —— redis cluster in kubernetes

原创 Linux操作系统 作者:保持好奇心 时间:2025-07-18 10:43:21 0 删除 编辑

1. 前提

前几天,一个项目组反馈甲方爸爸要求协查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必须升级。

2. 研究

但是,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。那么我们需要自动动手丰衣足食。

3. 操作

首先按要求打包redis和redis-exporter

3.1. 打包镜像

3.1.1. 克隆代码

在一台安装了docker的主机上(使用nerdctl和podman的同学自行替换命令前缀,本次不另行说明)下载代码

git clone https://github.com/OT-CONTAINER-KIT/redis.git

3.1.2. 打包镜像

代码克隆到本地后,先确认我们可以使用的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

3.1.3. 下载redis-operator

最新版的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

3.2. 下载helm chart

由于需要升级的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

3.3. 部署redis cluster

将下载结果导入到内网后,需要修改以下信息。首先修改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上示例代码对实际环境进行适应性调整。

 4. 最后吐槽

整体升级过程比较顺利,但是我不得不去在最后吐槽一个事情,这次甲方爸爸安全管理团队给出来的漏洞协查通报差点把我们弄得不知所措。协查通内容关键部分截图如下:

从截图上可以看到,“影响范围包括了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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-11-08

  • 博文量
    4
  • 访问量
    5552