从配置加固到
漏洞防御的完整实践
Redis 的默认配置为开发便利而生,而非为生产安全而设。本文系统梳理六大核心防御维度,结合 2025 年最新披露的高危漏洞 CVE-2025-49844(CVSS 10.0),为你提供一套可落地的安全加固方案。
为什么 Redis 安全问题如此普遍?
Redis 的安全问题几乎从不起源于黑客的精密攻击——它们起源于假设。团队假设 Redis 只在内部使用,网络是可信的,或者没有人会直接连接 Redis。这些假设在初期或许成立,但随着系统增长、网络变化和部署复杂化,它们往往会悄然失效。
当 Redis 被攻陷时,影响从来都不轻微:数据消失、内存异常飙升、服务器被劫持用于挖矿,或整个数据集被清空。而在大多数情况下,根本原因并非复杂的 0day 漏洞,而是早期被忽视的基础安全卫生。
Redis 不会保护自己,除非你明确配置安全控制。— Redis Security Best Practices, 2025
今年最值得关注的两个 CVE
在深入最佳实践之前,先了解两个 2025 年披露的真实漏洞——它们直接影响你的修复优先级。
经认证用户可通过精心构造的 Lua 脚本操控垃圾回收器,触发 use-after-free(UAF)内存损坏,进而实现远程代码执行。该漏洞在源码中潜伏长达 13 年,可能影响高达 75% 的云环境。
当 Redis 启用密码认证但客户端未提供密码时,持续触发"NOAUTH"响应可导致输出缓冲区无限增长,最终耗尽系统内存。需要 Redis 端口可从公网访问才能被利用。
CVE-2025-49844 临时缓解方案
无法立即升级时,通过 ACL 禁止普通用户执行 Lua 脚本:
# 禁止应用用户执行 Lua 相关命令 ACL SETUSER appuser ~* &* +@all -EVAL -EVALSHA -EVALSHA_RO -EVAL_RO # 验证生效 ACL LIST ACL WHOAMI
六层纵深防御体系
没有任何单一措施能解决所有问题。以下六层防御组合在一起,可以将攻击者的成本提高到大多数机会性攻击无法承受的程度。
这是最重要的一条规则。Redis 应始终运行在私有网络中,访问权限仅限于真正需要它的应用服务器。网络隔离是第一道也是最强的防线——如果 Redis 可公网访问,其他所有保护措施都会退居次位。
# 仅监听本地回环和内网 IP,禁止 0.0.0.0 bind 127.0.0.1 10.0.0.5 # 保护模式默认开启,请勿关闭 protected-mode yes
# 只允许应用服务器子网访问 Redis 端口 iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 6379 -j DROP iptables-save > /etc/iptables/rules.v4
默认情况下,Redis 不要求密码即可连接。ACL 是 Redis 6.0 引入的重磅安全特性,支持细粒度的权限控制:每个用户可以分配不同的命令权限、Key 访问范围和 Channel 权限。
# 禁用默认 default 用户(强烈建议) ACL SETUSER default off # 只读用户:仅能读取 cache: 前缀的 key ACL SETUSER readonly_user on >ReadOnlyPass123 \ ~cache:* &* +GET +MGET +HGET +HGETALL +LRANGE +ZRANGE # 应用用户:读写权限,禁止危险命令 ACL SETUSER app_user on >AppPass456 \ ~* &* +@all -@dangerous -CONFIG -DEBUG -SHUTDOWN -FLUSHALL -FLUSHDB # 管理员:完整权限 ACL SETUSER admin_user on >AdminPass789 ~* &* +@all # 持久化 ACL 规则 ACL SAVE
ACL 权限速查
明文传输意味着任何网络中间人都可以嗅探 Redis 通信内容,包括认证密码和所有数据。Redis 6.0+ 原生支持 TLS。
openssl genrsa -out redis.key 2048 openssl req -new -x509 -days 365 -key redis.key -out redis.crt \ -subj "/CN=redis-server/O=MyOrg" openssl dhparam -out redis.dh 2048
port 0 # 禁用明文端口 tls-port 6379 tls-cert-file /etc/redis/redis.crt tls-key-file /etc/redis/redis.key tls-dh-params-file /etc/redis/redis.dh tls-ca-cert-file /etc/redis/ca.crt tls-auth-clients yes # 强制客户端证书 (mTLS) tls-protocols "TLSv1.2 TLSv1.3" tls-prefer-server-ciphers yes
import redis, ssl r = redis.Redis( host='10.0.0.5', port=6379, ssl=True, ssl_certfile='/path/to/client.crt', ssl_keyfile='/path/to/client.key', ssl_ca_certs='/path/to/ca.crt', ssl_cert_reqs=ssl.CERT_REQUIRED ) r.ping() # 验证 TLS 连接
某些 Redis 命令在误用或被攻击者利用时危害极大。FLUSHALL 可以一次性清空所有数据,CONFIG 可以在运行时修改服务器配置,EVAL 则是 RediShell 漏洞的攻击入口。
# 彻底禁用(rename 为空字符串) rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command DEBUG "" rename-command CONFIG "" rename-command SHUTDOWN "" # 重命名为随机字符串(内部运维仍可用) rename-command KEYS "KEYS_a8f3b2c1d9e7" rename-command MONITOR "MONITOR_x5k2m9n4p7q1" # 禁用调试接口 enable-debug-command no
rename-command 在 Redis Cluster 模式下不适用,请改用 ACL -CONFIG -DEBUG -FLUSHALL 实现命令限制。# AOF 持久化(推荐生产环境) appendonly yes appendfsync everysec # 每秒同步,平衡性能与安全 # RDB 快照 save 900 1 save 300 10 save 60 10000 # 数据目录 dir /var/lib/redis dbfilename dump.rdb
from cryptography.fernet import Fernet import redis # 密钥安全存储到 Vault / AWS KMS key = Fernet.generate_key() cipher = Fernet(key) r = redis.Redis(host='localhost', port=6379) # 写入时加密 encrypted = cipher.encrypt(b"sensitive user data") r.set('user:42:secret', encrypted) # 读取时解密 decrypted = cipher.decrypt(r.get('user:42:secret'))
安全不只是配置,还需要持续监控。当攻击者进入内网后,行为指标往往比签名更早发出警报。
# 拒绝的连接(可能是暴力破解) redis-cli INFO stats | grep rejected_connections # 异常命令统计 redis-cli INFO commandstats | grep -E "flushall|config|debug|eval" # 慢日志(超过 10ms 的命令) redis-cli SLOWLOG GET 10 # 内存使用 redis-cli INFO memory | grep used_memory_human
groups: - name: redis_security rules: - alert: RedisRejectedConnections expr: increase(redis_rejected_connections_total[5m]) > 10 annotations: summary: "Redis 拒绝连接异常,可能存在暴力破解" - alert: RedisFlushAllDetected expr: increase(redis_commands_total{cmd="flushall"}[1m]) > 0 annotations: summary: "检测到 FLUSHALL,立即排查" - alert: RedisHighMemoryUsage expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9 annotations: summary: "Redis 内存使用率超过 90%"
安全加固对照表
逐项确认你的 Redis 实例是否达标,每个维度都是独立的防御层。
- Redis 未绑定
0.0.0.0,仅监听内网 IP - 防火墙 / 安全组限制只有应用服务器可访问 6379
- Redis 部署在私有子网,无公网入口
protected-mode yes已启用
- 已启用强密码认证(
requirepass或 ACL) default用户已禁用或降权- 不同角色使用不同 ACL 用户
- 密码存储在 Secret Manager,而非代码或配置
- 已启用 TLS,禁用明文 6379 端口
- 启用客户端证书认证(mTLS)
- TLS 版本限制为 1.2 及以上
FLUSHALL / FLUSHDB / DEBUG已禁用CONFIG命令已通过 ACL 限制管理员- Lua 脚本权限已通过 ACL 限制(EVAL)
- Redis 以非 root 用户运行
- 启用 AOF 持久化,
appendfsync everysec - 数据目录权限
750,文件权限640 - 敏感数据实现客户端加密或磁盘加密
- Redis 版本 ≥ 8.2.2(修复 CVE-2025-49844)
- 已配置慢日志监控
- Prometheus 告警:拒绝连接 + 危险命令
- 定期安全审计(建议每季度一次)
把安全当作工程实践,而非一次性任务
大多数 Redis 安全事件是机会性的而非针对性的。六层防御体系的核心逻辑是纵深防御:即便某一层被突破,其他层仍能提供保护。
及时打补丁永远是最高优先级。CVE-2025-49844 的教训再次证明:一个潜伏 13 年的漏洞,在被披露后只需数天就会被大规模利用。保持版本更新,是所有安全措施中 ROI 最高的一项。


