1. Redis安全威胁全景
Redis 的设计初衷是“高性能内存数据结构服务器”,它默认假设运行在可信内网、由可信客户端访问。这个假设在今天的云原生、容器化和多租户环境中几乎不成立。理解 Redis 安全,第一步不是背命令,而是建立一张攻击面地图:攻击者从哪里进来、能做什么、会留下什么痕迹、最终能拿到什么。本节围绕默认配置风险、未授权访问、命令注入、数据泄露、持久化文件暴露五类常见攻击面,建立安全工程视角。
一、默认配置:Redis 的“出厂信任”
Redis 6.0 之前,默认配置几乎不设防:bind 127.0.0.1 只监听本地,但很多部署为了远程访问改成 bind 0.0.0.0;protected-mode yes 在 3.2 引入,用于在无密码且非本地绑定时拒绝外部连接,但一旦显式设置 protected-mode no 或配置了密码,这层保护就消失;requirepass 默认为空,意味着任何能连上 6379 端口的客户端都可以直接执行命令。更危险的是 CONFIG SET dir 与 CONFIG SET dbfilename 这类管理命令默认可用,攻击者可以改变持久化路径,把恶意内容写入任意可写目录。
从安全工程视角看,默认配置的风险不是“某个参数错了”,而是默认信任模型与真实部署环境错配。Redis 把“谁能连上端口”等同于“谁被授权”,而网络边界、容器网络、K8s Service 都可能让这个边界失效。
二、未授权访问:最常见的入口
未授权访问是 Redis 安全事件中出现频率最高的入口。典型场景是:Redis 监听 0.0.0.0:6379,未设置密码,防火墙或安全组放行了该端口。攻击者用 redis-cli -h <target> -p 6379 直接连接,执行 INFO 确认版本与角色,再用 CONFIG GET dir 探测可写目录。此时攻击者已经获得了一个“可执行任意 Redis 命令”的立足点。
需要强调的是,未授权访问本身不是终点,而是跳板。攻击者通常不会停留在读写键值,而是利用 Redis 的持久化、主从复制、模块加载等能力,把“命令执行”升级为“系统命令执行”或“文件写入”。
三、命令注入与持久化文件暴露:从数据面到系统面
Redis 的持久化机制是攻击链的关键放大器。RDB 文件由 SAVE 或 BGSAVE 生成,AOF 文件由 appendonly yes 开启后追加写入。攻击者可以通过 CONFIG SET dir /var/spool/cron 和 CONFIG SET dbfilename root,再写入一个包含换行与 cron 语法的键值,最后触发 SAVE,把 RDB 文件写到 cron 目录,实现计划任务注入。类似地,写入 SSH authorized_keys、Web 目录下的 webshell、或覆盖 /etc/ld.so.preload 都是常见变体。
另一条路径是主从复制:攻击者用 SLAVEOF 或 REPLICAOF 让目标 Redis 成为自己控制的“恶意主节点”的从节点,主节点通过 FULLRESYNC 把恶意 RDB 推送给目标,目标加载后即被植入。这条路径不依赖 CONFIG SET,在部分受限环境中依然可行。
命令注入的另一个维度是 Lua 脚本与模块。EVAL 默认可用,虽然 Lua 沙箱限制了文件与网络访问,但结合 redis.call 仍可放大影响;Redis 4.0 引入的模块机制若加载了不可信 .so,则直接获得原生代码执行能力。
四、数据泄露:不只是“读到键值”
数据泄露常被简化为“攻击者读到了数据”,但在 Redis 中泄露面更宽:KEYS * 与 SCAN 可枚举全部键名,键名本身可能包含用户 ID、订单号、手机号;GET、HGETALL、LRANGE 可读取值;INFO 会暴露版本、内存、连接数、主从拓扑;CLIENT LIST 会暴露客户端地址与名称;MONITOR 可实时抓取所有命令,等于拿到完整业务流量。若 Redis 被用作 Session 存储,攻击者还能直接伪造会话。
因此,数据泄露的评估不能只看“有没有密码”,还要看键命名规范、敏感数据是否加密、是否禁用高危命令、是否限制网络来源。
五、安全工程视角:把攻击面映射为控制点
把上述威胁放到一张图上,可以清晰看到“入口—能力—后果”的传导关系。下图以攻击者视角梳理 Redis 常见攻击面与对应控制点,帮助在工程中定位优先级。
六、一个可复用的检查清单
把上述攻击面转化为可执行的检查项,建议在每次上线或巡检时逐条确认。以下清单以“是否可被未授权利用”为判断标准,字段可直接用于工单或巡检表。
| 检查项 | 安全值示例 | 风险说明 |
|---|---|---|
| 监听地址 | bind 10.0.1.20 | 避免 0.0.0.0 暴露到公网 |
| protected-mode | yes | 无密码且非本地绑定时拒绝外部连接 |
| requirepass | ≥16 位随机口令 | 空密码等于无认证 |
| ACL 用户 | user app on >pass ~app:* +get +set | 按业务最小权限授权 |
| 高危命令 | rename-command CONFIG "" | 阻断 CONFIG SET 写文件路径 |
| 持久化目录 | dir /data/redis | 避免写入 cron、SSH、Web 目录 |
| 文件权限 | chmod 600 dump.rdb | 防止备份被其他进程读取 |
| 主从复制 | 仅允许可信主节点 | 防止恶意主节点推送 RDB |
| 网络访问 | 安全组仅放行应用网段 | 缩小未授权访问入口 |