Redis里FLUSHALL、KEYS这些命令在生产环境绝对不能乱用,一个误操作就可能清空整个数据库。直接解决方案是:在redis.conf里用rename-command把危险命令改成随机字符串或者直接禁用,同时必须启用Redis 6.0以上的ACL功能,给每个应用创建专属账号并只分配最小必要权限。
Redis危险命令清单与禁用方法
最需要警惕的命令包括FLUSHALL/FLUSHDB(清空数据)、KEYS(阻塞式查询)、CONFIG(修改配置)、SHUTDOWN(关闭服务)、DEBUG(调试命令)。禁用方法是在redis.conf配置文件中添加rename-command指令。例如要彻底禁用FLUSHALL命令,可以这样配置:
rename-command FLUSHALL "" rename-command KEYS "" rename-command CONFIG "" rename-command SHUTDOWN ""
如果团队某些成员仍需在特定情况下使用这些命令,可以采用重命名方式:
rename-command FLUSHALL "9f8c7d6e5a4b3c2d1" rename-command KEYS "a1b2c3d4e5f67890"
这样只有知道这些随机字符串的人才能执行对应操作。配置完成后需要重启Redis服务或通过CONFIG REWRITE命令动态加载。注意:禁用CONFIG命令前,必须先完成所有必要的配置调整,否则后续将无法修改配置。
Redis ACL访问控制详细配置
Redis 6.0引入的ACL系统提供了用户级别的权限控制。每个用户有独立的用户名、密码和权限规则。查看当前ACL列表可以使用ACL LIST命令:
> ACL LIST 1) "user default on nopass ~* &* +@all" 2) "user appuser on >mypassword ~app:* -@all +get +set"
创建新用户的基本语法是ACL SETUSER。例如创建一个只能操作特定键前缀的只读用户:
ACL SETUSER reporter on >reportpass ~reports:* -@all +get +hget +hmget
这个reporter用户只能访问以"reports:"开头的键,并且只能执行GET、HGET、HMGET这几个读取命令。权限规则中~表示键模式,+表示允许命令,-表示禁止命令,@代表命令类别。
按业务场景设计ACL权限组
实际生产中应该按业务角色设计权限组。缓存服务账号通常只需要基础读写权限:
ACL SETUSER cache-service on >cachepass123 ~cache:* -@all +set +get +del +exists +expire
队列处理账号需要列表操作权限:
ACL SETUSER queue-worker on >queuepass ~queue:* -@all +lpush +rpop +llen +lrange
监控账号只需要信息查询权限:
ACL SETUSER monitor on >monitorpass ~* -@all +info +client +slowlog +memory
管理员账号可以拥有完整权限但限制操作范围:
ACL SETUSER admin on >adminpass ~* &* +@all -DEBUG -SHUTDOWN
注意每个账号都应该遵循最小权限原则,即使是管理员也应该禁用DEBUG、SHUTDOWN等危险命令。
ACL规则中的命令类别控制
Redis将命令分为多个类别,使用@符号可以批量控制。常用类别包括:
@keyspace - 键操作相关(DEL, EXISTS, EXPIRE等) @read - 只读命令(GET, LRANGE, SMEMBERS等) @write - 写入命令(SET, LPUSH, SADD等) @admin - 管理命令(CONFIG, ACL, SAVE等) @dangerous - 危险命令(FLUSHALL, KEYS, DEBUG等) @all - 所有命令
例如要给一个用户所有读取权限但禁止写入,可以这样配置:
ACL SETUSER readonly on >readpass ~* -@all +@read
如果要允许除了危险命令外的所有操作:
ACL SETUSER normaluser on >userpass ~* -@all +@all -@dangerous
这种分类控制大大简化了权限管理,特别是在需要批量调整权限时非常高效。
持久化ACL配置与备份策略
通过ACL命令设置的权限默认只保存在内存中,重启后会丢失。有三种持久化方式:第一种是在redis.conf中直接定义用户:
user appuser on >hashedpassword ~app:* -@all +get +set
第二种是通过ACL SAVE命令将当前ACL规则保存到ACL文件中:
> ACL SAVE OK
第三种是在配置文件中指定aclfile路径:
aclfile /etc/redis/users.acl
ACL文件采用明文存储,应该设置严格的文件权限(chmod 600),定期备份这个文件到安全位置。当团队有人员变动或业务调整时,要及时更新ACL配置并重新加载。
危险命令监控与审计日志
即使禁用了危险命令,也需要监控尝试执行这些命令的行为。在redis.conf中开启命令监控:
monitor-threshold 1000 # 监控执行时间超过1000ms的命令 slowlog-log-slower-than 10000 # 记录执行超过10ms的命令
通过SLOWLOG GET可以查看慢查询记录,其中可能包含危险操作尝试。更完善的方案是使用Redis的键空间通知功能,监控关键操作:
config set notify-keyspace-events A # 监控所有事件
对于生产环境,建议部署专门的Redis审计工具,记录所有敏感操作到日志系统,并与告警平台集成。当检测到多次权限拒绝或危险命令尝试时,立即发送告警通知运维人员。
多维度防御策略组合
单一防护措施往往不够,需要多层次防御:第一层是网络隔离,Redis只监听内网IP,使用防火墙限制访问来源;第二层是命令重命名,禁用或重命名核心危险命令;第三层是ACL控制,为每个服务创建最小权限账号;第四层是操作审计,记录所有敏感操作日志。
对于容器化部署环境,还需要额外注意:在Kubernetes中可以使用NetworkPolicy限制Pod访问,通过Sidecar代理进行命令过滤,在CI/CD流程中加入ACL配置检查。云托管Redis服务通常提供更细粒度的IAM权限控制,可以结合使用。
定期进行安全审计也很重要,每月至少检查一次ACL配置,查看是否有闲置账号、权限是否过度分配、密码强度是否足够。同时建立变更管理流程,任何ACL修改都需要经过申请、审批、执行、验证四个步骤。
迁移与兼容性注意事项
从旧版本Redis迁移到ACL系统时,需要特别注意兼容性问题。首先评估现有应用使用的命令范围,然后分阶段迁移:第一阶段先启用ACL但只创建监控账号;第二阶段为新建业务配置ACL账号;第三阶段逐步迁移存量业务。
对于客户端连接,需要更新连接字符串或配置。例如Java Jedis客户端:
JedisPool jedisPool = new JedisPool(new JedisPoolConfig(),
"redis-host", 6379, 2000, "newpassword", 0, "appuser");迁移过程中要保留一个过渡期,同时支持密码认证和ACL认证,确保业务平稳过渡。测试环境应该先于生产环境启用ACL,充分验证各种场景下的兼容性。
综合来看,Redis安全不是单点工作而是系统工程。命令禁用是基础防线,ACL访问控制是核心机制,网络隔离、操作审计、定期检查构成完整防护体系。随着Redis 7.0对ACL功能的进一步增强,现在正是全面升级安全策略的最佳时机。实施这些措施后,即使发生凭证泄露,攻击者能造成的破坏也将被限制在最小范围内。
