强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Redis 完全指南 / 14 - 安全

安全

14.1 安全概述

Redis 默认配置不安全——无密码、绑定所有接口、暴露危险命令。生产环境必须加固。

安全检查清单

检查项说明优先级
设置密码requirepass / ACL🔴 高
绑定地址bind 127.0.0.1🔴 高
禁用危险命令rename-command🔴 高
开启 TLS加密传输🟡 中
使用 ACL细粒度权限控制🟡 中
禁用 CONFIG 命令防止运行时修改配置🟡 中
定期更新版本修复安全漏洞🟢 低

14.2 密码认证

单密码认证(Redis 6.0 之前)

# redis.conf
requirepass YourStr0ngP@ssword
# 方式一:连接时指定密码
redis-cli -a YourStr0ngP@ssword

# 方式二:连接后认证
redis-cli
AUTH YourStr0ngP@ssword

# 方式三:通过命令行参数
redis-cli --pass YourStr0ngP@ssword

⚠️ 安全警告:密码通过明文传输(除非使用 TLS)。在生产环境中,密码可能会出现在 ps 命令和日志中。

主从复制密码

# 从节点配置
masterauth YourStr0ngP@ssword

Sentinel 密码

# sentinel.conf
sentinel auth-pass mymaster YourStr0ngP@ssword

14.3 ACL(访问控制列表)

Redis 6.0 引入了 ACL 系统,支持细粒度的用户权限控制。

ACL 基本概念

┌──────────────────────────────────────┐
│            ACL 用户                   │
├──────────────────────────────────────┤
│ 用户名    │ unique string            │
│ 密码      │ ≥ 1 个密码               │
│ 命令权限  │ +GET +SET -FLUSHALL ...  │
│ Key 权限  │ ~user:* ~cache:*         │
│ Channel   │ &channel:*               │
│ 默认数据库 │ on >password ~* &*       │
└──────────────────────────────────────┘

ACL 命令

# 查看所有用户
ACL LIST
# 1) "user default on #<hash> ~* &* +@all"

# 查看当前用户
ACL WHOAMI

# 创建用户
ACL SETUSER appuser on >password123 ~user:* ~cache:* +@read +@write -@admin

# 创建只读用户
ACL SETUSER readonly on >readonly123 ~* +@read

# 创建管理员
ACL SETUSER admin on >admin123 ~* &* +@all

# 禁用用户
ACL SETUSER appuser off

# 删除用户
ACL DELUSER appuser

# 查看用户详情
ACL GETUSER appuser

# 保存 ACL 配置到文件
ACL SAVE

# 加载 ACL 配置
ACL LOAD

ACL 权限类别

类别包含的命令说明
@all所有命令全部权限
@readGET, LRANGE, HGET, …读命令
@writeSET, LPUSH, HSET, …写命令
@setSADD, SREM, SMEMBERS, …Set 操作
@sortedsetZADD, ZRANGE, ZSCORE, …ZSet 操作
@hashHSET, HGET, HGETALL, …Hash 操作
@listLPUSH, RPUSH, LRANGE, …List 操作
@stringSET, GET, APPEND, …String 操作
@adminACL, CONFIG, DEBUG, …管理命令
@dangerousFLUSHALL, FLUSHDB, DEBUG, KEYS危险命令
@connectionAUTH, PING, QUIT, …连接命令
@pubsubPUBLISH, SUBSCRIBE, …发布订阅
@scriptingEVAL, EVALSHA, …Lua 脚本
@geoGEOADD, GEODIST, …地理位置
@hyperloglogPFADD, PFCOUNT, …HyperLogLog
@streamXADD, XREAD, XREADGROUP, …Stream
@slowKEYS, SORT, …慢命令
@fastGET, SET, INCR, …快命令

ACL 配置文件

# acl.conf
user default on >YourStr0ngP@ssword ~* &* +@all
user app on >apppassword ~app:* +@read +@write -@admin -@dangerous
user readonly on >readpassword ~* +@read
user admin on >adminpassword ~* &* +@all
# 加载 ACL 文件
redis-server --aclfile /etc/redis/acl.conf

ACL 使用示例

# 应用程序用户(只能操作 app:* 前缀的 Key)
ACL SETUSER appuser on >apppass123 ~app:* +@read +@write -@admin -@dangerous

# 切换到 appuser
AUTH appuser apppass123

# ✅ 允许
SET app:config "value"
GET app:config
HSET app:user:1001 name "张三"

# ❌ 禁止(权限不足)
SET other:key "value"         # (error) NOPERM
FLUSHALL                      # (error) NOPERM
CONFIG SET maxmemory 4gb      # (error) NOPERM

14.4 rename-command(命令重命名)

Redis 6.0 之前常用的安全措施,通过重命名或禁用危险命令:

# redis.conf

# 禁用 FLUSHALL(设置为空字符串)
rename-command FLUSHALL ""

# 禁用 FLUSHDB
rename-command FLUSHDB ""

# 禁用 DEBUG
rename-command DEBUG ""

# 重命名 CONFIG(只有知道新名称的人才能执行)
rename-command CONFIG CONFIG_b7a2c4d8

# 重命名 KEYS
rename-command KEYS KEYS_b7a2c4d8

⚠️ 注意:Redis 6.0+ 推荐使用 ACL 替代 rename-command,更灵活、更安全。

14.5 TLS 加密

Redis 6.0 支持 TLS 加密传输。

生成证书

# 生成 CA 证书
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -out ca.crt -subj "/CN=Redis CA"

# 生成服务器证书
openssl genrsa -out redis-server.key 2048
openssl req -new -sha256 -key redis-server.key -out redis-server.csr -subj "/CN=redis-server"
openssl x509 -req -sha256 -in redis-server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out redis-server.crt -days 365

# 生成客户端证书
openssl genrsa -out redis-client.key 2048
openssl req -new -sha256 -key redis-client.key -out redis-client.csr -subj "/CN=redis-client"
openssl x509 -req -sha256 -in redis-client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out redis-client.crt -days 365

TLS 配置

# redis.conf

# TLS 端口
tls-port 6380

# 禁用非 TLS 端口
port 0

# 证书文件
tls-cert-file /etc/redis/tls/redis-server.crt
tls-key-file /etc/redis/tls/redis-server.key
tls-ca-cert-file /etc/redis/tls/ca.crt

# 客户端证书验证
tls-auth-clients yes

# 主从复制 TLS
tls-replication yes

# 集群总线 TLS
tls-cluster yes

TLS 连接

# 客户端 TLS 连接
redis-cli --tls \
  --cert /etc/redis/tls/redis-client.crt \
  --key /etc/redis/tls/redis-client.key \
  --cacert /etc/redis/tls/ca.crt \
  -p 6380

14.6 网络安全

绑定地址

# 只允许本地访问
bind 127.0.0.1 -::1

# 允许特定网段访问
bind 127.0.0.1 192.168.1.0/24

防火墙配置

# UFW (Ubuntu)
sudo ufw allow from 192.168.1.0/24 to any port 6379
sudo ufw allow from 192.168.1.0/24 to any port 26379  # Sentinel
sudo ufw allow from 192.168.1.0/24 to any port 16379  # Cluster bus

# firewalld (CentOS)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="6379" accept'
sudo firewall-cmd --reload

# iptables
sudo iptables -A INPUT -p tcp --dport 6379 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 6379 -j DROP

保护模式

# 当 bind 和 requirepass 都未设置时,保护模式会阻止外部访问
protected-mode yes

14.7 运行时安全加固

# 禁用 CONFIG 命令(重命名)
redis-cli CONFIG SET requirepass "new_strong_password"
# 或在配置文件中
rename-command CONFIG ""

# 限制客户端连接数
redis-cli CONFIG SET maxclients 1000

# 禁用危险命令
redis-cli ACL SETUSER default on >password ~* &* +@all -@dangerous

📌 业务场景

场景一:多租户权限隔离

# 租户 A 只能访问 tenant:a:* 前缀
ACL SETUSER tenant_a on >pass_a ~tenant:a:* +@read +@write -@admin

# 租户 B 只能访问 tenant:b:* 前缀
ACL SETUSER tenant_b on >pass_b ~tenant:b:* +@read +@write -@admin

场景二:运维只读权限

ACL SETUSER ops_readonly on >ops_pass ~* +@read +@slow +@admin -@dangerous

场景三:加密传输(跨机房)

# 使用 TLS 加密跨机房的主从复制和客户端连接

🔗 扩展阅读