Skip to content

安全配置

Redis 设计的默认假设是在可信网络内部运行——默认不设密码、bind 本机、protected-mode 兜底。安全配置是在这个基础上叠加防御层次:网络隔离是第一层,密码和 ACL 是第二层,危险命令控制和最小权限是第三层。

一、网络隔离——第一层防线

Redis 安全的第一层是"不让不该连的人连上"。密码和 ACL 在之后。

conf
bind 127.0.0.1 10.0.0.11     # 只监听本机和指定内网地址
protected-mode yes             # 兜底保护:无密码且非本机绑定时的额外拦截

检查当前监听情况:

bash
ss -lntp | grep ':6379'

看到 0.0.0.0:6379 表示所有网卡都在监听——如果机器有公网 IP,Redis 就直接暴露到了公网。0.0.0.0 本身不是事故,但前面的防火墙和安全组必须严格限制来源。

本机防火墙示例(iptables):

bash
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

云上环境的安全组是等同的概念——安全组规则太宽比 Redis 配置错了更难发现,因为 Redis 自己不知道前面有多少来源能连进来。

二、密码和 ACL

requirepass——全局密码

Redis 6 之前只有全局密码:

conf
requirepass strong_password_here

连接时传入:

bash
redis-cli -a 'strong_password_here' PING

命令行里的 -a 密码可能被 ps 看到。脚本里可以改用环境变量减少暴露:

bash
export REDISCLI_AUTH='strong_password_here'
redis-cli PING

ACL——按用户拆分权限

Redis 6 开始支持 ACL,可以创建多个用户,各自拥有独立的密码、可操作的 key 模式和可执行的命令集合。相比所有人共用一个 requirepass,ACL 可以区分应用写账号、只读监控账号和运维管理账号。

查看现有用户:

bash
redis-cli ACL LIST

关闭危险的默认用户,创建应用和只读用户:

bash
# 关闭无密码的 default 用户
redis-cli ACL SETUSER default off

# 应用账号——只能操作 app: 前缀的 key,只有基本的读写和过期命令
redis-cli ACL SETUSER app on '>app_password' '~app:*' '+get' '+set' '+del' '+expire'

# 只读账号——可以读所有 key,但不能写
redis-cli ACL SETUSER readonly on '>readonly_password' '~*' '+get' '+mget' '+exists' '+ttl' '+type'

ACL 规则语法:

片段含义
on / off启用或禁用该用户
>password设置密码
~pattern限制可访问的 key 匹配模式,~* 表示所有 key
+command允许执行的命令
-command禁止执行的命令

ACL 还支持 ACL LOG 查看被拒绝的命令请求,用来排查权限是否设得过于严格或者是否有越权尝试。

三、危险命令控制

以下命令在生产环境中影响很大:

命令风险
FLUSHALL / FLUSHDB清空所有数据,不可逆
CONFIG可以动态修改持久化、安全等关键配置
SHUTDOWN停止 Redis 实例
DEBUG可能阻塞线程甚至导致崩溃
KEYS大实例上遍历键空间会阻塞主线程

Redis 6 用 ACL 禁用:

bash
redis-cli ACL SETUSER app -flushall -flushdb -config -shutdown -debug

Redis 5 及更早版本用 rename-command 禁用:

conf
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command SHUTDOWN ""

把命令名改为空字符串表示禁用。rename-command 的副作用:某些运维工具和监控脚本如果调用了这些命令,改名后它们也会失效——需要同步调整工具配置。

KEYS 通常不直接禁用(排查时会用到),而是通过 ACL 限制只有特定账号能用,同时推动应用侧改用 SCAN

四、运行用户和文件权限

Redis 进程不应该以 root 身份运行。如果 Redis 自身有漏洞或配置被滥用,低权限用户能减少对系统的影响面:

bash
ps -ef | grep '[r]edis-server'    # 确认运行用户不是 root

配置文件和数据目录的权限:

bash
chown redis:redis /etc/redis/6379.conf
chmod 640 /etc/redis/6379.conf    # 配置文件可能含密码,不应对其他用户可读

chown -R redis:redis /data/redis
chmod 750 /data/redis

五、TLS

内网环境不一定开启 TLS,但跨机房、跨云、共享网络或合规有要求时需要考虑。TLS 会增加证书管理和排查成本——证书过期、CA 信任链问题、客户端不支持 TLS,都是额外的故障源。

配置示例:

conf
tls-port 6380
port 0                           # 关闭非 TLS 端口
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt

客户端连接:

bash
redis-cli --tls \
  --cert /etc/redis/tls/client.crt \
  --key /etc/redis/tls/client.key \
  --cacert /etc/redis/tls/ca.crt \
  -p 6380 PING

六、审计和日志的局限

Redis 自身的日志记录的是启动、关闭、持久化和连接事件,不会像数据库审计那样记录每条命令和对应的参数:

conf
loglevel notice
logfile /var/log/redis/redis-6379.log

排查"谁在什么时候执行了什么命令"时,Redis 自身日志能提供的信息有限。需要结合:

  • 堡垒机或跳板机记录(谁连上了 Redis 机器)
  • 慢日志(只记录超过阈值的慢命令,不是完整审计)
  • 应用日志(应用侧做了什么样的数据操作)
  • MONITOR(实时命令流,但消耗性能且可能暴露敏感数据,生产环境慎重)

ACL LOG 可以记录被拒绝的命令尝试,排查越权:

bash
redis-cli ACL LOG

七、基线检查清单

部署完成后逐项确认:

bash
# 监听地址
ss -lntp | grep ':6379'

# 是否设了密码
redis-cli CONFIG GET requirepass

# protected-mode 是否开启
redis-cli CONFIG GET protected-mode

# bind 了哪些地址
redis-cli CONFIG GET bind

# ACL 用户配置
redis-cli ACL LIST

# 运行用户
ps -ef | grep '[r]edis-server'
检查项安全标准
监听地址仅本机或内网指定地址,不监听 0.0.0.0(除非前面有严格控制)
安全组/防火墙限制来源 IP 段,不放任意来源
认证启用 ACL 区分应用/只读/管理账号,或至少 requirepass
默认用户default 用户应关闭或限制权限
危险命令FLUSHALL/CONFIG/SHUTDOWN/DEBUG 已禁用
运行用户非 root,专用 redis 用户
配置文件权限640,仅 redis 用户可读写
数据目录权限清晰,备份策略明确

安全配置在初始化阶段做比上线后补救代价小很多。等实例已经接了业务再改认证方式、收紧命令权限、调整监听地址,影响面大且可能触发应用中断。