第 40 章
生产配置与安全加固
第40章 生产配置与安全加固
Redis 的默认配置面向开发便利,而非生产安全。本章系统覆盖网络绑定、认证体系、危险命令防护、TLS 加密、内核参数调优,以及完整的25条生产安全 Checklist。
1. 网络绑定配置
1.1 bind 与 protected-mode
# redis.conf
# 只监听内网接口,绝不绑定 0.0.0.0 或公网 IP
bind 127.0.0.1 192.168.1.100
# protected-mode:在无密码且未配置 bind 时,拒绝非 loopback 连接
# 生产中有密码时可设为 no,但建议保持 yes 作为双重保护
protected-mode yes
# 监听端口(可改非默认端口作为额外防护)
port 6379
# Unix socket(性能最好,同机通信)
unixsocket /var/run/redis/redis.sock
unixsocketperm 770
# 验证绑定是否生效
ss -tlnp | grep 6379
# 正确:只显示 127.0.0.1:6379 和 192.168.1.100:6379
# 危险:显示 0.0.0.0:6379 或 :::6379
2. 认证:requirepass 与 ACL
2.1 传统 requirepass(Redis 6.0 前)
# redis.conf
requirepass "YourStr0ng!Password#2024"
# 客户端认证
AUTH YourStr0ng!Password#2024
# 密码强度要求:
# - 长度 >= 32 字符
# - 包含大小写字母、数字、特殊字符
# - 避免字典词、生日、公司名
2.2 ACL(Redis 6.0+,强烈推荐)
ACL 支持细粒度权限控制:指定用户可访问哪些 key、执行哪些命令。
# 语法:ACL SETUSER <name> [on|off] [>password] [~key-pattern] [+command|-command]
# 应用只读用户(只能读取 cache: 前缀的 key)
ACL SETUSER readonly_user on >ReadPass#123 ~cache:* +@read
# 应用读写用户(只能操作 cache: 和 session: 前缀)
ACL SETUSER app_user on >AppPass#456 ~cache:* ~session:* +get +set +del +expire +hset +hget +hgetall +hgetall
# 管理员(全部权限)
ACL SETUSER admin_user on >AdminPass#789 ~* &* +@all
# 只允许发布订阅
ACL SETUSER pubsub_user on >PubSubPass ~* &events:* +subscribe +publish +unsubscribe
# 查看所有用户
ACL LIST
# 输出:
# user default off nopass ~* &* +@all
# user app_user on #<sha256密码哈希> ~cache:* ~session:* +get +set ...
# 查看当前用户
ACL WHOAMI
# 验证某用户是否可执行某命令
ACL DRYRUN app_user get cache:user:1001 # OK 或 报错
# 加载 ACL 文件(推荐将 ACL 配置独立文件)
ACL LOAD
ACL SAVE
# redis.conf 指定 ACL 文件
aclfile /etc/redis/users.acl
# users.acl 内容示例:
user default off
user app_user on #5e884898da28047151d0e56f8dc629277b7b1ad36601f39a6e4c6a40f5e0a16 ~cache:* ~session:* +get +set +del +expire +hset +hget +hgetall +ttl
user admin_user on #<admin_password_sha256> ~* &* +@all
2.3 命令分组
# Redis 内置命令组
+@all # 所有命令
+@read # GET/HGET/LRANGE/SMEMBERS 等只读命令
+@write # SET/HSET/LPUSH/SADD 等写命令
+@string # 字符串相关命令
+@hash # Hash 相关命令
+@list # List 相关命令
+@set # Set 相关命令
+@sortedset # ZSet 相关命令
+@geo # GEO 命令
+@stream # Stream 命令
+@pubsub # 发布订阅命令
+@admin # CONFIG/INFO/DEBUG 等管理命令
+@dangerous # FLUSHALL/KEYS/DEBUG 等危险命令
-@dangerous # 禁止危险命令(在 +@all 后减去)
3. rename-command 隐藏危险命令
# redis.conf
# 禁用危险命令(设为空字符串)
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
rename-command KEYS ""
rename-command CONFIG "" # 禁用后需通过配置文件管理,不能动态修改
rename-command SHUTDOWN ""
# 改名为随机字符串(内部工具仍可使用)
rename-command CONFIG "CONFIG_a8f3d2c1b4e5"
rename-command DEBUG "DEBUG_x9y8z7w6v5u4"
rename-command OBJECT "OBJECT_q1w2e3r4t5"
# 注意:Cluster 模式下 rename-command 不支持,需用 ACL 替代
# 客户端适配(改名后)
CONFIG_COMMAND = "CONFIG_a8f3d2c1b4e5"
def redis_config_get(param: str):
return r.execute_command(CONFIG_COMMAND, "GET", param)
4. TLS 双向认证(mTLS)
4.1 生成证书
# 创建 CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
-subj "/C=CN/O=YourCompany/CN=Redis CA"
# 生成服务端证书
openssl genrsa -out redis.key 2048
openssl req -new -key redis.key -out redis.csr \
-subj "/C=CN/O=YourCompany/CN=redis.internal"
openssl x509 -req -days 365 -in redis.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out redis.crt
# 生成客户端证书(mTLS 要求)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
-subj "/C=CN/O=YourCompany/CN=redis-client"
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt
4.2 Redis TLS 配置
# redis.conf
# 关闭明文端口(或保留用于内部监控)
port 0
# 开启 TLS 端口
tls-port 6380
# 证书路径
tls-cert-file /etc/redis/certs/redis.crt
tls-key-file /etc/redis/certs/redis.key
tls-ca-cert-file /etc/redis/certs/ca.crt
# 要求客户端提供证书(双向认证)
tls-auth-clients yes
# TLS 版本(最低 TLS 1.2)
tls-protocols "TLSv1.2 TLSv1.3"
# 密码套件
tls-ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
tls-ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
tls-prefer-server-ciphers yes
# 复制也使用 TLS
tls-replication yes
tls-cluster yes # Cluster 内部通信 TLS
4.3 客户端 TLS 连接
import redis
import ssl
r = redis.Redis(
host="redis.internal",
port=6380,
ssl=True,
ssl_certfile="/path/to/client.crt",
ssl_keyfile="/path/to/client.key",
ssl_ca_certs="/path/to/ca.crt",
ssl_check_hostname=True,
)
# 测试连接
print(r.ping()) # True
# redis-cli TLS 连接
redis-cli -h redis.internal -p 6380 \
--tls \
--cert /path/to/client.crt \
--key /path/to/client.key \
--cacert /path/to/ca.crt \
ping
5. maxmemory 计算与配置
5.1 计算公式
maxmemory = (物理内存 - OS预留 - 其他进程内存) × 0.75~0.85
示例(32GB服务器,仅运行Redis):
OS预留: 2GB
Prometheus exporter + 监控agent: 0.5GB
可用: 32 - 2 - 0.5 = 29.5GB
maxmemory = 29.5 × 0.80 ≈ 23GB
注意:预留20%给 BGSAVE 的 fork COW(Copy-On-Write)开销
写入密集场景 fork 瞬间内存可翻倍!
5.2 配置示例
# redis.conf
maxmemory 23gb
maxmemory-policy allkeys-lru # 推荐策略(无需应用层设置 TTL 也能自动淘汰)
# 淘汰算法采样数(默认5,增大提高精度但消耗CPU)
maxmemory-samples 10
# 淘汰策略说明:
# noeviction - 不淘汰,写入报错(适合做数据库)
# allkeys-lru - 淘汰最久未使用的key(通用缓存首选)
# allkeys-lfu - 淘汰使用频率最低的key(热点数据保留)
# allkeys-random - 随机淘汰
# volatile-lru - 只淘汰有TTL的key中最久未使用的
# volatile-lfu - 只淘汰有TTL的key中频率最低的
# volatile-random - 随机淘汰有TTL的key
# volatile-ttl - 优先淘汰TTL最短的key
6. 内核参数优化
# /etc/sysctl.conf
# 允许过度提交内存(避免 BGSAVE fork 因内存不足失败)
# 0: 启发式(默认)1: 允许过度提交 2: 严格限制
vm.overcommit_memory = 1
# 增大TCP连接队列(防止高并发时连接被丢弃)
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TCP keepalive(及时发现死连接)
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# 增大文件描述符限制
fs.file-max = 1000000
# 应用配置
sysctl -p
# 透明大页(THP)—— 必须关闭
# THP 会导致 Redis fork 时 COW 延迟抖动,以及内存碎片问题
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 持久化(开机自动关闭 THP)
cat >> /etc/rc.local << 'EOF'
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
chmod +x /etc/rc.local
# 验证
cat /sys/kernel/mm/transparent_hugepage/enabled
# 输出应为:always madvise [never]
# 进程级文件描述符限制
# /etc/security/limits.conf
redis soft nofile 65535
redis hard nofile 65535
# 或在 systemd service 中设置
# /etc/systemd/system/redis.service
[Service]
LimitNOFILE=65535
# redis.conf 内的相关配置
tcp-backlog 511 # 与 somaxconn 配合,建议 >= 512
tcp-keepalive 300 # Redis 级别的 TCP keepalive(秒)
timeout 0 # 客户端空闲超时(0=不超时,可设300)
7. 持久化安全配置
# redis.conf
# RDB 快照
save 3600 1 # 1小时内有1个写操作时保存
save 300 100 # 5分钟内有100个写操作时保存
save 60 10000 # 1分钟内有10000个写操作时保存
# RDB 写失败时停止写入(防止数据丢失)
stop-writes-on-bgsave-error yes
# RDB 文件压缩
rdbcompression yes
rdbchecksum yes # CRC64 校验
# AOF 配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # 每秒 fsync(平衡性能和安全)
# appendfsync always # 每次写都 fsync(最安全,性能最差)
# appendfsync no # 交给 OS 决定(性能最好,可能丢数据)
# AOF 重写(减少 AOF 文件大小)
no-appendfsync-on-rewrite no # 重写期间照常 fsync
auto-aof-rewrite-percentage 100 # AOF 增长到原来的 2 倍时触发重写
auto-aof-rewrite-min-size 64mb # AOF >= 64MB 才触发重写
# 目录权限
dir /var/lib/redis
# chown redis:redis /var/lib/redis
# chmod 750 /var/lib/redis
8. 审计日志
# Redis 本身无审计日志功能
# 方案1:redis-cli MONITOR 输出重定向(影响性能,仅短时使用)
redis-cli monitor >> /var/log/redis/audit.log &
# 方案2:使用 redis-audit 工具(第三方)
# https://github.com/snmaynard/redis-audit
# 方案3:代理层审计(推荐生产)
# Twemproxy / Envoy sidecar 拦截并记录所有命令
# 支持按用户/IP/命令类型过滤记录
# 方案4:keyspace notifications + 外部监听
CONFIG SET notify-keyspace-events "KEA" # 所有事件
redis-cli --no-auth-warning -p 6379 subscribe '__keyevent@0__:set'
9. 生产安全 Checklist(25条)
网络隔离(5条)
✅ 1. bind 配置只绑定内网 IP,禁止 0.0.0.0
✅ 2. 防火墙规则:6379/6380 只开放给应用服务器 IP,对公网全部关闭
✅ 3. Redis 与应用部署在同一 VPC/安全组,不经过公网
✅ 4. Sentinel/Cluster 管理端口(26379/17000+)单独防火墙策略
✅ 5. 使用 Unix Socket 代替 TCP(同机应用,性能+安全双优)
认证与授权(5条)
✅ 6. 必须配置认证(requirepass 或 ACL),禁止空密码
✅ 7. 使用 ACL 实现最小权限:应用用户只能操作自己的 key 前缀
✅ 8. 禁用 default 用户(ACL SETUSER default off)
✅ 9. 不同服务使用不同 Redis 用户,DB 隔离(SELECT 0/1/2...)
✅ 10. 密码存储在密钥管理服务(Vault / AWS Secrets Manager),不硬编码
危险命令防护(4条)
✅ 11. rename-command 禁用 FLUSHDB / FLUSHALL / DEBUG / SHUTDOWN
✅ 12. rename-command 禁用 KEYS(强制使用 SCAN)
✅ 13. ACL 中 -@dangerous 禁止应用用户执行危险命令
✅ 14. 生产 DBA 操作前需二次确认(FLUSHALL 等操作必须双人确认)
传输安全(2条)
✅ 15. 生产环境启用 TLS,最低 TLS 1.2,推荐 TLS 1.3
✅ 16. Cluster 节点间通信也启用 tls-cluster yes / tls-replication yes
内存与配置(4条)
✅ 17. 配置 maxmemory 和合适的 maxmemory-policy,防止内存无限增长
✅ 18. 配置 timeout(客户端空闲超时),防止连接泄漏
✅ 19. 关闭透明大页(THP):echo never > .../transparent_hugepage/enabled
✅ 20. vm.overcommit_memory = 1,防止 BGSAVE fork 失败
持久化与备份(3条)
✅ 21. 生产启用 AOF(appendonly yes,appendfsync everysec)
✅ 22. 定期备份 RDB 到异地存储(S3/OSS),保留至少7天
✅ 23. 定期测试备份恢复流程(每季度至少一次演练)
监控与告警(2条)
✅ 24. 部署 redis_exporter + Prometheus + Grafana,核心告警全覆盖(见第39章)
✅ 25. 配置 slowlog-log-slower-than 5000(5ms),慢查询告警和定期审查
10. 完整生产 redis.conf 模板
# ==== 网络 ====
bind 127.0.0.1 192.168.1.100
port 6379
protected-mode yes
tcp-backlog 511
timeout 300
tcp-keepalive 300
# ==== TLS(按需开启)====
# tls-port 6380
# port 0
# tls-cert-file /etc/redis/certs/redis.crt
# tls-key-file /etc/redis/certs/redis.key
# tls-ca-cert-file /etc/redis/certs/ca.crt
# tls-auth-clients yes
# tls-protocols "TLSv1.2 TLSv1.3"
# tls-replication yes
# ==== 认证 ====
# requirepass "YourStr0ng!Password#2024" # 用 ACL 替代
aclfile /etc/redis/users.acl
# ==== 危险命令 ====
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
rename-command KEYS ""
rename-command SHUTDOWN "SHUTDOWN_9x8y7z"
rename-command CONFIG "CONFIG_a1b2c3d4"
# ==== 内存 ====
maxmemory 23gb
maxmemory-policy allkeys-lru
maxmemory-samples 10
# ==== 持久化 ====
save 3600 1
save 300 100
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes
# ==== 性能 ====
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
# ==== 慢日志 ====
slowlog-log-slower-than 5000
slowlog-max-len 256
# ==== 日志 ====
loglevel notice
logfile /var/log/redis/redis.log
# ==== 进程 ====
daemonize yes
pidfile /var/run/redis/redis.pid
# ==== 客户端 ====
maxclients 10000
本章总结
- bind + protected-mode + 防火墙三层网络隔离是基础
- Redis 6.0+ ACL 是认证和授权的最佳实践,颠覆单一 requirepass
- rename-command 处理危险命令,ACL -@dangerous 双重防护
- TLS mTLS 确保传输层安全,Cluster 和复制通信同样需要开启
- maxmemory 配置要为 BGSAVE fork 预留 COW 内存空间(15-25%)
- 内核参数:THP 关闭、overcommit=1、somaxconn 扩大,三项必改
- 25条 Checklist 覆盖网络/认证/命令/TLS/内存/持久化/监控全维度