Redis 默认通过 6379 端口提供明文 TCP 通信,所有命令、参数和返回值都以未加密的形式在网络中传输。无论是使用 AUTH 提交的密码,还是写入缓存的用户会话、订单信息,只要链路中存在抓包点,这些数据都能被直接还原。对于部署在公网、跨机房或容器网络中的 Redis 实例来说,仅靠防火墙和私有网络并不足以防止中间人窃听。要解决这个问题,可以启用 Redis 自带的 TLS 加密传输能力,它基于 OpenSSL 完成握手与数据加密,配合证书机制还能验证服务端身份。配置过程主要包含三步:生成或获取证书、修改 redis.conf 中的 TLS 参数、使用支持 TLS 的客户端连接验证。

下面从证书准备、服务端配置、客户端连接三个层面展开,并补充双向认证与常见问题排查。
一、确认 Redis 的 TLS 支持能力
Redis 的 TLS 并非所有安装包都默认启用。如果你使用 Linux 发行版自带的 redis-server,一般已经编译了 TLS 支持,可通过 redis-server --version 查看版本信息,再使用 redis-cli --tls --help 判断是否存在 TLS 相关参数。若命令提示无法识别 --tls,则需要重新编译或更换安装源。
源码编译时,需要显式加入 BUILD_TLS=yes 参数。以常见流程为例,解压源码后执行 make BUILD_TLS=yes,再执行 make install。依赖方面要求系统安装 OpenSSL 开发库,例如 Debian/Ubuntu 下的 libssl-dev,CentOS/RHEL 下的 openssl-devel。如果用的是容器镜像,建议直接选择官方镜像或已经启用 TLS 的镜像,避免后续因动态链接库缺失导致启动失败。
redis-server --version redis-cli --tls --help | head -n 5
确认完成后,可以先规划证书目录。通常将 CA 证书、服务端证书和私钥放在 /etc/redis/tls/ 目录中,并确保运行 Redis 的用户对该目录有读取权限。不要在 /tmp 下长期存放私钥,因为临时目录的访问控制较松,容易造成私钥泄露。
二、生成证书并配置 redis.conf
对于内部测试或小规模生产环境,可以使用 OpenSSL 生成一套私有证书体系。核心思路是先生成 CA 根证书,再用 CA 签发服务端证书,最后将私钥和证书文件路径填入 redis.conf。下面命令中 subj 的 CN 字段需要与服务端实际访问地址保持一致,如果客户端通过 IP 连接,证书应包含 IP SAN 扩展,否则客户端可能因主机名不匹配而拒绝连接。
# 生成 CA 私钥和自签名根证书 openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "/CN=Redis Test CA" # 生成服务端私钥和证书签名请求 openssl genrsa -out redis.key 2048 openssl req -new -key redis.key -out redis.csr -subj "/CN=redis-server" # 使用 CA 签发服务端证书 openssl x509 -req -in redis.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out redis.crt -days 825 -sha256 # 收紧私钥权限 chmod 600 redis.key
上述命令生成的是自签名 CA 和由该 CA 签发的服务端证书。若已有受信任的第三方证书,可将 redis.crt 换成完整证书链文件,顺序通常是服务端证书在前、中间 CA 在后。Redis 读取证书时不会自动拼接链,因此需要手动将多段 PEM 文本合并到同一个文件中。
随后修改 redis.conf,核心参数包括 tls-port、tls-cert-file、tls-key-file、tls-ca-cert-file 和 tls-auth-clients。如果要彻底关闭明文端口,将 port 设为 0,并只保留 tls-port 6379,这样所有客户端都必须通过 TLS 接入。
# 关闭明文监听 port 0 tls-port 6379 # 服务端证书与私钥 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 # 先允许客户端不提供证书,仅加密传输 tls-auth-clients no # 限制协议版本并优先服务端密码套件 tls-protocols "TLSv1.2 TLSv1.3" tls-prefer-server-ciphers yes tls-session-caching yes
其中 tls-auth-clients no 表示服务端只向客户端出示证书,客户端不必提供自己的证书,这种模式适合大多数单向 TLS 场景。若设为 yes 则必须为每个客户端签发证书,形成双向认证。设置完成后执行 redis-server /etc/redis/redis.conf 启动,再通过 redis-cli --tls 验证即可。
需要特别留意证书路径和私钥权限。Redis 经常以专用的 redis 用户运行,如果私钥文件权限是 600 但所属用户是 root,redis 用户可能无法读取。建议将证书目录设为 750,私钥文件设为 640 并将组归属到 redis 组,或直接用 chown redis:redis 调整归属。
三、客户端连接与语言库配置
命令行验证是最直接的检查方式。对于自签名 CA 场景,客户端需要显式指定 CA 证书路径,否则无法验证服务端证书的签发链。连接命令如下:
redis-cli --tls \ --cacert /etc/redis/tls/ca.crt \ -h 127.0.0.1 -p 6379 \ ping
如果一切正常,命令会返回 PONG。如果只是临时测试且不想提供 CA 证书,可以添加 --insecure 参数跳过证书验证,但该方式不应出现在生产环境中,因为它会退化为只加密不认证,无法防止中间人攻击。
不同客户端库的 TLS 参数命名略有差异,但都依赖 CA 证书或 SSL 上下文。以 Python 的 redis-py 为例,可以这样创建带 TLS 的连接:
import redis
client = redis.Redis(
host="127.0.0.1",
port=6379,
ssl=True,
ssl_ca_certs="/etc/redis/tls/ca.crt"
)
print(client.ping())Java 的 Jedis 或 Lettuce 同样需要配置 SSL。Jedis 可以直接使用 Jedis(host, port, true) 并设置 SSLContext,Lettuce 则通过 RedisURI 的 setSsl(true) 和 setVerifyPeer(true) 完成。Go 语言的 go-redis 库在 Options 中设置 TLSConfig 后,客户端会自动完成握手。无论使用哪种语言,核心点都是传入可信 CA 证书,并保持连接参数与服务端端口一致。
如果客户端连接报证书验证错误,优先检查 CA 文件路径是否可读、服务端证书是否由该 CA 签发、以及服务端返回的证书链是否完整。对于使用 IP 地址连接的情况,证书还需要包含对应 IP 的 SAN 条目,否则验证会失败。生成证书时可增加 SAN 扩展,例如 -addext "subjectAltName=IP:192.168.1.10,DNS:redis.ipipp.com"。
四、双向认证与常见问题排查
双向 TLS 认证意味着客户端也必须向服务端出示证书,服务端验证通过后才允许执行命令。这在多租户环境或高安全等级系统中比较常见。配置时先生成客户端私钥和证书签名请求,再用同一 CA 签发客户端证书。服务端将 tls-auth-clients 改为 yes,客户端连接时额外提供 --cert 和 --key 参数。
# 生成客户端证书 openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr -subj "/CN=redis-client" openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256 # 客户端连接 redis-cli --tls \ --cacert /etc/redis/tls/ca.crt \ --cert /etc/redis/tls/client.crt \ --key /etc/redis/tls/client.key \ -h 127.0.0.1 -p 6379 \ ping
排查 TLS 连接问题时,可以从服务端日志和客户端报错两个方向入手。常见错误包括私钥文件权限不足、证书和私钥不匹配、CA 证书未正确拼接、协议版本被客户端拒绝等。若服务端启动时报 Can't load cert or key file,通常是路径或权限问题。若客户端提示 unable to get local issuer certificate,说明 CA 链缺失。还可以使用 openssl s_client -connect 127.0.0.1:6379 -tls1_2 直接检查握手过程,该工具能输出服务端证书链和协议协商结果,适合定位证书链问题。
性能方面,TLS 会增加每次连接握手和对称加密的 CPU 开销。对于高并发短连接场景,建议开启 tls-session-caching yes 以复用会话密钥,并尽量使用 TLSv1.3,因为它的握手往返次数更少。对于长连接场景,加密开销相对平稳,但仍建议在启用 TLS 后压测 QPS 和 P99 延迟,必要时增加 Redis 实例或优化业务连接池。安全与性能并不完全冲突,合理选择协议版本和密码套件,可以在保护数据的同时控制额外开销。
最后,TLS 只是 Redis 安全体系的一部分。启用加密传输后,仍应结合 ACL 限制命令权限、使用强密码或客户端证书进行身份认证,并禁止直接暴露公网端口。只有将传输加密、身份认证和访问控制结合起来,才能构建完整的 Redis 安全边界。