Redis 主从复制在默认配置下,数据在网络上是以明文形式传输的。这意味着任何能够接触到网络流量的人,都可以直接看到你的缓存数据,包括可能存在的敏感用户会话、业务缓存或配置信息。解决这个问题需要从两个维度入手:一是主从节点之间的身份认证,防止未授权节点接入;二是传输层的 SSL/TLS 加密,防止数据在链路上被窃听或篡改。这两个机制并非互斥,在生产环境中通常需要叠加使用,才能构建完整的数据同步安全防线。
配置 requirepass 和 masterauth 实现节点认证Redis 的认证机制基于共享密钥,核心配置项只有两个:requirepass 和 masterauth。requirepass 设置在 master 节点上,它要求所有客户端在发送命令之前,必须先执行 AUTH 命令并提供正确的密码。这个“客户端”不仅包括你的应用程序,也包括试图从该 master 同步数据的 slave 节点。因此,当 slave 尝试连接 master 时,它必须携带这个密码,否则 master 会拒绝复制请求,并在日志中输出类似 “Client sent AUTH, but no password is set” 或 “invalid password” 的错误。
具体配置非常直接。在 master 的 redis.conf 文件中,找到并修改 requirepass 指令:
requirepass your_strong_password_here
这个密码需要足够复杂,建议使用长度超过 32 位、包含大小写字母、数字和特殊符号的随机字符串。你可以使用 openssl 命令生成:
openssl rand -base64 32
在 slave 节点上,则需要在 redis.conf 中配置 masterauth,它的值必须与 master 的 requirepass 完全一致:
masterauth your_strong_password_here
如果你通过命令行临时添加认证,可以使用 redis-cli 连接后执行 CONFIG SET 命令,但务必同步修改配置文件,否则重启后配置会丢失。一个容易忽略的细节是,当 master 发生故障转移,某个 slave 被提升为新的 master 时,它本身也需要设置 requirepass,否则其他 slave 无法以新 master 的身份完成认证。在 Sentinel 或 Cluster 架构中,所有节点的 requirepass 和 masterauth 应保持统一,并配合 sentinel 的 sentinel auth-pass 指令,确保整个拓扑结构中的认证一致性。
SSL/TLS 加密同步的必要性与编译部署仅仅有密码认证是不够的。密码验证只在连接建立时发生一次,后续的数据同步流依然是明文的。如果你的 Redis 部署在跨机房、跨地域的云环境,或者底层网络路径不可信,SSL/TLS 加密就是必选项。Redis 从 6.0 版本开始原生支持 SSL/TLS,但需要注意,大多数 Linux 发行版通过包管理器安装的 Redis 默认没有开启 SSL 支持,你需要从源码编译,或者使用官方提供的带 TLS 支持的二进制包。
编译过程的关键是在 make 时启用 BUILD_TLS 标志。首先确保系统已安装 OpenSSL 开发库,然后执行:
make BUILD_TLS=yes make install
编译完成后,你可以通过运行 redis-server --version 来确认是否包含 TLS 支持,输出中会明确显示 “SSL” 字样。接下来,你需要准备 SSL 证书。对于生产环境,应使用由受信任的 CA 签发的证书。对于内部测试,可以使用自签名证书。生成自签名证书的典型命令如下:
openssl genrsa -out redis.key 2048 openssl req -new -key redis.key -out redis.csr -subj "/CN=redis-master" openssl x509 -req -in redis.csr -signkey redis.key -out redis.crt -days 365
这里生成的 redis.key 是私钥,redis.crt 是证书文件。你需要将这些文件安全地分发到所有参与复制的节点上,并设置严格的权限,例如 chmod 600 redis.key,防止私钥泄露。
配置 TLS 复制与双向认证Redis 的 TLS 配置非常灵活,你可以选择仅在复制链路上启用加密,而客户端连接保持明文,也可以全局启用。对于主从复制的场景,核心配置项包括 tls-port、tls-cert-file、tls-key-file 以及 tls-replication。假设你希望主从复制走专用的 TLS 端口,而普通客户端仍通过默认 6379 端口明文访问,可以在 master 和 slave 的配置文件中这样设置:
port 6379 tls-port 6380 tls-cert-file /path/to/redis.crt tls-key-file /path/to/redis.key tls-replication yes
这里的关键是 tls-replication yes,它告诉 Redis 主从之间的数据同步必须使用 TLS 加密。此时,slave 在连接 master 时,需要指定 TLS 端口和证书信息。在 slave 的配置中,除了上述 TLS 基础配置外,还需要明确 replicaof 指令使用 TLS 端口:
replicaof master-host 6380 tls-replication yes
如果你的安全策略要求双向 TLS 认证,即 master 也需要验证 slave 的证书,那么还需要配置 tls-ca-cert-file 和 tls-auth-clients。在 master 上设置:
tls-ca-cert-file /path/to/ca.crt tls-auth-clients yes
这样,slave 在连接时也必须提供由该 CA 签发的有效证书,否则握手会失败。这是一种极强的安全保证,可以防止伪造的 slave 节点接入复制拓扑,即使攻击者窃取了 requirepass 密码也无济于事。
性能影响与优化策略TLS 加密会引入额外的 CPU 开销,主要发生在握手阶段和数据传输时的对称加解密。对于高吞吐量的 Redis 实例,这个开销不容忽视。根据实际测试,启用 TLS 后,Redis 的吞吐量可能会下降 30% 到 50%,延迟也会有所增加。为了缓解这个问题,你可以采取几种优化措施。第一,使用 Redis 6.2 及以上版本,它对 TLS 的 I/O 线程模型进行了优化,支持将加解密操作卸载到多个 I/O 线程上。你可以在配置中启用 io-threads 和 io-threads-do-reads:
io-threads 4 io-threads-do-reads yes
第二,选择更高效的加密套件。在 redis.conf 中通过 tls-ciphers 指定优先使用 AES-GCM 等支持硬件加速的算法,避免使用过于古老或计算密集的套件。第三,考虑会话复用。Redis 支持 TLS 会话缓存,通过设置 tls-session-caching yes 和 tls-session-cache-size 来减少重复握手的开销。对于长连接的主从复制链路来说,握手频率本身不高,但会话缓存在网络闪断重连时能显著缩短恢复时间。
常见故障排查与日志分析当主从复制无法建立时,日志是定位问题的第一手资料。如果 slave 日志中出现 “Connection refused” 或 “No route to host”,首先检查网络连通性和防火墙规则,确认 TLS 端口是否已开放。如果日志显示 “SSL_connect failed” 或 “certificate verify failed”,问题通常出在证书配置上。你需要逐一核对:证书路径是否正确、私钥是否与证书匹配、证书是否在有效期内、CA 证书链是否完整。使用 openssl s_client 工具可以模拟 TLS 连接,帮助诊断问题:
openssl s_client -connect master-host:6380 -cert redis.crt -key redis.key -CAfile ca.crt
这条命令会详细输出 TLS 握手的每一步,包括服务器证书信息、协商的加密套件以及任何验证错误。如果握手成功,你会看到 “Verify return code: 0 (ok)” 的提示。另一个常见问题是密码认证与 TLS 的交互。当 TLS 启用后,requirepass 认证依然有效,但密码本身现在是在加密通道内传输的,安全性得到保障。如果 slave 日志中反复出现 “MASTER aborted replication with an error: NOAUTH Authentication required”,说明 masterauth 配置缺失或密码错误,需要仔细比对 master 的 requirepass 值。
构建纵深防御的复制安全体系将认证和加密结合使用,能够形成纵深防御。即使攻击者通过某种手段获取了密码,如果他没有有效的客户端证书,在双向 TLS 模式下依然无法建立复制连接。反之,如果证书管理不善导致私钥泄露,密码认证还能提供一层额外的保护。在实际部署中,建议遵循最小权限原则:为 Redis 复制专门生成一套证书,与客户端连接使用的证书区分开。定期轮换证书和密码,并将这些敏感信息纳入密钥管理服务中,避免硬编码在配置文件或代码仓库里。监控方面,应设置告警规则,对连续的 AUTH 失败或 TLS 握手失败进行实时检测,这往往是攻击行为的前兆。
对于使用 Redis Cluster 的场景,每个节点之间的 gossip 通信和数据迁移同样需要保护。你可以在所有节点上统一配置 tls-cluster yes,强制集群内部通信也走 TLS 加密。此时,tls-replication 和 tls-cluster 应同时启用,确保整个集群的东-西向流量都处于加密状态。Sentinel 模式下的通信保护则通过 tls-replication 和 sentinel 自身的 TLS 配置来完成,确保监控和选举过程不被劫持。
