Skip to content

Redis 认证与授权

Redis 提供了多种认证与授权机制,用于保护 Redis 实例免受未授权访问和滥用。合理配置认证与授权可以有效提高 Redis 的安全性。

密码认证

基本密码认证

Redis 支持简单的密码认证机制,可以通过配置文件或命令行设置密码。

配置文件设置密码

redis.conf 文件中设置密码:

txt
# 设置认证密码
requirepass your_strong_password

命令行设置密码

通过 CONFIG SET 命令动态设置密码:

bash
# 动态设置密码
redis-cli CONFIG SET requirepass your_strong_password

# 保存配置到文件
redis-cli CONFIG REWRITE

客户端认证

客户端连接 Redis 时需要提供密码:

bash
# 连接时指定密码
redis-cli -h host -p port -a your_strong_password

# 先连接,再认证
redis-cli -h host -p port
redis> AUTH your_strong_password

密码策略最佳实践

  1. 使用强密码

    • 密码长度至少 16 位
    • 包含大小写字母、数字和特殊字符
    • 避免使用常见密码或简单组合
  2. 定期更换密码

    • 建议每 3-6 个月更换一次密码
    • 使用密码管理工具存储和生成密码
  3. 不要硬编码密码

    • 避免在应用代码中硬编码 Redis 密码
    • 使用环境变量或配置文件管理密码

ACL 访问控制

Redis 6.0 引入了 ACL(Access Control List)功能,提供了更细粒度的访问控制。

ACL 基本概念

  • 用户:每个客户端连接可以关联一个用户
  • 密码:每个用户可以设置多个密码
  • 权限:控制用户可以执行哪些命令和访问哪些键
  • 频道权限:控制用户可以发布/订阅哪些频道

ACL 配置文件

redis.conf 文件中可以配置 ACL:

txt
# 启用 ACL 日志
acl-log-max-len 128

# 配置用户
user default off -@all +ping
user admin on #secret +@all
user appuser on #apppass +@read +@write -@admin

ACL 命令

创建和修改用户

bash
# 创建新用户
redis-cli ACL SETUSER appuser on >apppass +@read +@write -@admin

# 修改现有用户
redis-cli ACL SETUSER appuser +set +get

# 删除用户
redis-cli ACL DELUSER appuser

查看用户信息

bash
# 查看所有用户
redis-cli ACL LIST

# 查看特定用户
redis-cli ACL GETUSER appuser

# 查看当前用户
redis-cli ACL WHOAMI

测试权限

bash
# 测试用户是否有特定命令权限
redis-cli ACL DRYRUN appuser SET key value

ACL 权限分类

命令权限

  • +@all:允许所有命令
  • -@all:禁止所有命令
  • +@read:允许所有读命令
  • +@write:允许所有写命令
  • +@admin:允许所有管理命令
  • +@string:允许所有字符串命令
  • +@list:允许所有列表命令
  • +set:允许 SET 命令
  • -keys:禁止 KEYS 命令

键权限

bash
# 允许访问所有键
redis-cli ACL SETUSER appuser ~*

# 允许访问特定前缀的键
redis-cli ACL SETUSER appuser ~app:*

# 允许访问多个前缀的键
redis-cli ACL SETUSER appuser ~app:* ~cache:*

频道权限

bash
# 允许发布/订阅所有频道
redis-cli ACL SETUSER appuser &*

# 允许发布/订阅特定频道
redis-cli ACL SETUSER appuser &channel:*

命令权限管理

禁用危险命令

Redis 中有些命令可能会对系统造成严重影响,建议禁用或重命名:

配置文件中禁用命令

txt
# 禁用危险命令
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command DEL ""
rename-command CONFIG ""

# 重命名命令
rename-command FLUSHDB "private_flushdb"
rename-command FLUSHALL "private_flushall"

动态禁用命令

bash
# 动态禁用命令
redis-cli CONFIG SET rename-command FLUSHDB ""
redis-cli CONFIG SET rename-command FLUSHALL ""

# 保存配置到文件
redis-cli CONFIG REWRITE

命令权限最佳实践

  1. 最小权限原则

    • 只授予用户执行必要命令的权限
    • 禁止普通用户执行管理命令
  2. 禁用危险命令

    • 生产环境中禁用或重命名危险命令
    • 如 FLUSHDB、FLUSHALL、KEYS、DEL 等
  3. 定期审计权限

    • 定期检查用户权限配置
    • 移除不再需要的权限

密码管理

密码生成

使用强密码生成工具生成 Redis 密码:

bash
# 使用 openssl 生成强密码
openssl rand -base64 24

# 使用 pwgen 生成强密码
pwgen -s 24 1

密码存储

  • 不要硬编码密码:避免在应用代码或配置文件中明文存储密码
  • 使用环境变量:通过环境变量传递密码
  • 使用密码管理工具:如 HashiCorp Vault、AWS Secrets Manager 等
  • 加密存储:如果必须存储密码,使用加密方式存储

密码轮换

定期更换 Redis 密码是安全最佳实践:

  1. 准备新密码:生成新的强密码
  2. 设置双密码:Redis 6.0+ 支持同时设置多个密码
  3. 更新客户端:依次更新所有客户端使用新密码
  4. 移除旧密码:确保所有客户端都使用新密码后,移除旧密码

示例:

bash
# 设置新密码(保留旧密码)
redis-cli ACL SETUSER default on #oldpass #newpass

# 更新所有客户端使用新密码

# 移除旧密码
redis-cli ACL SETUSER default on #newpass

连接安全

限制绑定 IP

redis.conf 中限制 Redis 绑定的 IP 地址:

txt
# 只绑定到本地回环地址
bind 127.0.0.1

# 绑定到特定 IP 地址
bind 192.168.1.100

使用 SSL/TLS

Redis 6.0+ 支持 SSL/TLS 加密,可以加密客户端与 Redis 服务器之间的通信:

配置 SSL/TLS

txt
# 启用 SSL/TLS
tls-port 6380
tls-cert-file /path/to/cert.pem
tls-key-file /path/to/key.pem
tls-ca-cert-file /path/to/ca.pem

使用 SSL/TLS 连接

bash
# 使用 SSL/TLS 连接
redis-cli --tls -h host -p 6380 -a password

安全最佳实践

  1. 启用认证

    • 所有 Redis 实例都应启用认证机制
    • 使用强密码或 ACL 进行认证
  2. 最小权限原则

    • 只授予用户执行必要命令的权限
    • 禁止普通用户执行管理命令
  3. 禁用危险命令

    • 生产环境中禁用或重命名危险命令
    • 如 FLUSHDB、FLUSHALL、KEYS、DEL 等
  4. 限制网络访问

    • 限制 Redis 绑定的 IP 地址
    • 使用防火墙限制访问 Redis 端口
    • 生产环境中避免将 Redis 暴露在公网
  5. 使用 SSL/TLS

    • 启用 SSL/TLS 加密客户端与服务器之间的通信
    • 特别是在 Redis 实例部署在不同服务器或云环境中时
  6. 定期审计

    • 定期检查 Redis 配置和权限
    • 监控异常访问尝试
    • 定期更换密码
  7. 使用专用用户

    • 为 Redis 服务创建专用的系统用户
    • 限制该用户的系统权限
  8. 启用日志

    • 启用 Redis 日志记录
    • 监控认证失败和异常命令执行

常见问题(FAQ)

Q1: 忘记 Redis 密码怎么办?

A1: 如果忘记了 Redis 密码,可以通过以下步骤重置:

  1. 停止 Redis 服务
  2. 编辑 redis.conf 文件,注释或删除 requirepass 配置
  3. 重启 Redis 服务
  4. 使用 CONFIG SET 命令设置新密码
  5. 保存配置到文件
bash
# 停止 Redis 服务
systemctl stop redis

# 编辑配置文件,注释 requirepass 行
vi /etc/redis/redis.conf

# 重启 Redis 服务
systemctl start redis

# 设置新密码
redis-cli CONFIG SET requirepass new_strong_password

# 保存配置
redis-cli CONFIG REWRITE

Q2: Redis 6.0 之前的版本如何实现细粒度访问控制?

A2: Redis 6.0 之前的版本不支持 ACL,可以通过以下方式实现基本的访问控制:

  1. 使用密码认证
  2. 禁用或重命名危险命令
  3. 使用防火墙限制访问 IP
  4. 部署 Redis 在私有网络中
  5. 考虑使用 Redis 代理(如 Twemproxy、Codis)实现访问控制

Q3: 如何审计 Redis 用户的命令执行?

A3: 可以通过以下方式审计 Redis 用户的命令执行:

  1. 启用 Redis 日志,记录所有命令执行
  2. 使用 MONITOR 命令实时监控命令执行(生产环境慎用)
  3. 使用 Redis 6.0+ 的 ACL 日志功能
  4. 集成第三方监控工具,如 Prometheus + Grafana
  5. 使用 Redis 代理记录命令执行日志

Q4: 如何防止 Redis 密码泄露?

A4: 可以通过以下方式防止 Redis 密码泄露:

  1. 使用强密码,定期更换
  2. 不要在应用代码中硬编码密码
  3. 使用环境变量或配置文件管理密码
  4. 使用加密存储方式存储密码
  5. 限制 Redis 访问权限,只允许必要的 IP 访问
  6. 启用 SSL/TLS 加密通信
  7. 定期审计 Redis 配置和权限

Q5: 如何为多个应用配置不同的 Redis 访问权限?

A5: 使用 Redis 6.0+ 的 ACL 功能,可以为每个应用创建独立的用户,并配置不同的权限:

bash
# 为应用1创建用户,只允许读命令
redis-cli ACL SETUSER app1 on >app1pass ~app1:* +@read

# 为应用2创建用户,允许读写命令,但禁止管理命令
redis-cli ACL SETUSER app2 on >app2pass ~app2:* +@read +@write -@admin

# 为管理员创建用户,允许所有命令
redis-cli ACL SETUSER admin on >adminpass ~* +@all

Q6: Redis 认证会影响性能吗?

A6: Redis 认证对性能的影响非常小,因为认证只在连接建立时进行一次,不会影响后续的命令执行。

对于高并发场景,建议使用连接池管理 Redis 连接,避免频繁的认证开销。