2026-03-13 start:
将redis版本升级为7.4.6,能够修复 Redis 拒绝服务漏洞(CVE-2025-21605、CVE-2025-32023、CVE-2025-49844)
CVE-2025-21605 是 Redis 中一个高危拒绝服务(DoS)漏洞,核心是未认证客户端可让输出缓冲区无限增长、耗尽内存导致服务崩溃。
一、漏洞核心信息
漏洞编号:CVE-2025-21605
CVSS 评分:7.5(高危)
漏洞类型:拒绝服务(DoS)、内存耗尽
影响范围:Redis 2.6 及以上、7.4.3 以下所有版本
利用条件:无需认证、无需特权,仅需能网络访问 Redis 实例
二、漏洞原理
漏洞源于 Redis 输出缓冲区管理的设计缺陷:
默认无限制:client-output-buffer-limit 对普通客户端默认不设上限,输出缓冲区可无限增长。
未认证也可触发:
无密码时:直接发大量请求,响应持续堆积在缓冲区。
有密码但未提供:每次请求返回 NOAUTH,错误响应不断累积。
最终结果:缓冲区占满所有内存,Redis 进程被系统 OOM Killer 终止,服务不可用。
Redis Lua远程代码执行漏洞(CVE-2025-49844)是一个已存在约13年的严重内存释放后使用漏洞,允许认证用户通过恶意Lua脚本实现沙箱逃逸和远程代码执行,CVSS评分高达9.9-10.0。
漏洞概述
漏洞名称:Redis Lua脚本远程代码执行漏洞
CVE编号:CVE-2025-49844
公开时间:2025年10月3日
CVSS评分:9.9 - 10.0(严重)
漏洞类型:释放后使用(Use-After-Free, UAF)
发现者:Wiz研究团队(Benny Isaacs, Nir Brakha, Sagi Tzadik)通过Pwn2Own Berlin 2025报告
CVE-2025-32023 是 Redis 中高危远程代码执行(RCE)漏洞,相比之前的 DoS 漏洞风险更高 —— 攻击者可通过特定操作在 Redis 服务器上执行任意命令,直接控制服务器,属于 Redis 近年最严重的漏洞之一。
在/opt/redis目录创建redis_upgrade.sh:
cat > redis_upgrade.sh << 'EOF'
# 粘贴下面的完整脚本内容(全部复制,包括#!/bin/bash开头)
EOF
chmod +x redis_upgrade.sh
#!/bin/bash
set -e
# ====================== 核心配置(仅需改这3项)======================
REDIS_PASSWORD="你的生产Redis密码" # 替换为真实密码
REDIS_PATH="/opt/redis" # 安装路径(无需改)
REDIS_PORT="你的实际端口" # 替换为生产环境端口(如 6378/6380 等)
# ====================================================================
REDIS_CONF="${REDIS_PATH}/conf/redis.conf"
REDIS_USER="redis"
TARGET_VERSION="7.4.6"
red() { echo -e "\033[31m$1\033[0m"; }
green() { echo -e "\033[32m$1\033[0m"; }
yellow() { echo -e "\033[33m$1\033[0m"; }
blue() { echo -e "\033[34m$1\033[0m"; }
blue "===== 1. 前置检查 ====="
if ! id -u "${REDIS_USER}" >/dev/null 2>&1; then
red "错误:用户 ${REDIS_USER} 不存在!"
exit 1
fi
if [ ! -f "${REDIS_CONF}" ]; then
red "错误:配置文件 ${REDIS_CONF} 不存在!"
exit 1
fi
# 适配非6379端口的Redis连接检查
if ! ${REDIS_PATH}/bin/redis-cli -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" PING >/dev/null 2>&1; then
red "错误:Redis ${REDIS_PORT} 端口未运行或密码错误!"
exit 1
fi
green "前置检查通过"
blue "===== 2. 全量备份 ====="
BACKUP_DIR="${REDIS_PATH}.bak.$(date +%Y%m%d_%H%M%S)"
sudo cp -r "${REDIS_PATH}" "${BACKUP_DIR}"
green "备份完成:${BACKUP_DIR}"
blue "===== 3. 下载编译 Redis ${TARGET_VERSION} ====="
cd /tmp || exit
if [ ! -f "redis-${TARGET_VERSION}.tar.gz" ]; then
wget --no-check-certificate "https://download.redis.io/releases/redis-${TARGET_VERSION}.tar.gz" || {
red "下载Redis失败!"
exit 1
}
fi
tar -zxf "redis-${TARGET_VERSION}.tar.gz" || {
red "解压Redis包失败!"
exit 1
}
cd "redis-${TARGET_VERSION}" || exit
make clean && make MALLOC=jemalloc -j4 || {
red "编译Redis失败!"
exit 1
}
green "Redis ${TARGET_VERSION} 编译完成"
blue "===== 4. 热替换二进制文件 ====="
sudo mv "${REDIS_PATH}/bin/redis-server" "${REDIS_PATH}/bin/redis-server.old"
sudo mv "${REDIS_PATH}/bin/redis-sentinel" "${REDIS_PATH}/bin/redis-sentinel.old"
sudo cp src/redis-server "${REDIS_PATH}/bin/"
sudo cp src/redis-cli "${REDIS_PATH}/bin/"
sudo cp src/redis-sentinel "${REDIS_PATH}/bin/"
sudo cp src/redis-benchmark "${REDIS_PATH}/bin/"
sudo chown -R "${REDIS_USER}:${REDIS_USER}" "${REDIS_PATH}/bin"
green "二进制文件替换完成"
blue "===== 5. 加固漏洞配置 ====="
if ! grep -q "^client-output-buffer-limit normal" "${REDIS_CONF}"; then
echo -e "\nclient-output-buffer-limit normal 512mb 256mb 60" >> "${REDIS_CONF}"
else
sudo sed -i 's/^client-output-buffer-limit normal.*/client-output-buffer-limit normal 512mb 256mb 60/' "${REDIS_CONF}"
fi
green "漏洞加固配置完成"
blue "===== 6. 热重启Redis ====="
# 适配非6379端口的命令执行
${REDIS_PATH}/bin/redis-cli -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" BGREWRITEAOF >/dev/null 2>&1
sleep 2
${REDIS_PATH}/bin/redis-cli -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" SHUTDOWN NOSAVE >/dev/null 2>&1
# 启动新版(配置文件已指定端口,无需额外传参)
sudo -u "${REDIS_USER}" "${REDIS_PATH}/bin/redis-server" "${REDIS_CONF}"
sleep 3
blue "===== 7. 验证升级结果 ====="
CURRENT_VERSION=$("${REDIS_PATH}/bin/redis-server" --version | awk '{print $3}' | cut -d'=' -f2 | cut -d'.' -f1-3)
if [ "${CURRENT_VERSION}" = "${TARGET_VERSION}" ]; then
green "版本验证通过:Redis ${TARGET_VERSION}"
else
red "版本升级失败!当前:${CURRENT_VERSION}"
# 回滚时适配端口
sudo -u "${REDIS_USER}" "${REDIS_PATH}/bin/redis-cli" -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" SHUTDOWN NOSAVE >/dev/null 2>&1
sudo rm -rf "${REDIS_PATH}/bin/redis-server" "${REDIS_PATH}/bin/redis-sentinel"
sudo mv "${REDIS_PATH}/bin/redis-server.old" "${REDIS_PATH}/bin/redis-server"
sudo mv "${REDIS_PATH}/bin/redis-sentinel.old" "${REDIS_PATH}/bin/redis-sentinel"
sudo -u "${REDIS_USER}" "${REDIS_PATH}/bin/redis-server" "${REDIS_CONF}"
green "已回滚至升级前版本"
exit 1
fi
# 验证端口服务可用性
if ${REDIS_PATH}/bin/redis-cli -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" PING | grep -q "PONG"; then
green "${REDIS_PORT} 端口服务验证通过"
else
red "${REDIS_PORT} 端口服务启动失败!"
exit 1
fi
blue "===== 8. 清理临时文件 ====="
sudo rm -rf /tmp/redis-${TARGET_VERSION} /tmp/redis-${TARGET_VERSION}.tar.gz
sudo rm -f "${REDIS_PATH}/bin/redis-server.old" "${REDIS_PATH}/bin/redis-sentinel.old"
green "Redis ${TARGET_VERSION}(${REDIS_PORT}端口)升级完成!"
end