redis的publish命令默认不落盘、不审计、不回调,无法通过redis.conf配置直接捕获发布行为;必须通过代理层或封装sdk收口发布请求,在中间层同步记录含时间戳、channel、消息摘要、来源ip等字段的审计日志。

Redis Publish命令本身不记录日志,必须拦截
Redis 的 PUBLISH 命令是纯内存操作,服务端默认不落盘、不审计、不回调。你无法通过配置项(如 redis.conf 中的 slowlog 或 auditlog)直接捕获谁在什么时间发了什么消息到哪个 channel。想做审计,唯一可行路径是把发布行为“收口”到可控的中间层——不能让客户端直连 Redis 执行 PUBLISH。
用代理层或 SDK 封装强制走审计逻辑
推荐两种落地方式,按团队基础设施成熟度选:
- 若已有统一网关或 Redis 代理(如 Redis-Proxy、Twemproxy 改造版),可在代理层解析 RESP 协议,识别出
PUBLISH请求后,先写入审计日志(如 Kafka / MySQL / ES),再透传给后端 Redis。注意:需处理 pipeline 和 multi-bulk 场景,避免误判PUBLISH参数位置 - 更轻量且可控的方式是强制所有业务使用封装后的 SDK(如 Python 的
redis_audited包)。核心是重载publish()方法:def publish(self, channel, message): self._log_audit("PUBLISH", channel=channel, message=message, caller=getframeinfo(currentframe().f_back)) return super().publish(channel, message)关键点:日志必须同步落盘(避免异步丢日志),且message若为二进制或大对象,建议只存摘要(sha256(message)[:8])和长度,否则审计库易成瓶颈
订阅端无法被审计,但可反向约束发布端
Redis 的 SUBSCRIBE 是长连接、无状态、服务端不记录订阅者身份。你无法知道谁在监听 news:topic。因此审计重点只能放在“谁有权限发”,而非“谁在收”。实操建议:
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 在中间层校验
channel命名规范(如强制前缀audited:),非合规 channel 直接拒绝PUBLISH - 结合业务身份(如 JWT 中的
service_id)生成审计字段,写入日志时带上user_id、app_name、ip(从 SDK 上下文或代理 header 获取) - 不要试图在 Redis 内用
KEYS subscribed:*扫描——性能差且不准,SUBSCRIBE不产生 key
审计日志格式与存储要兼顾查询和合规要求
一条有效审计日志至少包含:timestamp、channel、message_size、message_hash、publisher_ip、publisher_app、trace_id(用于链路追踪对齐)。存储选型注意:
- MySQL:适合按时间+channel 查最近 7 天操作,但高并发写入需分表;避免存原始
message字段,防拖慢主库 - Elasticsearch:适合运营查“某 app 连续发了哪些敏感词”,但要注意
message_hash字段设为keyword类型,否则无法精确 match - 别忽略时钟一致性:Redis 实例、代理、审计存储三端时间差超过 1s,会导致“先发后记”类排查困难
真正难的不是记录动作,而是确保每条 PUBLISH 都经过这个链路——任何绕过中间层的直连,都会让整套审计失效。上线前务必用 redis-cli --rdb 抓包或在测试环境禁用原生 redis-server 端口验证兜底效果。










