You need to enable JavaScript to run this app.
导航

客户端使用 SSL 加密连接 Redis

最近更新时间2023.12.20 14:29:21

首次发布时间2023.05.26 12:29:28

缓存数据库 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 版的数据库登录账号和密码:

  • 账号
    为保障数据安全性,实例创建完成后会自动创建默认账号 default。您也可以根据业务需要创建新的账号并设置账号所拥有的权限。更多信息,请参见创建与管理账号
  • 密码
    Redis 支持如下密码填写格式:
    • 直接填写密码(仅使用 default 默认账号时支持该格式)。
    • <username> <password>
    • <username>:<password>

    说明

    如果忘记密码,您可以重置密码。具体操作,请参见修改或重置密码

获取数据库连接信息

您可以参考如下步骤获取缓存数据库 Redis 版连接地址和端口号信息:

  1. 登录 Redis 控制台
  2. 在顶部菜单栏的左上角,选择实例所属的项目和地域。
  3. 在实例列表页,单击目标实例名称。
  4. 在实例详情页单击连接管理页签,即可在私网访问或公网访问区域查看对应的连接地址和端口号信息。

说明

关于 Redis 连接地址的更多说明,请参见连接地址类型

客户端 SSL 连接示例

Java

说明

下述示例代码以 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"));
        }
    }
}

Python

说明

下述示例代码以 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

说明

<?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

说明

以下示例以 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)
}