Redis 生产安全指南:ACL 权限、TLS 加密与审计日志

Redis 安全加固:ACL 权限体系、密码认证、SSL/TLS 加密、命令重命名与禁用、审计日志与 CVE 修复

Redis 以高性能著称,但默认配置在生产环境中存在显著安全缺口:无认证、明文传输、无访问隔离。本文从威胁模型出发,系统讲解密码认证、ACL 权限体系、TLS 加密、网络加固、命令重命名、审计日志与 CVE 修复,帮助你构建一套可落地的 Redis 生产安全基线。


一、Redis 安全威胁模型:默认无认证风险

1.1 默认配置的危险性

Redis 默认配置存在以下安全隐患:

  • 无认证要求:默认 requirepass 为空,无需密码即可连接
  • 监听所有接口:默认 bind 0.0.0.0,可从任意网络位置访问
  • 明文传输:通信数据未加密,可被网络嗅探截获
  • 无权限隔离:所有客户端拥有全部命令执行权限
  • 危险命令开放FLUSHALLCONFIGDEBUG 等命令可直接执行

1.2 常见攻击向量

+-------------------------------------------------------------+
|                    Redis 攻击向量                           |
+-------------------------------------------------------------+
| 1. 未授权访问 -> 直接连接6379端口,读写/删除所有数据          |
| 2. 命令注入   -> 通过 Redis 写入恶意 SSH 公钥或 WebShell     |
| 3. 网络嗅探   -> 抓取明文传输的数据包获取敏感信息             |
| 4. 内部横向   -> 拿到一台服务器权限后扫描内网 Redis 实例      |
| 5. 配置篡改   -> 修改持久化路径实现任意文件写入               |
| 6. 拒绝服务   -> FLUSHALL / KEYS * / DEBUG SEGFAULT         |
+-------------------------------------------------------------+

1.3 安全加固三原则

  1. 最小权限:每个应用/服务使用独立用户,只授予必要命令权限
  2. 传输加密:所有跨网络通信必须启用 TLS/SSL
  3. 纵深防御:网络层(防火墙/VPC)+ 应用层(ACL/密码)+ 审计层(日志)多管齐下

二、密码认证:requirepass / masterauth

Redis 提供了最基本的密码认证机制,适用于 Redis 6.0 之前的单用户场景,或与 ACL 搭配作为兜底方案。

2.1 设置访问密码

redis.conf 中配置:

# 设置服务器连接密码
requirepass "MyStr0ngP@ssw0rd!2026"

# 如果该实例是副本,配置主库认证密码
masterauth "MyStr0ngP@ssw0rd!2026"

注意:requirepass 设置后,所有客户端必须使用 AUTH password 登录,否则只能执行少数几个命令(AUTH、HELLO、PING、QUIT)。

2.2 动态修改密码

# 在线修改密码(立即生效,不重启)
redis-cli AUTH MyStr0ngP@ssw0rd!2026
redis-cli CONFIG SET requirepass "NewStr0ngP@ssw0rd!2026"

# 同步修改副本的 masterauth
redis-cli CONFIG SET masterauth "NewStr0ngP@ssw0rd!2026"

# 确保写入配置文件持久化
redis-cli CONFIG REWRITE

2.3 密码强度建议

  • 长度至少 32 个字符
  • 混合大小写字母、数字与特殊符号
  • 使用密码管理器生成随机密码
  • 定期轮换(建议 90 天一次)
  • 禁止硬编码在代码中,使用环境变量或密钥管理服务

三、ACL(Redis 6.0+):用户创建、权限位 +command/-command/@category

ACL(Access Control List)是 Redis 6.0 引入的多用户权限体系,替代了单一的 requirepass,支持用户隔离、细粒度命令控制和 Key 前缀匹配。

3.1 ACL 核心概念

概念说明
User独立账号,拥有自己的密码和权限
Permission允许(+command)或拒绝(-command)特定命令
Category命令分类(@read@write@admin 等),批量授权
SelectorKey 模式匹配(~pattern),限制可访问的 Key
ChannelPub/Sub 频道权限(&pattern

3.2 查看与理解默认用户

# 列出所有用户
redis-cli ACL LIST

# 典型输出:
# user default on nopass ~* &* +@all
# user app_backend on #e3b0c44298... ~app:* +@read +@write ~* -@dangerous

字段解析:

  • user default:用户名
  • on:账号启用(off 为禁用)
  • nopass:无需密码(应修改为有密码)
  • ~*:允许访问所有 Key
  • &*:允许订阅所有频道
  • +@all:允许执行所有命令

3.3 创建与管理用户

# 1. 重置默认用户,移除 nopass
redis-cli ACL SETUSER default on >'MyStr0ngP@ssw0rd!2026' ~* +@all

# 2. 创建只读应用用户(只能读 app: 前缀的 Key)
redis-cli ACL SETUSER app_reader on >'ReaderP@ss123' ~app:* resetchannels +@read

# 3. 创建读写应用用户
redis-cli ACL SETUSER app_writer on >'WriterP@ss456' ~app:* resetchannels +@read +@write

# 4. 创建缓存用户(仅字符串操作)
redis-cli ACL SETUSER cache_user on >'CacheP@ss789' ~cache:* resetchannels +get +set +del +expire +ttl +mget +mset

# 5. 创建队列用户(仅限 List/Stream 操作)
redis-cli ACL SETUSER queue_user on >'QueueP@ss000' ~queue:* resetchannels +@list +@stream

# 6. 创建哨兵用户(仅监控相关命令)
redis-cli ACL SETUSER sentinel_user on >'Sentine1P@ss' +@sentinel +ping +info +role +config|get

# 7. 禁用用户
redis-cli ACL SETUSER old_app off

# 8. 删除用户
redis-cli ACL DELUSER old_app

3.4 权限位与分类详解

常用命令分类(+@category):

# 查看所有分类及命令数
redis-cli ACL CAT

# 查看某个分类包含的命令
redis-cli ACL CAT read
redis-cli ACL CAT write
redis-cli ACL CAT admin
redis-cli ACL CAT dangerous
redis-cli ACL CAT fast

关键分类说明:

分类用途
@read只读命令:GET、HGET、LRANGE、ZRANGE 等
@write写命令:SET、HSET、LPUSH、ZADD 等
@keyspaceKey 管理:DEL、EXPIRE、RENAME、TYPE 等
@admin管理命令:ACL、CONFIG、CLIENT、SLOWLOG 等
@dangerous高危命令:FLUSHALL、FLUSHDB、KEYS、DEBUG、SHUTDOWN 等
@fast时间复杂度 O(1) 的快速命令
@slow可能阻塞服务器的慢命令
@connection连接命令:AUTH、PING、SELECT、QUIT 等
@pubsub发布订阅:SUBSCRIBE、PUBLISH、PSUBSCRIBE 等
@transaction事务命令:MULTI、EXEC、WATCH、DISCARD 等
@scriptingLua 脚本:EVAL、EVALSHA、SCRIPT 等
@sortedsetSorted Set 命令:ZADD、ZRANGE、ZREM 等
@listList 命令:LPUSH、RPOP、LRANGE、BLPOP 等
@hashHash 命令:HSET、HGET、HGETALL、HDEL 等
@setSet 命令:SADD、SREM、SMEMBERS、SISMEMBER 等
@stringString 命令:SET、GET、INCR、MSET 等
@bitmapBitmap 命令:SETBIT、GETBIT、BITCOUNT 等
@hyperloglogHyperLogLog 命令:PFADD、PFCOUNT 等
@geoGEO 命令:GEOADD、GEORADIUS 等
@streamStream 命令:XADD、XREAD、XGROUP 等
@sentinelSentinel 专用命令

3.5 细粒度权限控制

# 允许所有读写,但禁用危险命令
redis-cli ACL SETUSER app_safe on >'SafeP@ss123' ~app:* +@all -@dangerous

# 允许读全部,写仅限特定前缀,禁用 CONFIG
redis-cli ACL SETUSER app_mixed on >'MixedP@ss456' +@read +@write ~app:* -config -config|set -config|get

# 仅允许字符串和 List 操作
redis-cli ACL SETUSER app_limited on >'LimitP@ss789' ~* +@string +@list -@all

# 允许特定命令的精确控制
redis-cli ACL SETUSER app_precise on >'PreciseP@ss' ~data:* +get +set +hget +hset +lpush +lrange +del +expire +ttl -@all

# 添加多个 Key 前缀模式
redis-cli ACL SETUSER app_multi on >'MultiP@ss' ~app:* ~session:* ~cache:* +@read +@write

# 使用 ALLKEYS 和 ALLCOMMANDS 简写
redis-cli ACL SETUSER admin_user on >'AdminP@ss123' allkeys allchannels +@all

3.6 Key 前缀权限的进阶用法

# 使用 %R 和 %W 前缀只读/只写模式(Redis 7.0+)
# 允许读取所有 app: 开头的 Key,但不能写入
redis-cli ACL SETUSER app_readonly on >'RO_P@ss123' %R~app:* +@read

# 允许写入,但不能读取某些敏感字段
redis-cli ACL SETUSER app_writeonly on >'WO_P@ss456' %W~app:* +@write

3.7 ACL 配置文件持久化

# 方式一:从 ACL 文件加载
# redis.conf 中配置
aclfile /etc/redis/users.acl

# users.acl 内容示例:
user default on #e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ~* &* +@all
user app_reader on >'ReaderP@ss123' ~app:* resetchannels +@read
user app_writer on >'WriterP@ss456' ~app:* resetchannels +@read +@write -@dangerous
user monitor on >'Monit0rP@ss' +info +ping +slowlog|get +memory|usage +client|list
user replication on >'Repl1caP@ss' +psync +replconf +ping
# 方式二:动态保存 ACL 到文件
redis-cli ACL SAVE

# 动态从文件加载
redis-cli ACL LOAD

# 将当前 ACL 生成配置文件格式输出
redis-cli ACL GENPASS 32
redis-cli ACL GETUSER app_writer

3.8 生产环境的 ACL 最佳实践

# 1. 先创建新用户测试
redis-cli ACL SETUSER test_user on >'TestP@ss' ~test:* +@read +@write

# 2. 使用 ACL DRYRUN 测试权限(Redis 7.0+)
redis-cli ACL DRYRUN app_writer SET app:key1 value1
# 返回 OK 表示允许

redis-cli ACL DRYRUN app_reader SET app:key1 value1
# 返回 (error) NOPERM 表示拒绝

# 3. 查看用户权限详情
redis-cli ACL GETUSER app_writer

# 4. 查看当前登录用户
redis-cli ACL WHOAMI

# 5. 密码哈希存储(更安全)
redis-cli ACL SETUSER app_hash on #d2d2d2d2... ~app:* +@read +@write
# 使用 # 后跟 SHA-256 哈希值代替明文密码

四、TLS/SSL 加密:tls-port / tls-cert-file、客户端证书

Redis 6.0 引入了对 TLS 的原生支持,允许在集群内部通信和客户端连接中启用加密传输,防止数据包被窃听或篡改。

4.1 TLS 配置基础

redis.conf 中配置 TLS 参数:

# === TLS 基础配置 ===

# 启用 TLS 端口(原端口可同时保留作为兼容入口)
tls-port 6380
port 6379

# 证书和私钥路径
tls-cert-file /etc/redis/certs/redis.crt
tls-key-file /etc/redis/certs/redis.key
tls-ca-cert-file /etc/redis/certs/ca.crt

# 客户端证书认证(双向 TLS,可选但推荐)
tls-auth-clients optional

# 仅允许 TLS 连接(禁用明文端口,生产推荐)
# port 0
tls-port 6379

# 允许的 TLS 协议版本
tls-protocols "TLSv1.2 TLSv1.3"

# 密码套件配置(偏好前向安全算法)
tls-ciphers DEFAULT:!MEDIUM

# 集群和副本通信启用 TLS
# cluster 模式
tls-cluster yes
tls-replication yes

# Sentinel 通信启用 TLS
# sentinel 需在各自配置中设置 tls-port

4.2 生成自签名证书(测试环境)

# 创建 CA 和服务器证书
mkdir -p /etc/redis/certs && cd /etc/redis/certs

# 1. 生成 CA 私钥和证书
openssl req -x509 -newkey rsa:4096 -keyout ca.key -out ca.crt \
  -sha256 -days 3650 -nodes \
  -subj "/CN=Redis CA/O=MyOrg"

# 2. 生成服务器私钥
openssl genrsa -out redis.key 4096

# 3. 创建证书签名请求(CSR)
openssl req -new -key redis.key -out redis.csr \
  -subj "/CN=redis.example.com/O=MyOrg"

# 4. 创建扩展配置(SAN 包含 IP 和域名)
cat > redis.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=@alt_names

[alt_names]
DNS.1=redis.example.com
DNS.2=*.redis.example.com
IP.1=127.0.0.1
IP.2=192.168.1.100
IP.3=10.0.0.5
EOF

# 5. 使用 CA 签发服务器证书
openssl x509 -req -in redis.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out redis.crt -days 365 -sha256 \
  -extfile redis.ext

# 6. 设置正确权限
chmod 600 redis.key ca.key
chmod 644 redis.crt ca.crt
chown -R redis:redis /etc/redis/certs

4.3 强制双向 TLS(mTLS)

# redis.conf - 要求所有客户端提供有效证书
tls-auth-clients yes

# 验证客户端证书中的 CN 或 SAN(需配合 Lua 或外部验证实现)
# 也可通过防火墙/代理做二级验证

4.4 客户端 TLS 连接

# redis-cli 使用 TLS 连接
redis-cli --tls \
  --cert ./client.crt \
  --key ./client.key \
  --cacert ./ca.crt \
  -h redis.example.com -p 6380 \
  AUTH app_writer WriterP@ss456

# Python 示例 (redis-py)
# pip install redis[ocsp]
"""
import redis

r = redis.Redis(
    host='redis.example.com',
    port=6380,
    ssl=True,
    ssl_certfile='./client.crt',
    ssl_keyfile='./client.key',
    ssl_ca_certs='./ca.crt',
    ssl_check_hostname=True,
    username='app_writer',
    password='WriterP@ss456'
)
r.ping()
"""

# Go 示例 (go-redis)
"""
import (
    "crypto/tls"
    "crypto/x509"
    "github.com/redis/go-redis/v9"
)

func NewRedisClient() *redis.ClusterClient {
    cert, _ := tls.LoadX509KeyPair("client.crt", "client.key")
    caCert, _ := os.ReadFile("ca.crt")
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    return redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: []string{"redis.example.com:6380"},
        TLSConfig: &tls.Config{
            Certificates: []tls.Certificate{cert},
            RootCAs:      caCertPool,
            ServerName:   "redis.example.com",
        },
        Username: "app_writer",
        Password: "WriterP@ss456",
    })
}
"""

4.5 仅启用 TLS(禁用明文端口)

# 完全禁用明文端口,只允许 TLS 通信
port 0
tls-port 6379

# 所有内部通信强制 TLS
tls-replication yes
tls-cluster yes

4.6 TLS 性能调优

# 使用硬件加速(需 OpenSSL 支持)
# 在 BIOS 中启用 AES-NI 指令集

# 连接池复用 TLS 会话
tls-session-caching yes
tls-session-cache-size 2048
tls-session-cache-timeout 300

# 长连接应用应启用连接池,避免频繁 TLS 握手开销

五、网络防护:bind / protected-mode / 防火墙

5.1 bind 地址限制

# 仅监听本地回环(单机本机访问场景)
bind 127.0.0.1 ::1

# 仅监听内网接口(应用与 Redis 同 VPC 场景)
bind 192.168.1.100 10.0.0.5

# 禁止公网暴露(永远不要监听 0.0.0.0 无限制)
# bind 0.0.0.0  # <- 危险!不要这样做

生产环境应将 Redis 部署在私有子网,仅允许应用服务器通过内网 IP 访问。

5.2 protected-mode(自动防护)

# 当 bind 未设置且未设置密码时,protected-mode 会自动拒绝外部连接
# 这是 Redis 3.2+ 的安全兜底机制
protected-mode yes

# 如果确认在安全网络中,可以关闭(但不建议)
# protected-mode no

5.3 防火墙规则

# iptables - 仅允许特定 IP 访问 Redis 端口
iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

# firewalld
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port protocol="tcp" port="6379" accept'
firewall-cmd --permanent --remove-service=redis  # 移除默认允许
firewall-cmd --reload

# UFW
ufw allow from 10.0.0.0/24 to any port 6379 proto tcp
ufw deny 6379

# 云安全组(AWS/阿里云/腾讯云示例规则)
# 入站规则:
# - 协议 TCP,端口 6379,来源 10.0.0.0/16(应用服务器子网)
# - 协议 TCP,端口 16379,来源 10.0.0.0/16(集群总线端口)
# - 拒绝所有其他来源

5.4 网络安全架构

+--------------------------------------------------+
|                   公网用户                        |
+--------------------------------------------------+
          |                                         
          v                                         
+--------------------------------------------------+
|              API 网关 / 负载均衡                   |
|              (WAF + DDoS 防护)                   |
+--------------------------------------------------+
          |                                         
          v                                         
+--------------------------------------------------+
|              应用服务器集群                        |
|         (Nginx + 业务服务 + 缓存层)               |
|                                                  |
|   +---------+  +---------+  +---------+          |
|   | App Svc |  | App Svc |  | App Svc |          |
|   +----+----+  +----+----+  +----+----+          |
|        |            |            |               |
|        +------------+------------+               |
|                     |                            |
|                     v(TLS/mTLS)                  |
|   +----------------------------------------+     |
|   |         Redis Cluster / Sentinel       |     |
|   |   (私有子网 + ACL + 防火墙 + 审计)    |     |
|   |                                        |     |
|   |  Node1   Node2   Node3   Node4   Node5 |     |
|   +----------------------------------------+     |
+--------------------------------------------------+

六、命令重命名与禁用:rename-command FLUSHDB ""

除了 ACL 之外,Redis 还提供了一种更底层的命令控制方式——rename-command,通过将危险命令重命名或置空来防止误操作或恶意执行。

6.1 禁用高危命令

# redis.conf - 将危险命令设为空字符串(完全禁用)
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command DEBUG ""
rename-command CONFIG ""
rename-command SHUTDOWN ""
rename-command BGREWRITEAOF ""
rename-command BGSAVE ""

注意:rename-command 必须放在配置文件末尾,且一旦禁用后所有客户端都无法调用原命令。

6.2 重命名为随机名称

# 将 CONFIG 重命名,只有知道新名称的管理员才能使用
rename-command CONFIG "a3b9f2e7d1c8x0w5v4q6"

# 将 SHUTDOWN 重命名
rename-command SHUTDOWN "z8k2m7n1p0o4i5u3y6t9"

使用时需要知道别名:

# 使用重命名后的命令
redis-cli a3b9f2e7d1c8x0w5v4q6 GET maxclients
redis-cli z8k2m7n1p0o4i5u3y6t9 NOSAVE

6.3 需要谨慎处理的命令

命令风险建议操作
FLUSHALL清空所有数据库数据禁用或重命名
FLUSHDB清空当前数据库禁用或重命名
KEYS *O(N) 扫描全库 Key,阻塞服务器禁用或重命名
DEBUG SEGFAULT触发崩溃,用于测试禁用
CONFIG SET/GET修改配置、查看敏感信息重命名为随机名
SHUTDOWN关闭服务器重命名
SAVE阻塞式 RDB 持久化重命名
BGSAVE后台 RDB 持久化按需保留或重命名
BGREWRITEAOFAOF 重写按需保留或重命名
SLAVEOF/REPLICAOF改变主从关系重命名
SYNC/PSYNC全量同步重命名
EVAL/EVALSHA执行任意 Lua 脚本限制或配合 ACL 控制
MODULE LOAD加载动态模块禁用

6.4 rename-command 与 ACL 的配合

# 推荐策略:双重防护
# 1. 先用 rename-command 将危险命令重命名
rename-command CONFIG "cfg_admin_7x9k2m"
rename-command FLUSHALL ""
rename-command KEYS ""

# 2. 再用 ACL 控制谁能使用重命名后的命令
# users.acl:
# user admin on >'AdminP@ss123' allkeys allchannels +@all +cfg_admin_7x9k2m
# user app_safe on >'SafeP@ss456' ~app:* +@all -@dangerous

rename-command 的优先级高于 ACL:即使 ACL 授予了命令权限,如果命令被 rename-command 禁用,客户端仍然无法执行。

6.5 模块扩展命令的防护

# 禁用 MODULE 命令防止加载未经验证的模块
rename-command MODULE ""

# 如果使用了 RedisSearch、RedisJSON 等模块,
# 可以通过 ACL 限制只有特定用户能使用模块命令
# user search_user on >'SearchP@ss' +ft.search +ft.info +ft.explain

七、审计日志:ACL LOG / MONITOR

安全加固后,持续的审计监控同样关键。Redis 提供了多种审计手段,帮助追踪异常访问和安全事件。

7.1 ACL LOG(Redis 6.0+)

ACL LOG 记录权限拒绝事件,是排查未授权访问的第一线工具。

# 查看最近的 ACL 拒绝日志
redis-cli ACL LOG

# 查看指定条数的日志(最多 128 条,默认可配置)
redis-cli ACL LOG 10

# 清空 ACL 日志
redis-cli ACL LOG RESET

典型输出解析:

# 1) 1) "entry"
#    2) 1) "count"
#       2) (integer) 5          # 该事件触发次数
#       3) "reason"
#       4) "command"
#       5) "context"
#       6) "toplevel"
#       7) "object"
#       8) "flushall"
#       9) "username"
#      10) "app_reader"
#      11) "age-seconds"
#      12) "12.345"
#      13) "client-info"
#      14) "id=7 addr=10.0.0.25:54321..."
#      15) "entry-id"
#      16) (integer) 42

字段含义:

  • count:同一事件的累计触发次数
  • reason:拒绝原因(command / key / channel / auth
  • object:被拒绝的命令/Key/频道名
  • username:触发拒绝的 ACL 用户名
  • client-info:客户端连接信息(IP、端口、连接 ID)

7.2 配置 ACL LOG 参数

# redis.conf
# ACL LOG 最大条目数(默认 128)
acllog-max-len 1000

# 当达到上限时,最旧的条目自动淘汰

7.3 ACL LOG 的自动化监控

# 将 ACL LOG 接入日志收集系统
#!/bin/bash
# acl-log-monitor.sh

while true; do
    LOGS=$(redis-cli --raw ACL LOG 1)
    if [ -n "$LOGS" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') ALERT: ACL Denial Detected"
        echo "$LOGS" | logger -t redis-acl-denial
        # 发送到企业微信/钉钉/飞书机器人
        # curl -X POST ....
    fi
    sleep 10
done
# Python 监控脚本
import redis
import json
import time

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

last_entry_id = 0

while True:
    logs = r.acl_log(count=10)
    for entry in logs:
        entry_id = entry.get('entry-id', 0)
        if entry_id > last_entry_id:
            print(f"[ALERT] ACL Denied: user={entry['username']} "
                  f"reason={entry['reason']} object={entry['object']} "
                  f"client={entry['client-info']}")
            # 发送到 SIEM 或告警系统
            last_entry_id = entry_id
    time.sleep(5)

7.4 MONITOR 命令(实时流量监控)

# 实时输出所有执行的命令(性能开销大,仅用于调试)
redis-cli MONITOR

# 输出示例:
# 1691881234.567890 [0 10.0.0.25:54321] "GET" "app:user:12345"
# 1691881234.568012 [0 10.0.0.25:54322] "HGETALL" "app:config:default"
# 1691881234.570123 [0 10.0.0.25:54321] "SET" "app:session:abc" "xxx" "EX" "3600"

警告:MONITOR 会显著降低 Redis 性能(可达 50%),且输出量巨大。仅应在以下场景短时使用:

  • 排查可疑命令执行
  • 调试应用与 Redis 的交互模式
  • 流量分析(需配合过滤脚本)
# MONITOR 的安全使用方法
# 1. 限制只有管理员能执行 MONITOR
redis-cli ACL SETUSER admin on >'AdminP@ss' allkeys +monitor +client|kill +client|list

# 2. 配合 timeout 限制监控时长
redis-cli --raw MONITOR | head -n 1000 > redis_monitor_$(date +%Y%m%d_%H%M%S).log

# 3. 过滤特定命令
redis-cli MONITOR | grep -E '"(FLUSHALL|CONFIG|DEBUG|KEYS)"'

7.5 SLOWLOG(慢查询日志)

# 查看慢查询日志(默认 >10ms)
redis-cli SLOWLOG GET 20

# 配置慢查询阈值(微秒)
redis-cli CONFIG SET slowlog-log-slower-than 5000  # 5ms
redis-cli CONFIG SET slowlog-max-len 1024

# 清空慢查询日志
redis-cli SLOWLOG RESET

慢查询日志字段:

  • id:日志唯一 ID
  • timestamp:执行时间(Unix 时间戳)
  • duration:执行耗时(微秒)
  • command:命令及参数数组
  • client:客户端地址和端口
  • name:客户端名称(如设置了 CLIENT SETNAME

7.6 持久化审计日志

# 将 Redis 日志重定向到文件,配合 rsyslog 转发
logfile /var/log/redis/redis-server.log
loglevel notice

# 系统日志集成
syslog-enabled yes
syslog-ident redis
syslog-facility local0
# rsyslog 配置 (/etc/rsyslog.d/50-redis.conf)
local0.* /var/log/redis/redis-audit.log

# logrotate 配置 (/etc/logrotate.d/redis)
/var/log/redis/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 redis redis
    sharedscripts
    postrotate
        /bin/kill -HUP $(cat /var/run/redis/redis-server.pid 2>/dev/null) >/dev/null 2>&1
    endscript
}

7.7 审计日志的 Elasticsearch 集成

# Filebeat 配置,将 Redis 日志发送到 Elasticsearch
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/redis/redis-server.log
    - /var/log/redis/redis-audit.log
  fields:
    service: redis
    environment: production
  fields_under_root: true

output.elasticsearch:
  hosts: ["https://es-cluster:9200"]
  index: "redis-audit-%{+yyyy.MM.dd}"

# Kibana 中创建可视化看板:
# - ACL 拒绝事件趋势图
# - 慢查询 Top 10
# - 命令分布饼图
# - 异常 IP 访问热力图

八、CVE 修复流程:版本升级策略

Redis 社区活跃,安全漏洞(CVE)的发现和修复节奏较快。建立标准化的漏洞响应流程是保障生产安全的重要环节。

8.1 主要 CVE 历史回顾

CVE 编号影响版本漏洞类型风险等级
CVE-2024-31228< 7.2.5, < 6.2.16ACL 绕过高危
CVE-2023-45145< 7.0.14整数溢出高危
CVE-2023-28856< 7.0.11拒绝服务中危
CVE-2023-25155< 7.0.9Lua 脚本越界读取高危
CVE-2023-22458< 7.0.8整数溢出高危
CVE-2022-35977< 7.0.8Lua 栈溢出中危
CVE-2022-31144< 7.0.4拒绝服务高危
CVE-2022-0543Debian/Ubuntu 包Lua 沙箱逃逸严重
CVE-2021-41099< 6.2.6, < 5.0.14整数溢出高危
CVE-2021-32761< 6.2.6拒绝服务中危
CVE-2020-14147< 6.0.6Lua 脚本整数溢出高危
CVE-2019-10192< 5.0.5堆缓冲区溢出高危
CVE-2018-11219< 4.0.11, < 5.0-rc6整数溢出高危
CVE-2015-8080< 3.0.4拒绝服务中危
CVE-2015-4335< 3.0.3拒绝服务中危
CVE-2013-7458< 2.6.17信息泄露低危

8.2 CVE 监控渠道

# 1. Redis 官方安全公告
# https://github.com/redis/redis/security/advisories

# 2. 邮件订阅
# 关注 Redis 官方 GitHub Releases 的 Watch -> Security alerts

# 3. NVD 国家漏洞数据库
# https://nvd.nist.gov/vuln/search/results?query=redis

# 4. 自动化漏洞扫描
# Clair、Trivy、Snyk、OpenVAS 等工具扫描 Redis 镜像与二进制

# 使用 Trivy 扫描
$ trivy image redis:7.2
$ trivy filesystem /usr/local/bin/redis-server

8.3 版本升级策略

版本策略矩阵:
+------------+------------+------------+------------+
|   环境     |   稳定版本  | 补丁周期   |  升级窗口  |
+------------+------------+------------+------------+
| 生产环境   | 最新稳定版减一 | 每 2 周   | 每月维护窗  |
| 预发布环境 | 最新稳定版    | 每周      | 按需       |
| 开发环境   | 最新版       | 随时      | 即时       |
+------------+------------+------------+------------+

升级流程:

# === 阶段一:测试验证 ===
# 1. 在测试环境部署新版本
docker run --rm -d --name redis-test redis:7.4.0 redis-server

# 2. 运行功能回归测试
redis-benchmark -h redis-test -p 6379 -n 100000 -c 50

# 3. 验证数据持久化兼容性
redis-cli SAVE
# 对比 RDB/AOF 文件是否正常

# 4. 验证主从复制正常
redis-cli INFO replication
# 确认 master_link_status:up

# === 阶段二:金丝雀发布 ===
# 5. 先升级一个副本节点
#    修改配置文件指向新版本二进制
#    重启该副本,观察复制状态

# === 阶段三:滚动升级 ===
# 6. Sentinel 模式下逐台升级副本
#    升级后 sentinel 自动发现新版本

# 7. Cluster 模式下一个节点一个节点升级
#    使用 redis-cli --cluster 管理节点替换

# === 阶段四:主库切换 ===
# 8. 手动故障转移将主库降级为副本
redis-cli SENTINEL failover mymaster

# 9. 升级原主库
# 10. 观察新主库稳定运行 24 小时

# === 阶段五:回滚预案 ===
# 11. 保留旧版本二进制和配置文件 7 天
# 12. 保留升级前 RDB 备份

8.4 热补丁(紧急 CVE 响应)

# 对于高危 CVE 需要紧急修复但无法立即重启时:

# 1. 使用 rename-command 临时禁用受影响命令
redis-cli CONFIG SET rename-command FLUSHALL ""
redis-cli CONFIG SET rename-command DEBUG ""
redis-cli CONFIG REWRITE

# 2. 通过防火墙限制访问
iptables -A INPUT -p tcp --dport 6379 -j DROP
# 仅允许白名单 IP
iptables -I INPUT -p tcp --dport 6379 -s 10.0.0.0/24 -j ACCEPT

# 3. 修改 ACL 降低暴露面
redis-cli ACL SETUSER default -@all +@read +ping +info

# 4. 启用审计,密切监控
# 开启 MONITOR(短时)或加强 ACL LOG 监控频率

8.5 版本生命周期

版本系列发布日期维护状态建议
Redis 7.42024-07活跃维护新环境首选
Redis 7.22023-08活跃维护生产推荐
Redis 7.02022-04仅安全补丁建议升级
Redis 6.22021-03仅安全补丁规划升级
Redis 6.02020-04终止维护必须升级
Redis 5.x2018-10终止维护必须升级
Redis 4.x2018-01终止维护必须升级
Redis 3.x2015-04终止维护必须升级

原则:终止维护版本遇到 CVE 将不再获得补丁,应尽快制定升级计划。


九、安全基线检查清单

以下检查清单涵盖 Redis 生产环境的所有安全维度,可用于上线前的安全检查或定期审计。

9.1 认证与授权

  • requirepass 已设置为强密码(32+ 字符,随机生成)
  • 已启用 ACL(Redis 6.0+),默认用户有密码且非 nopass
  • 为每个应用创建了独立的 ACL 用户,遵循最小权限原则
  • ACL 用户权限已使用 ACL DRYRUN 验证
  • 已禁用或删除不再使用的 ACL 用户
  • 密码未硬编码在代码中,使用环境变量/密钥管理(如 Vault)
  • 密码有定期轮换机制(90 天周期)
  • 主从复制的 masterauth 与主库密码一致

9.2 网络安全

  • bind 仅监听内网接口,未暴露 0.0.0.0
  • protected-mode 保持 yes
  • 防火墙/安全组仅允许白名单 IP 访问 Redis 端口
  • Redis 实例部署在私有子网,无公网路由
  • 集群总线端口(16379)同样受防火墙保护
  • Sentinel 通信端口(26379)仅限管理网段访问
  • VPC/子网间有网络 ACL 二次隔离

9.3 传输加密

  • 已启用 TLS(Redis 6.0+),tls-port 配置正确
  • 证书文件权限为 600(私钥)/644(公钥)
  • 证书由可信 CA 签发(自建 CA 或商业证书)
  • 证书包含正确的 SAN(IP + 域名)
  • tls-protocols 限制为 TLSv1.2+
  • 生产环境已禁用明文端口(port 0
  • 副本复制和集群通信已启用 tls-replication yes / tls-cluster yes
  • 客户端支持并正确配置 TLS CA 验证
  • 双向 TLS(mTLS)已启用(安全要求高的场景)

9.4 命令控制

  • FLUSHALLFLUSHDB 已通过 rename-command 禁用
  • KEYS 命令已禁用(使用 SCAN 替代)
  • DEBUG 命令已禁用
  • CONFIG 已重命名为随机字符串
  • SHUTDOWN 已重命名
  • Lua 脚本命令通过 ACL 做了限制(高危场景禁用 EVAL
  • MODULE 命令已禁用

9.5 持久化与数据安全

  • RDB/AOF 文件存储路径权限为 700
  • 备份文件加密存储或存放在加密磁盘上
  • 定期对 RDB 文件进行异地备份
  • AOF 文件开启启用 fsync 策略(appendfsync everysecalways
  • 备份保留策略明确,旧备份已安全销毁

9.6 审计与监控

  • ACL LOG 已启用,acllog-max-len 配置合理
  • 慢查询日志 slowlog-log-slower-than <= 10ms
  • Redis 日志已集中收集到日志系统(ELK/PLG/Loki)
  • 有 ACL 拒绝事件的实时告警机制
  • 每日/每周审查慢查询和异常访问日志
  • 监控 Redis 连接数突增、CPU/内存异常波动
  • MONITOR 使用有审批流程,不可常驻开启

9.7 CVE 与版本管理

  • 当前运行版本在官方维护期内
  • 已订阅 Redis 安全公告
  • 有自动化的漏洞扫描流程(Trivy/Clair)
  • 有书面的版本升级预案和回滚方案
  • 升级前在测试环境完成验证
  • 保留升级前 7 天的 RDB 备份

9.8 高可用与灾备

  • 主从复制已配置,副本可快速晋升
  • Sentinel / Cluster 模式已部署且监控正常
  • 有自动化故障切换脚本且经过演练
  • 跨可用区部署,单点故障不影响可用性
  • 最大客户端连接数 maxclients 已合理限制
  • 内存上限 maxmemory 已配置,驱逐策略已设定

结语

Redis 安全不是单一配置就能解决的问题,而是需要从网络层、认证层、传输层、命令层、审计层构建纵深防御体系。核心要点回顾:

  1. 先网络隔离bind 限制 + 防火墙白名单,确保 Redis 不暴露在外网
  2. 再身份认证:用 ACL 替代单一密码,按应用和用户粒度分配权限
  3. 加密传输:Redis 6.0+ 启用 TLS,跨网络通信全部加密
  4. 收缩攻击面rename-command 禁用或重命名高危命令
  5. 持续审计:ACL LOG + 慢查询 + 日志集中监控
  6. 漏洞管理:订阅安全公告,建立升级和应急响应流程

安全是一个持续的过程,而非一次性的配置。建议每季度使用本清单进行一次安全检查,确保配置未因运维变更而回退。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「database」更多文章

  1. 缓存架构演进之路:从单机 Redis 到亿级分布式多级缓存体系
  2. Redis 7.x 重大新特性与架构升级深度解析
  3. Redis 消息队列深度对比:Pub/Sub、Streams 与 Kafka/RabbitMQ 选型指南