redis不支持订阅级ip白名单,必须在网络层(如安全组、iptables)或代理层实现;bind仅控制连接入口,无法限制已连接客户端的subscribe行为,真正有效的ip限制需前移至tcp握手阶段。

Redis 本身不支持基于客户端 IP 的订阅白名单机制,所谓“客户端白名单限制”必须在 Redis 外围实现——要么靠网络层(防火墙/安全组),要么靠代理层(如 Envoy、HAProxy),Redis 内置的 bind 只能限制「谁可以连上来」,不能区分「连上来之后能不能 SUBSCRIBE」。
为什么不能在 redis.conf 里配「只允许某 IP 订阅」
Redis 没有 subscribe-whitelist 这类配置项,bind 控制的是 TCP 连接入口,不是命令级权限。一旦连接建立,所有已认证客户端(无论 IP)都能执行 SUBSCRIBE,服务端不做来源判断。试图用 client list + 定时 CLIENT KILL 做事后清理,既滞后又不可靠——恶意连接可能在被 kill 前已拖垮输出缓冲区。
真正有效的客户端 IP 白名单只能落在网络层
必须把限制前移到 TCP 握手阶段,让非法 IP 根本连不上 6379 端口:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 云环境优先用安全组:只放行应用服务器、监控节点等可信 CIDR,禁止 0.0.0.0/0
- 物理机或 Docker 环境用
iptables或nftables:iptables -A INPUT -p tcp --dport 6379 -s 10.0.1.5 -j ACCEPT iptables -A INPUT -p tcp --dport 6379 -s 10.0.1.6 -j ACCEPT iptables -A INPUT -p tcp --dport 6379 -j DROP
- 如果 Redis 跑在 Kubernetes 中,用 NetworkPolicy 限制
ingress流量来源 Pod Label - 切勿依赖
bind 127.0.0.1后再加反向代理——代理转发后源 IP 会变成 127.0.0.1,白名单失效
替代方案:用代理层做订阅级鉴权
若业务强依赖「按 IP 控制订阅行为」,需引入轻量代理(非 Redis 自身能力):
- HAProxy 可基于
tcp-request content解析 Redis 协议前几个字节,匹配SUBSCRIBE命令并结合src_ip拒绝;但需注意 Redis 协议是纯文本且无固定长度头,解析稳定性差 - 更稳妥的是自研 TCP 代理:在 accept 后读取完整命令,校验
src_ip和频道名正则(如拒绝tmp_*),再决定是否透传给 Redis - 所有代理必须禁用
PSUBSCRIBE——它比SUBSCRIBE更难解析,且支持通配符,攻击面更大
别忽略 bind 和 requirepass 的配合陷阱
单独设 bind 或单独设 requirepass 都不保险:
-
bind 10.0.1.5但没设requirepass→ 内网任意机器连上就能乱 publish - 设了
requirepass但bind是空或0.0.0.0→ 密码可能被爆破或泄露后全网可连 - 正确姿势:
bind 10.0.1.5+requirepass your_strong_password+rename-command SUBSCRIBE ""三者缺一不可 - 如果业务真需要订阅,改用封装好的 SDK,由 SDK 在建立连接后先调用内部鉴权接口(查 Redis Set 白名单),再发
SUBSCRIBE
最易被忽略的一点:即使网络层封死了 IP,只要有一个合法客户端被入侵,攻击者就能用它的连接复用身份发起恶意订阅——所以 client-output-buffer-limit pubsub 仍要调得激进,且必须禁用 notify-keyspace-events,否则内部事件频道就是绕过白名单的后门。










