一、前言:你的 Redis 可能正在"裸奔"!
你是否做过以下操作?
- 将 Redis 直接暴露在公网(
bind 0.0.0.0) - 使用默认端口
6379且未设密码 - 允许
CONFIG、FLUSHALL等危险命令执行
⚠️ 后果 :
数据被清空、服务器被植入挖矿木马、甚至被用于远程代码执行(RCE)!
本文将基于 Redis 6.0+(企业主流版本) ,从 网络层 → 认证层 → 命令层 → 传输层 四个维度,带你构建生产级安全防线。
二、安全威胁全景图
| 威胁类型 | 攻击方式 | 后果 |
|---|---|---|
| 未授权访问 | 扫描公网 6379 端口 |
任意命令执行 |
| 弱密码/无密码 | 暴力破解或直接连接 | 数据窃取、删除 |
| 危险命令滥用 | 执行 CONFIG SET dir |
写入恶意 .so 模块 → RCE |
| 主从复制劫持 | 从库可写 + 公网暴露 | 注入恶意 Lua 脚本 |
| 明文传输 | 中间人嗅探 | 敏感数据泄露 |
✅ 核心原则 :
"Redis 默认不安全!生产环境必须逐层加固。"
三、第一道防线:网络层隔离
3.1 绑定内网 IP(bind)
# redis.conf
# 仅允许本地访问(单机部署)
bind 127.0.0.1
# 允许特定内网IP(集群/应用服务器)
bind 192.168.1.100 10.0.0.10
# ❌ 禁止:bind 0.0.0.0(除非配合防火墙)
3.2 启用保护模式(protected-mode)
# 默认开启(Redis 3.2+)
protected-mode yes
作用 :当
bind非127.0.0.1且未设密码时,拒绝外部连接。
3.3 防火墙规则(Linux iptables)
bash
# 仅允许应用服务器IP访问
iptables -A INPUT -p tcp -s 192.168.1.50 --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
四、第二道防线:认证与访问控制
4.1 传统密码(requirepass)
# redis.conf
requirepass Your_Very_Strong_Password_!@#123
缺点:所有用户共享同一密码,无法细粒度控制。
4.2 ACL(访问控制列表,Redis 6.0+ 推荐!)
(1) 启用 ACL 文件
# redis.conf
aclfile /etc/redis/users.acl
(2) 创建用户策略(/etc/redis/users.acl)
# 超级管理员(谨慎使用)
user admin on >AdminPass123 ~* &* +@all
# 应用只读用户
user app_reader on >ReaderPass456 ~cache:* ~session:* +@read
# 应用读写用户
user app_writer on >WriterPass789 ~user:* ~order:* +@read +@write -flushall -config
(3) 权限说明
| 符号 | 含义 |
|---|---|
on |
启用用户 |
>password |
设置密码 |
~key |
允许访问的 Key 模式 |
+command |
允许的命令 |
-command |
禁用的命令 |
+@category |
允许的命令类别(如 @read, @write, @admin) |
4.3 客户端连接示例(Java)
java
// 使用 ACL 用户连接
Config config = new Config();
config.useSingleServer()
.setAddress("redis://192.168.1.100:6379")
.setUsername("app_writer") // 指定用户名
.setPassword("WriterPass789");
RedissonClient redisson = Redisson.create(config);
五、第三道防线:危险命令禁用
5.1 为什么需要禁用?
CONFIG:可修改dir和dbfilename,写入 WebshellFLUSHALL/FLUSHDB:清空所有数据DEBUG:可能导致服务崩溃MODULE:加载恶意模块
5.2 禁用方法(rename-command)
# redis.conf
rename-command CONFIG ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command DEBUG ""
rename-command MODULE ""
原理 :将命令重命名为空字符串,使其无法执行。
5.3 验证是否生效
bash
# 尝试执行被禁用的命令
127.0.0.1:6379> CONFIG GET *
(error) ERR unknown command `CONFIG`, with args beginning with:
⚠️ 注意 :
ACL 的
-command比rename-command更灵活,推荐优先使用 ACL。
六、第四道防线:传输层加密(TLS)
6.1 为什么需要 TLS?
- 防止中间人攻击(MitM)
- 满足 GDPR、等保等合规要求
6.2 配置步骤
(1) 生成证书(OpenSSL)
bash
# 生成 CA
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=RedisCA" -days 3650 -out ca.crt
# 生成服务端证书
openssl genrsa -out redis.key 2048
openssl req -new -key redis.key -subj "/CN=redis-server" -out redis.csr
openssl x509 -req -in redis.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out redis.crt -days 3650
(2) Redis 配置(redis.conf)
bash
# 启用 TLS
tls-port 6380
port 0 # 关闭非加密端口
# 证书路径
tls-cert-file /etc/redis/redis.crt
tls-key-file /etc/redis/redis.key
tls-ca-cert-file /etc/redis/ca.crt
# 强制客户端验证
tls-auth-clients yes
(3) 客户端连接(redis-cli)
bash
redis-cli --tls --cert redis.crt --key redis.key --cacert ca.crt -p 6380
七、生产环境安全配置模板
/etc/redis/redis.conf(完整版)
bash
# ===== 网络安全 =====
bind 192.168.1.100
protected-mode yes
port 0 # 关闭非TLS端口
tls-port 6380 # 启用TLS端口
# ===== 认证与ACL =====
aclfile /etc/redis/users.acl
# ===== 危险命令 =====
rename-command CONFIG ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
# ===== TLS 加密 =====
tls-cert-file /etc/redis/redis.crt
tls-key-file /etc/redis/redis.key
tls-ca-cert-file /etc/redis/ca.crt
tls-auth-clients yes
# ===== 其他安全 =====
maxclients 1000
timeout 300
replica-read-only yes # 从库只读
/etc/redis/users.acl
user default off # 禁用默认用户
user admin on >SuperSecretPass ~* &* +@all
user webapp on >WebAppPass ~session:* ~cache:* +@read +@write -flush* -config
八、安全审计与监控
8.1 日志监控
bash
# redis.conf
logfile /var/log/redis/redis.log
loglevel notice
关键日志事件:
User <name> connected(新用户连接)Command 'CONFIG' not allowed(危险命令拦截)
8.2 自动化扫描
bash
# 检查公网暴露
nmap -p 6379 your-server-ip
# 检查弱密码(谨慎使用)
redis-cli -h your-server-ip -a weakpass INFO
8.3 Prometheus 监控指标
| 指标 | 说明 |
|---|---|
redis_connected_clients |
连接数突增可能异常 |
redis_rejected_connections |
连接被拒绝次数 |
redis_acl_access_denied_commands |
ACL 拦截的命令数 |
九、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!