Skip to content

总结

在服务器上使用 Redis 作为阿里云 OSS 对象存储的本地缓存,最初为了偷懒,直接采用了与开发环境相同的 Docker 启动命令以保证环境一致,却为后续被攻击埋下了隐患:

  1. 开发环境未设置 Redis 密码和主从复制密码(这是大忌)。
  2. 直接启动的 Redis 容器允许 SLAVEOF 等敏感操作,未做更多限制。
  3. 启动 Docker 容器时将 6379 端口对外开放,面板防火墙和 ECS 安全组均未限制端口入站流量。

可以说,整个配置漏洞百出,简直漏成了筛子(笑)。


排查过程

最初发现问题是因为后端传输图片流时经常过一段时间崩溃。通过排查后端接口报错发现:当 Redis 缓存未命中时,从 OSS 拉取图片后无法写入 Redis 缓存,导致接口返回 image not found。当时天真地以为 Redis 挂掉了,查看面板日志时发现有大量的主从复制同步失败记录。

但遗憾的是,当时并未想到可能是攻击行为,而是单纯认为是 Redis 容器配置问题或内存不足导致隔段时间被切换为从节点(其实看到日志中出现的未知 IP 47.121.222.122 就应该怀疑被攻击了)。由于该 IP 请求频率极高,且问题难以复现,前两次都简单粗暴地重启容器,Redis 恢复为主节点后就以为修复了,因此没有保留现场,也懒得去分析后来被刷爆的 26M、16 万行的日志(捂脸笑)。

后来发现 Redis 被错误设置为从节点后,想着在启动命令里明确指定 Redis 作为主节点运行,结果过了两天又被设置为从节点(无奈)。

最终在 4 月 27 日,图片流再次加载失败,正好刷到一个网安攻击视频,这才开始往攻击方面怀疑。通过完整日志搜索 SLAVEOF 关键字,定位了攻击者通过主从复制进行攻击的行为,同时抓到了两个疯狂扫描端口和尝试 HTTP 连接 Redis 的美国 IP。不过 Redis 直接禁用了 HTTP 请求,所有攻击请求因主从复制失败而未能实现后续恶意行为。由于容器化的隔离兜底,除了图片加载失败外,并未造成更大的影响。


排查思路

其实对任何问题的排查思路都是一致的:先看状态确认错误原因,再看日志找具体原因。这里顺便回顾一下一些常用的 Redis 命令:

  1. 连接 Redis
    bash
    redis-cli -a <password>
  2. 查看状态
    bash
    INFO
    查看指定主从复制状态:
    bash
    INFO replication

应对策略

首当其冲的就是不要偷懒,直接用命令启动容器,应该编写 docker-compose.yml 文件,这样更加灵活,也方便后续修改容器启动流程。

其次,设置 Redis 密码、连接主节点的密码,并禁用敏感的主从切换操作:

yaml
command: ["redis-server", "--requirepass", "password", "--rename-command", "SLAVEOF", "", "--masterauth", "password"]

最后,通过安全组和防火墙禁掉 6379 端口,避免暴露在外网环境中。

Redis 主从复制

(待更)