Redis未授权访问漏洞,本质上是因为Redis服务绑定了公网地址且没有设置密码认证,导致攻击者可以直接连接并执行任意命令。修复的核心思路只有三条:要么让Redis只监听内网,要么设置强密码,要么在Redis前面加一层网络访问控制。但实际生产环境中,光做到其中一条往往不够,需要组合方案才能真正堵死风险。

立即止血:通过命令行临时设置密码

如果你发现一台正在运行的Redis实例存在未授权访问,最快的方法是直接通过redis-cli连上去,动态设置一个临时密码,避免继续被利用。执行以下命令:

redis-cli -h 127.0.0.1 -p 6379
CONFIG SET requirepass "你的强密码"

这条命令会立即生效,但不会持久化到配置文件。也就是说,Redis重启后密码就会失效,所以这只是应急手段,不能替代正式的配置修改。设置完成后,再次连接就需要AUTH认证了:

redis-cli -h 127.0.0.1 -p 6379 -a "你的强密码"

注意,用-a参数在命令行中直接带密码存在泄露风险,因为Linux系统下其他用户可以通过ps命令看到进程参数。更安全的方式是进入交互模式后再用AUTH指令认证。

永久修复:修改Redis配置文件

治本的方法是在redis.conf配置文件中做三处关键修改。第一处是绑定地址,找到bind配置项,将其设置为内网IP或127.0.0.1,绝对不要绑定0.0.0.0。如果你的业务确实需要对外提供服务,至少要把bind精确指定为业务需要的IP,而不是全零监听。配置示例:

bind 127.0.0.1 192.168.1.100

第二处是设置访问密码,找到requirepass配置项,取消注释并设置一个高强度密码。密码长度建议超过20位,包含大小写字母、数字和特殊字符,避免使用字典单词。配置示例:

requirepass R3d1s_Secure_P@ssw0rd_2024

第三处是禁用危险命令。Redis有一些命令在攻击场景中特别危险,比如CONFIG、FLUSHALL、FLUSHDB、KEYS、DEBUG等。可以通过rename-command将这些命令重命名为只有管理员才知道的随机字符串,或者直接禁用。配置示例:

rename-command CONFIG b8f7c3d9e2a1_CONFIG
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command DEBUG ""

将命令重命名为空字符串表示彻底禁用该命令。对于CONFIG这种偶尔需要使用的命令,可以改成复杂名称,自己需要时用新名称调用。修改完配置文件后重启Redis服务使配置生效。

网络层防护:iptables或安全组策略

即便Redis自身配置了密码,也不应该直接暴露在公网上。最稳妥的做法是在网络层做访问控制,只允许信任的IP地址访问Redis端口。如果你使用的是云服务器,优先在安全组中配置规则,只放行业务服务器的内网IP访问6379端口,拒绝所有其他来源。如果是物理服务器或虚拟机,可以使用iptables设置防火墙规则:

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

这两条规则的含义是:先允许192.168.1.0/24网段的TCP访问6379端口,然后丢弃其他所有来源的请求。注意规则的顺序很重要,iptables是按顺序匹配的。设置完成后记得保存iptables规则,否则服务器重启后会丢失。

最小权限原则:以非root用户运行Redis

很多运维人员习惯直接用root账户启动Redis,这是一个非常危险的做法。一旦攻击者通过Redis漏洞获得了命令执行权限,就等于直接拿到了服务器的root权限。正确的做法是创建一个专门的系统用户来运行Redis服务,该用户只拥有Redis工作目录的读写权限,对其他系统目录没有任何权限。操作步骤大致如下:

groupadd redis
useradd -g redis -s /sbin/nologin -M redis
chown -R redis:redis /var/lib/redis
chown -R redis:redis /var/log/redis

然后在Redis的systemd服务文件或启动脚本中指定以redis用户身份运行。这样即使Redis被攻破,攻击者也只能在redis用户的权限范围内活动,无法直接修改系统文件或安装后门程序。

隐藏Redis版本信息

攻击者在扫描到Redis端口后,通常会先用INFO命令获取服务器版本信息,然后针对特定版本寻找已知漏洞。虽然隐藏版本信息不是根本性的安全措施,但可以增加攻击者的探测成本。在redis.conf中有一项配置可以修改或隐藏版本号:

redis_version_override "6.0.0"

这个配置只在Redis 7.0及以上版本中可用。如果你使用的是较低版本,可以考虑在Redis前面加一层代理,由代理拦截并修改INFO命令的返回内容。不过要清楚,这只是障眼法,不能替代密码和网络隔离。

开启保护模式

Redis从3.2版本开始引入了保护模式(protected-mode),默认是开启的。保护模式的逻辑是:如果Redis没有设置密码,并且绑定的是公网地址,那么它会拒绝来自非回环接口的外部连接。但很多运维人员在部署时会顺手关掉这个选项,因为觉得“影响调试”。实际上,保护模式是一个很好的兜底机制,不应该被关闭。检查redis.conf中的配置:

protected-mode yes

确认这一行没有被改成no。保护模式虽然不能替代密码,但可以在配置疏漏时提供一层额外的保护。

定期审计与监控

安全配置不是一劳永逸的。Redis的访问日志、慢查询日志以及系统层面的网络连接日志,都应该纳入日常监控范围。重点关注异常的连接来源、高频的AUTH失败记录、以及危险命令的执行情况。可以在Redis中使用ACL功能(6.0以上版本支持)为不同业务创建不同权限的用户,限制每个用户可执行的命令和可访问的键空间。ACL配置示例:

ACL SETUSER app_user on >app_password ~app:* +@all -@dangerous

这条规则创建了一个名为app_user的用户,密码为app_password,只能访问以app:为前缀的键,可以使用所有命令但排除了危险命令类别。通过细粒度的权限控制,即使某个业务的凭证泄露,也不会波及整个Redis实例。

处理已感染服务器

如果你的Redis服务器已经被入侵,修复配置只是第一步。攻击者很可能已经在服务器上留下了后门,比如写入SSH公钥、植入定时任务、或者在crontab中添加恶意脚本。检查以下位置:

cat ~/.ssh/authorized_keys
crontab -l
cat /var/spool/cron/root
cat /etc/crontab

重点关注不明来源的SSH公钥和异常的定时任务条目。同时检查/var/lib/redis目录下是否有以.so结尾的可疑动态链接库文件,攻击者可能通过Redis的模块加载功能植入恶意模块。如果发现服务器已被深度入侵,最保险的做法是备份业务数据后重装系统,因为root权限下的后门可能隐藏得很深。

总结修复清单

把以上措施整理成一份可执行的检查清单:第一,bind地址设置为内网IP或127.0.0.1;第二,requirepass设置20位以上强密码;第三,rename-command禁用或重命名危险命令;第四,安全组或iptables限制来源IP;第五,以非root用户运行Redis;第六,确保protected-mode开启;第七,启用ACL进行细粒度权限控制;第八,检查并清除服务器上的入侵残留。这八条全部落实,Redis未授权访问的风险基本可以降到零。安全加固不是一次性工作,随着Redis版本更新和业务变化,需要定期复查这些配置是否依然有效。