Redis默认配置下如果直接暴露在公网,攻击者无需密码就能通过6379端口执行FLUSHALL清空数据,甚至利用CONFIG SET指令写入SSH公钥或计划任务实现服务器提权。实际攻防案例中,一台未设置密码的Redis从上线到被扫描器发现平均只需要十几分钟。要解决这个问题,核心手段就是启用密码认证,并配合访问控制策略把Redis的暴露面收敛到最小。
Redis的密码认证依赖requirepass参数。打开redis.conf,找到requirepass所在行,取消注释并设置一个高强度密码。密码不要使用纯数字或常见单词,建议长度超过32位,混合大小写字母、数字和特殊符号。修改后重启Redis服务,客户端连接后必须执行AUTH命令才能操作数据。例如:
# redis.conf requirepass "Xk9#mP2$vL7@qR4&nT8^wB5!cF6*hJ3"
命令行连接时使用redis-cli -a参数传入密码,或者连接后执行AUTH password。需要注意的是,-a方式会让密码出现在进程列表和shell历史记录中,生产环境更推荐在连接后手动执行AUTH,或者使用REDISCLI_AUTH环境变量。如果使用Jedis、Lettuce等客户端,连接池配置中必须显式设置密码,否则连接建立后第一个命令就会返回NOAUTH Authentication required错误。
密码认证的局限与风险
requirepass只是第一道防线,它解决的是“谁能连进来”的问题,但无法解决“连进来的人能做什么”。Redis的密码是全局唯一的,没有用户分级概念,任何知道密码的客户端都能执行所有命令,包括CONFIG、FLUSHALL、SHUTDOWN等危险操作。此外,Redis的密码以明文形式存储在配置文件中,如果服务器被攻破,密码直接泄露。更隐蔽的风险在于,Redis的AUTH命令本身没有防暴力破解机制,攻击者可以无限次尝试密码,因此高强度密码是必须的。
还有一个容易被忽略的点:Redis主从复制架构中,从节点同样需要配置masterauth参数,否则主从同步会因为认证失败而中断。如果主节点设置了requirepass,从节点的masterauth必须与主节点密码一致,否则从节点会不断重连并报错。哨兵模式下,哨兵配置中的sentinel auth-pass也需要同步设置,否则哨兵无法完成故障转移。
绑定地址与端口隔离
密码认证之外,最直接的访问控制就是把Redis绑定到内网地址。默认配置中bind 127.0.0.1只允许本机访问,但很多运维为了方便会改成0.0.0.0,这等于把Redis暴露给所有网卡。如果Redis只服务于本机应用,保持127.0.0.1即可;如果有多台内网服务器需要访问,绑定内网IP,例如bind 10.0.0.5。不要同时绑定公网IP和内网IP,除非有明确需求并且已经做好防火墙规则。
# redis.conf bind 10.0.0.5 127.0.0.1 protected-mode yes
protected-mode是Redis 3.2之后引入的保护机制,当Redis没有设置密码且没有绑定具体IP时,protected-mode会拒绝外部连接。但protected-mode不能替代密码,它只是在配置错误时提供一个兜底保护。生产环境应该同时启用密码和protected-mode。
命令禁用与重命名
即使有密码,也应该对高危命令进行限制。Redis的rename-command指令可以把危险命令重命名为随机字符串,或者直接禁用。例如:
# redis.conf rename-command CONFIG "CONFIG_9f3k2m" rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command SHUTDOWN "" rename-command DEBUG ""
将FLUSHALL和FLUSHDB重命名为空字符串表示禁用这两个命令,任何客户端都无法执行。CONFIG命令重命名后,只有知道新名字的人才能调用,这可以防止攻击者通过CONFIG SET修改配置或写入文件。但要注意,重命名命令会影响一些运维工具和监控脚本,需要在安全性和便利性之间权衡。另外,Redis的ACL功能从6.0版本开始引入,可以更精细地控制用户权限,这是比rename-command更优雅的方案。
ACL细粒度权限控制
Redis 6.0之前的密码认证是“一码通”,所有客户端权限相同。Redis 6.0引入ACL(Access Control List)后,可以创建多个用户,每个用户有独立的密码、可执行的命令和可访问的键。ACL配置文件通常放在独立的users.acl文件中,通过aclfile参数加载。例如:
# users.acl user default off user appuser on >app_password ~cache:* +get +set +del +exists +expire user admin on >admin_password allcommands allkeys
上面的配置禁用了默认用户,创建了appuser和admin两个用户。appuser只能操作cache:开头的键,并且只能执行get、set、del、exists、expire五个命令;admin拥有全部权限。客户端连接后使用AUTH username password进行认证。ACL的优势在于,即使某个应用的密码泄露,攻击者也只能在受限的键空间和命令范围内活动,无法执行CONFIG、FLUSHALL等危险操作。
ACL还支持命令分类授权,例如+@read表示允许所有读命令,+@write表示允许所有写命令,+@admin表示允许管理命令。对于需要运行Redis Sentinel或Redis Cluster的环境,ACL可以精确控制每个节点和客户端的权限,避免因为一个密码泄露导致整个集群被控制。
网络层防火墙与TLS加密
Redis本身不提供IP白名单功能,网络层的访问控制需要依赖防火墙。在Linux服务器上,可以使用iptables或firewalld限制6379端口的来源IP。例如只允许10.0.0.0/24网段访问:
# iptables iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 6379 -j DROP
如果Redis部署在云服务器上,还应该在云安全组中限制6379端口的入方向规则,只放行内网IP段。多层防护可以最大程度减少暴露面。
对于跨机房或跨地域的Redis访问,密码和命令在网络上明文传输存在被嗅探的风险。Redis 6.0开始支持TLS加密,配置tls-port和tls-cert-file等参数后,客户端可以通过TLS连接Redis,防止密码和数据在传输过程中被窃取。TLS会带来一定的性能开销,但对于公网传输场景,这是必要的安全措施。
定期审计与监控
安全配置不是一劳永逸的。定期检查Redis的配置文件是否被意外修改,确认requirepass、bind、protected-mode、rename-command等关键参数符合预期。使用CONFIG GET requirepass和CONFIG GET bind命令可以查看当前运行时的配置,但要注意CONFIG命令本身可能已经被重命名或禁用。
监控方面,关注Redis的慢查询日志和客户端连接列表。CLIENT LIST命令可以查看所有连接的客户端IP、认证状态和最后执行的命令。如果发现来自陌生IP的连接,或者某个客户端频繁执行AUTH失败,应该立即排查。Redis的日志文件中也会记录认证失败事件,配合日志分析工具可以及时发现暴力破解行为。
对于使用Redis Cluster的环境,每个节点的配置都需要保持一致的安全策略。集群节点之间的通信端口(默认16379)同样需要防火墙保护,不要暴露到公网。集群模式下,节点间的认证通过requirepass和masterauth实现,但ACL在集群中的支持从Redis 6.0开始逐步完善,需要根据具体版本确认。
Redis密码认证和访问权限管控是一个多层防御体系。requirepass解决基本认证,bind和防火墙解决网络暴露,rename-command和ACL解决权限最小化,TLS解决传输加密,监控审计解决持续安全。单独启用其中任何一项都不足以保证安全,只有组合使用才能有效降低Redis被攻击的风险。对于生产环境,建议至少做到:高强度密码、绑定内网IP、禁用高危命令、启用ACL、配置防火墙规则,并定期检查配置和连接情况。
