缓存数据库 Redis 版提供了 SSL(Secure Sockets Layer)加密服务,您可以提前开启 SSL 加密功能,在连接数据库时,通过设置 SSL 加密提高数据链路的安全性。本文介绍多语言客户端通过 SSL 加密连接来访问 Redis 数据库的具体方法。
通过私网访问 Redis 实例相对较安全,一般无需对数据链路加密。使用 SSL 加密连接会增加 Redis 服务的网络响应时间,建议仅在有加密需求时(例如通过公网连接 Redis 实例时)才开通 SSL 加密。
客户端使用 SSL 加密连接 Redis 数据库之前,您需要完成如下准备工作。
准备工作 | 说明 |
---|---|
为 Redis 设置 SSL 加密 | 为目标 Redis 实例开启 SSL 加密功能,并下载 SSL CA 证书。具体操作步骤,请参见设置 SSL 加密。 |
为 Redis 设置白名单 | 将安装了客户端的本地服务器或 ECS 实例的 IP 地址加入到 Redis 实例的白名单中。详细操作步骤,请参见设置白名单。 说明 若您的客户端设备和 Redis 实例不在同一个 VPC 内,您还要为 Redis 实例开启公网访问。开启公网访问的方法,请参见开启公网访问。 |
获取数据库账号信息 | 您可以参考如下步骤获取缓存数据库 Redis 版的数据库登录账号和密码: |
获取数据库连接信息 | 您可以参考如下步骤获取缓存数据库 Redis 版连接地址和端口号信息:
说明 关于 Redis 连接地址的更多说明,请参见连接地址类型。 |
说明
下述示例代码以 Jedis 客户端的 3.6.0 版本为例,推荐使用最新版本。
import java.io.FileInputStream; import java.io.InputStream; import java.security.KeyStore; import java.security.SecureRandom; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class JedisSSLTest { private static SSLSocketFactory createTrustStoreSSLSocketFactory(String jksFile) throws Exception { KeyStore trustStore = KeyStore.getInstance("jks"); InputStream inputStream = null; try { inputStream = new FileInputStream(jksFile); trustStore.load(inputStream, null); } finally { inputStream.close(); } TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); trustManagerFactory.init(trustStore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagers, new SecureRandom()); return sslContext.getSocketFactory(); } public static void main(String[] args) throws Exception { // redis-shzl8lsda9uaa****_ca_certificate.jks为证书文件名称。 final SSLSocketFactory sslSocketFactory = createTrustStoreSSLSocketFactory("redis-shzl8lsda9uaa****_ca_certificate.jks"); // 连接池的设置分别为实例的连接地址、端口号、超时设置、密码。 JedisPool pool = new JedisPool(new GenericObjectPoolConfig(), "redis-shzl8lsda9uaa****.redis.ivolces.com", 6379, 2000, "SslTest:Pwd@1234", 0, true, sslSocketFactory, null, null); try (Jedis jedis = pool.getResource()) { jedis.set("key", "value"); System.out.println(jedis.get("key")); } } }
说明
下述示例代码以 redis-py 客户端为例,推荐使用最新版本。
连接池连接
#!/bin/pythonimport redis # 设置连接池,分别将host、port、password的值分别替换为实例的连接地址、端口号、密码。 # redis-shzl8lsda9uaa****_ca_certificate.pem为证书文件名称。 pool = redis.ConnectionPool(connection_class=redis.connection.SSLConnection, max_connections=100, host="redis-shzl8lsda9uaa****.redis.ivolces.com", port=6379, password="SslTest:Pwd@1234", ssl_cert_reqs=True, ssl_ca_certs="redis-shzl8lsda9uaa****_ca_certificate.pem") client = redis.Redis(connection_pool=pool) client.set("hi", "redis") print client.get("hi")
普通连接
#!/bin/python import redis # 设置连接信息,分别将host、port、password的值分别替换为实例的连接地址、端口号、密码。 # redis-shzl8lsda9uaa****_ca_certificate.pem为证书文件名称。 client = redis.Redis(host="redis-shzl8lsda9uaa****.redis.ivolces.com", port=6379, password="SslTest:Pwd@1234", ssl=True, ssl_cert_reqs="required", ssl_ca_certs="redis-shzl8lsda9uaa****_ca_certificate.pem") client.set("hello", "world") print client.get("hello")
说明
<?php require __DIR__.'/predis/autoload.php'; /* 设置连接信息,分别将host、port、password的值分别替换为实例的连接地址、端口号、密码 redis-shzl8lsda9uaa****_ca_certificate.pem为证书文件名称*/ $client = new Predis\Client([ 'scheme' => 'tls', 'host' => 'redis-shzl8lsda9uaa****.redis.ivolces.com', 'port' => 6379, 'password' => 'SslTest:Pwd@1234', 'ssl' => ['cafile' => 'redis-shzl8lsda9uaa****_ca_certificate.pem', 'verify_peer' => true, 'verify_peer_name' => false], ]); $client->set("hello", "world"); print $client->get("hello")."\n";
说明
以下示例以 go-redis 客户端为例,推荐使用最新版本。
package main import ( "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "github.com/go-redis/redis" ) func main() { // redis-shzl8lsda9uaa****_ca_certificate.pem为证书文件路径 bytes, err := ioutil.ReadFile("redis-shzl8lsda9uaa****_ca_certificate.pem") if err != nil { fmt.Printf("err:%v\n", err) return } pool := x509.NewCertPool() pool.AppendCertsFromPEM(bytes) tlsConfig := &tls.Config{ RootCAs: pool, // 校验证书的主机名,使用私网地址即可 ServerName: "redis-shzl8lsda9uaa****.redis.ivolces.com", } // 实例的连接地址 addr := "redis-shzl8lsda9uaa****.redis.ivolces.com" // 实例密码 password := "SslTest:Pwd@1234" client := redis.NewClient(&redis.Options{ Addr: addr, TLSConfig: tlsConfig, Password: password, }) err = client.Set("hello", "world", 0).Err() if err != nil { fmt.Printf("err:%v\n", err) return } val, err := client.Get("hello").Result() if err != nil { fmt.Printf("err:%v\n", err) return } fmt.Printf("val:%s\n", val) }