欢迎光临
我们一直在努力

redis防御加固与安全基线

攻击 = 允许被网络访问 + 允许执行危险操作 + 操作落在危险位置。那防御就是三件事:

  • 网络层:不让他连得上(bind、防火墙、不要裸奔公网)。

  • 认证与授权层:就算连上,也要密码 / ACL 挡住危险命令。

  • 系统层:就算命令执行了,低权限用户 + 最小目录写权限,让他写不了能被执行的文件。


  • 1. 先看现状:现在的 Redis 有多裸?

    任何加固的第一步是盘点现状。管理员先自查:

    # 1) 谁在监听、监听在哪张网卡
    ss -tlnp | grep 6379        # 看是否 0.0.0.0 / *(公网)在听
    # 或
    netstat -an | grep 6379

    # 2) 关键配置现状
    redis-cli CONFIG GET bind
    redis-cli CONFIG GET protected-mode
    redis-cli CONFIG GET requirepass
    redis-cli CONFIG GET dir
    redis-cli INFO server | grep redis_version

    # 3) 当前用户/权限
    ps -ef | grep redis-server | grep -v grep   # redis 以什么用户跑?

    我怎么知道 Redis 是否暴露在公网?

    上面 ss 看监听地址:0.0.0.0:6379 或 *:6379 = 所有网卡都在听(含公网)。也可以从另一台机器 telnet 公网IP 6379 试连通性。安全工具如 shodan/fofa 能直接搜到全网暴露的 6379——那些基本都是被攻击重灾区。


    2. 网络层加固:让攻击者"连不上"

    2.1 bind:只监听需要的网卡

    # redis.conf 里
    # 只允许本机访问(最安全,开发/单机推荐)
    bind 127.0.0.1

    # 只允许内网特定 IP 访问(生产常用,按需改)
    bind 127.0.0.1 10.10.10.5

    # 千万别这样(监听所有网卡,等于暴露公网)
    # bind 0.0.0.0
    # 或注释掉 bind

    不写 bind 0.0.0.0 时,老版本默认可能监听所有网卡——所以显式写明 bind 是好习惯。

    2.2 protected-mode:兜底开关,务必保持 yes

    protected-mode yes

    protected-mode 只在"没设密码 + 非本机连接"时才拦。它是兜底不是万能。正确姿势:bind 收紧 + 设密码 + protected-mode yes 三者一起上,别只靠一个。

    2.3 防火墙 / 安全组

    即使 bind 失误,网络层还有最后一道闸:

    # 只允许信任网段访问 6379
    iptables -A INPUT -p tcp –dport 6379 -s 10.0.0.0/8 -j ACCEPT
    iptables -A INPUT -p tcp –dport 6379 -j DROP
    # 云上:安全组入方向不向 0.0.0.0/0 放行 6379


    3. 认证与授权:连上了也要拦

    3.1 requirepass:设置访问密码(最基础)

    Redis 6 之前只有这一种认证方式,所有客户端共用一个密码。

    # redis.conf
    requirepass 一个足够强、且不重复使用的密码

    验证:

    redis-cli -p 6379 ping
    # (error) NOAUTH Authentication required.   ← 没密码进不去,攻击断一条腿
    redis-cli -p 6379 -a 密码 ping
    # PONG

    设了 requirepass 之后,主从/哨兵之间也要配密码(masterauth),否则从库连不上主库——这属于运维细节,但漏配会导致复制失败告警。

    3.2 ACL:细粒度控制"谁能执行哪些命令"(Redis 6+,强烈推荐)

    requirepass 是"一刀切",ACL 才是现代 Redis 的正解:可以建多个用户,每个用户指定能访问哪些 key、执行哪些命令。

    ACL 基本模型:

    ACL SETUSER 用户名 规则…

    常用规则:

    规则含义
    on / off 启用 / 停用该用户
    >密码 设置密码
    ~pattern 允许访问匹配的 key(~* 所有;~cache:* 只 cache 前缀)
    +命令 / -命令 允许 / 禁止某命令
    +@类别 / -@类别 按类别批量放行/禁止(如 +@read -@admin)
    allkeys / allcommands 等价 ~* / +@all
    nopass 免密(default 用户默认 nopass,危险)

    创建一个只能读 cached:*、只能执行少量命令的只读用户(演示,真实按业务改):

    # 建用户:demo,密码 s3cretPwd,只能访问 cached:*,只允许 ping/get/set
    redis-cli -p 6379 ACL SETUSER demo on '>s3cretPwd' '~cached:*' '+ping' '+get' '+set'
    # 查看所有用户
    redis-cli -p 6379 ACL LIST
    # 输出示例:
    # user default on nopass sanitize-payload ~* &* +@all         ← 默认超级用户
    # user demo on sanitize-payload #hash… ~cached:* resetchannels -@all +get +set +ping

    用 demo 用户连:

    redis-cli -p 6379 –user demo -a s3cretPwd
    # 能 get cached:xxx、set cached:yyy、ping
    # 但不能 KEYS、不能 FLUSHALL、不能 CONFIG → 会被 (error) NOPERM 拒绝

    ACL 和 requirepass 能同时用吗?

    能。requirepass 本质是给 default 用户设密码。Redis 6+ 更推荐直接用 ACL 管理用户,可以保留 default 强密码,另建只读/最小权限用户给不同业务方。

     为什么 ACL 能防住攻击?

    前面所有 getshell,最后都依赖 CONFIG / BGSAVE / REPLICAOF / MODULE / EVAL 这类高危命令。用 ACL 把业务账号限制成只读 + 只碰业务 key,攻击者拿到这个账号也调不动任何危险命令。

    3.3 禁用/改名高危命令(无 ACL 的版本也能用)

    老版本没有 ACL,用 rename-command 把危险命令改名或直接禁用(只能写在 redis.conf 里,重启生效,CONFIG SET 改不了):

    # redis.conf
    # 把危险命令禁掉(改名成空字符串 = 禁用)
    rename-command CONFIG ""
    rename-command FLUSHALL ""
    rename-command FLUSHDB ""
    rename-command EVAL ""
    rename-command SCRIPT ""
    rename-command SHUTDOWN ""

    # 或改成只有你知道的暗名(如果业务确实要用)
    rename-command CONFIG "r3dis_c0nfig_9527"

    改名命令的坑:

  • 主从、哨兵、客户端里如果写了 CONFIG,改名后全都要跟着改,否则复制/运维脚本会挂;

  • rename-command 只在配置里生效,无法用 CONFIG SET 在线改;

  • 改名前先在测试环境验证业务兼容性。


  • 4. 系统层:就算命令执行了,也"写不了 / 干不了活"

    4.1 用低权限用户跑 Redis

    这是最容易被忽略、也最有效的一条。 Redis 若以 root 跑,写 crontab / SSH 公钥 / WebShell 全都有权限;用普通用户跑,那些系统目录根本写不进去。

    # 建一个无登录、最小权限的 redis 用户
    useradd -r -s /sbin/nologin redis
    mkdir -p /var/lib/redis /var/log/redis /etc/redis
    chown redis:redis /var/lib/redis /var/log/redis /etc/redis

    # redis.conf 里指定
    user redis

    # 或 systemd 单元里 User=redis

    为什么有些未授权 Redis 打不出 getshell?

    很多时候不是命令被禁,而是 Redis 跑在 redis 用户下,/root/.ssh、/var/spool/cron、web 目录它都没权限写——这正是低权限运行的防御价值。

    4.2 数据目录与落盘位置最小化

    • 给 Redis 一个独立且无执行权限的数据目录(如 /var/lib/redis),不要把 dir 指到 web 根目录。

    • 即使攻击者改了 dir,目录权限 + SELinux/AppArmor 也能二次拦截。

    • 定期检查 dir 里有没有异常文件(攻击者落盘的 shell.php 之类)。

    4.3 日志与监控

    • 开 Redis 日志(logfile),记录连接和命令。

    • 监控 6379 的连接来源、异常 KEYS * / CONFIG SET / FLUSHALL / REPLICAOF 命令。

    • 对外部发起的长时间连接、异常大流量保持警惕。


    5. 云上/容器部署的额外注意

    □ Docker:端口映射别裸开 6379(-p 6379:6379 且无密码 = 灾难);用 –network 内网或仅本机
    □ k8s:Redis 服务不要暴露成 NodePort/LoadBalancer 到公网
    □ 云托管 Redis(如云厂商):用安全组/VPC 隔离 + 开密码 + 开审计
    □ 公网示例默认账号/端口:第一时间改端口或至少加密码,别用默认 6379 裸奔


    6. 最小加固清单

    按顺序做,前三条性价比最高:

    # ===== redis.conf 最小安全配置 =====
    bind 127.0.0.1                       # 1. 不对外监听(或用内网IP)
    protected-mode yes                   # 2. 保护模式兜底
    requirepass 换成超强随机密码         # 3. 无密码 = 未授权访问(高危)

    # 4. 若有 ACL,给业务用最小权限用户(可选但推荐)
    # 5. 禁用/改名危险命令(老版本)
    rename-command CONFIG ""
    rename-command FLUSHALL ""

    # 6. 系统层
    #   用非 root 用户跑 redis
    #   数据目录独立且不可写危险位置
    # 7. 网络层
    #   防火墙/安全组只放行信任来源

    即使只做 1+2+3,之前的四条 getshell 全都会断在第 1 步(连不上/要密码)。再做 5,连"拿到密码但想用危险命令"也被断。这就是分层防御:每一层都独立地挡住一种攻击路径。


    7. 攻防对照表

    攻击手法(前面的篇目)核心依赖对应防御
    未授权访问(03) bind 0.0.0.0 + 无密码 bind 收紧 + protected-mode + requirepass/ACL
    爆破弱口令 弱密码 强密码 + 限制失败次数/来源 IP + 日志监控
    写 crontab/公钥/WebShell(03) CONFIG SET dir + 高权限 + 落盘 禁用 CONFIG + 非 root 跑 + 目录权限/SELinux
    主从复刻 RCE(03) REPLICAOF + 模块加载 + 可反连 禁用/改名 REPLICAOF + 版本升级 + ACL + 出网限制
    SSRF 打 Redis(04) 内网可达 + 无密码 网络隔离 + 密码 + SSRF 点本身修复(你 SSRF 篇已讲)
    信息泄露(读业务数据) 可连接可读 ACL 最小权限 + 敏感数据加密存储/不要明文进 Redis
    DoS(KEYS */灌数据) 单线程 + 可执行 禁 KEYS/FLUSHALL + 限内存 maxmemory + 连接数限制

    8. 失陷后的排查要点

    如果怀疑 Redis 失陷,冷静按下面查(配合应急响应流程):

  • 看有没有被写文件:检查 CONFIG GET dir 当前值、/var/spool/cron*、/root/.ssh/authorized_keys、web 根目录的陌生 .php/.so。

  • 看有没有被改配置:CONFIG GET requirepass、ACL LIST(是否多了陌生用户)。

  • 看有没有被加载模块:MODULE LIST(Redis 4+)。

  • 看主从关系:INFO replication 是否被改成了某陌生主的从库。

  • 看日志:redis.log、系统登录日志、反弹连接的连接记录。

  • 紧急处置:断网隔离 → 改密码/重建实例 → 取证 → 复盘加固。

  • 处置时优先"保留现场取证",别急着 flushall(会把攻击痕迹也清了)。


    9. 小结

    防御的本质不是背命令,而是分层:

    网络层(连不上) → 认证层(连上也要密码) → 授权层(危险命令被禁)
    → 系统层(命令执行了也写不了危险位置) → 监控审计(打进来能发现)

    攻防其实是同一张地图,攻方从外往内一层层找"允许",守方从内往外一层层设"不允许"。


    全系列自测

  • 用自己的话,把"未授权 Redis 为什么危险"从网络→认证→写文件→执行,完整讲一遍因果链。

  • 给一个"只能跑缓存、永远不该被当数据库写"的 Redis 写一份最小安全配置。

  • 假设你是蓝队,收到"内网 6379 裸奔"告警,写出你从确认到处置的完整动作清单。

  • 说出 ACL 里限制一个业务账号"只能读某前缀 key、不能用 CONFIG/FLUSHALL/EVAL"的完整命令。

  • 解释为什么"Redis 用 root 跑"比"没设密码"在某些场景更致命。

  • 赞(0)
    未经允许不得转载:171主机测评 » redis防御加固与安全基线
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址