tencent cloud

文档反馈

设置 SSL 加密

最后更新时间:2024-08-19 15:51:38

    SSL 加密概述

    SSL(Secure Sockets Layer)认证是客户端到云数据库服务器端的认证,对用户和服务器进行认证。开通 SSL 加密,可获取 CA 证书,将 CA 证书上传在服务端。在客户端访问数据库时,将激活 SSL 协议,在客户端和数据库服务端之间建立一条 SSL 安全通道,实现数据信息加密传输,防止数据在传输过程中被截取、篡改、窃听,保证双方传递信息的安全性。
    SSL 协议要求建立在可靠的传输层协议(TCP)之上,其优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP、FTP、TELNET 等)能透明地建立于 SSL 协议之上。SSL 协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作,在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。

    背景

    使用非加密方式连接数据库时,在网络中传输的所有信息都是明文,因此存在被非法用户窃听、篡改、冒充的三大风险;而 SSL 协议是为解决这三大风险而设计的,理论上可达到:
    信息是加密传播,第三方无法窃听。
    具有校验机制,一旦被篡改,通信双方会立刻发现。
    配备身份证书,防止身份被冒充。
    TDSQL-C MySQL 版支持通过开启 SSL 加密来增强链路安全性,并支持下载和安装 SSL CA 证书到需要的应用服务。
    注意:
    SSL 加密不保护数据本身,是确保来往于数据库和服务器之间的流量安全,在传输层对网络连接进行加密,能够提升通信数据的安全性和完整性,但会同时增加网络连接响应时间。

    前提条件

    实例版本为 MySQL5.7/8.0。
    实例形态为预置资源或 Serverless。

    支持版本

    TDSQL-C MySQL 版使用 OpenSSL 来实现安全连接。TDSQL-C MySQL 版支持传输层安全性协议(TLS)版本1.0、1.1、1.2和1.3。TLS 支持取决于 MySQL 版本。下表显示了支持 TLS 的 MySQL 版本。
    MySQL 版本
    TLS1.0
    TLS1.1
    TLS1.2
    TLS1.3
    MySQL 5.7
    不支持
    不支持
    支持
    支持
    MySQL 8.0
    支持
    支持
    支持
    支持

    开启 SSL 加密

    1. 登录 TDSQL-C MySQL 版控制台,在集群列表,单击集群 ID,进入集群管理页面。
    2. 在集群管理页面选择数据安全页,在 SSL 下选择需要开启的读写实例或只读实例。
    
    3. 此功能状态默认为未打开,将开关调为开启,然后单击确定,开启 SSL 加密。
    
    注意:
    开启 SSL 过程中,会重启您的数据库实例以加载 SSL 证书,请确保业务具备重连机制。
    4. 单击下载,下载 SSL CA 证书,证书有效期为20年。 下载的文件为压缩包(TencentDB-SSL-CA.zip),包含如下三个文件:
    p7b 文件:用于 Windows 系统中导入 CA 证书。
    jks 文件:Java 中的 truststore 证书存储文件,密码统一为 tencentdb,用于 Java 程序中导入 CA 证书链。
    pem 文件:用于其他系统或应用中导入 CA 证书。

    配置 SSL CA 证书

    开启 SSL 加密后,使用客户端连接云数据库时需要配置 SSL CA 证书。以下以 Navicat 为例,为您介绍 SSL CA 证书安装方法。其它应用或者客户端请参见对应产品的使用说明。
    说明:
    每开启或关闭一次 SSL 加密,其证书就会新生成。
    1. 打开 Navicat。
    2. 在对应数据库上单击鼠标右键,选择编辑连接
    3. 选择 SSL 页签,选择.pem 格式 CA 证书的路径。完成对应设置后单击确定
    说明:
    如果出现 connection is being used 报错,可能由于之前的会话未断开,请关闭 Navicat 后重试。
    4. 双击对应数据库,测试能否正常连接。

    关闭 SSL 加密

    1. 登录 TDSQL-C MySQL 版控制台,在集群列表,单击集群 ID,进入集群管理页面。
    2. 在集群管理页面选择数据安全页,在 SSL 下选择需要关闭的读写实例或只读实例。
    3. 状态后的开关调为关闭,在弹出的提示框中单击确定
    说明:
    关闭 SSL 过程中,会重启您的数据库实例以卸载 SSL 证书,请确保业务具备重连机制。

    使用 MySQL 命令行客户端连接开启 SSL 加密的实例

    如果您使用的数据库版本不同,则 MySQL 客户端的连接命令参数有所不同,您可通过如下命令,先查询所使用的数据库版本,再参见后续步骤连接实例。
    SELECT VERSION();
    
    查询结果示例:
    +--------------+
    | VERSION() |
    +--------------+
    | 8.0.30-txsql |
    +--------------+
    1 row in set (0.00 sec)
    1. 通过 TDSQL-C MySQL 版控制台下载 SSL CA 证书,操作请参见 开启 SSL 加密
    2. 使用 MySQL 命令行客户端,通过命令连接开启 SSL 加密的实例。
    客户端数据库版本为 MySQL 5.7/8.0时的命令,通过如下命令连接实例。
    mysql -h <IP 地址> --ssl-ca=<ca证书路径> --ssl-mode=REQUIRED -P <端口号> -u <用户名> -p
    如果要使用其他的 SSL 模式,例如 VERIFY_CA 或 VERIFY_IDENTITY,则需要通过如下命令连接实例。
    mysql -h <IP 地址> --ssl-ca=<ca证书路径> --ssl-mode=VERIFY_CA -P <端口号> -u <用户名> -p
    说明:
    --ssl-mode 参数表示 SSL 模式,通常情况下,推荐使用 REQUIRED 和 VERIFY_CA 模式,表示要求 MySQL 客户端使用 SSL/TLS 协议连接 MySQL 服务器,并要求验证 MySQL 服务器的 SSL/TLS 证书;而 VERIFY_IDENTITY 模式除了要求验证 MySQL 服务器的 SSL/TLS 证书,还要求客户端使用的主机名与服务器证书中的标识相匹配,否则 MySQL 客户端会拒绝连接 MySQL 服务器。
    3. 根据系统提示输入对应用户名的密码。
    

    常用程序连接开启 SSL 的实例的代码示例

    PHP
    $conn = mysqli_init();
    mysqli_ssl_set($conn,NULL,NULL, "<下载的证书路径>", NULL, NULL);
    mysqli_real_connect($conn, '<数据库访问地址>', '<数据库访问用户名>', '<数据库访问密码>', '<指定访问数据库>', <访问端口>, MYSQLI_CLIENT_SSL);
    if (mysqli_connect_errno($conn)) {
    die('Failed to connect to MySQL: '.mysqli_connect_error());
    }
    PHP (Using PDO)
    $options = array(
    PDO::MYSQL_ATTR_SSL_CA => '<下载的证书路径>'
    );
    $db = new PDO('mysql:host=<数据库访问地址>;port=<访问端口>;dbname='<指定访问数据库>', '<数据库访问用户名>', '<数据库访问密码>', $options);
    Java (MySQL Connector for Java)
    # generate truststore and keystore in code
    
    String importCert = " -import "+
    " -alias mysqlServerCACert "+
    " -file " + ssl_ca +
    " -keystore truststore "+
    " -trustcacerts " +
    " -storepass password -noprompt ";
    String genKey = " -genkey -keyalg rsa " +
    " -alias mysqlClientCertificate -keystore keystore " +
    " -storepass password123 -keypass password " +
    " -dname CN=MS ";
    sun.security.tools.keytool.Main.main(importCert.trim().split("\\\\s+"));
    sun.security.tools.keytool.Main.main(genKey.trim().split("\\\\s+"));
    
    # use the generated keystore and truststore
    
    System.setProperty("javax.net.ssl.keyStore","<下载的证书路径>");
    System.setProperty("javax.net.ssl.keyStorePassword","tencentdb");
    System.setProperty("javax.net.ssl.trustStore","<下载的证书路径>");
    System.setProperty("javax.net.ssl.trustStorePassword","tencentdb");
    
    url = String.format("jdbc:mysql://%s/%s?serverTimezone=UTC&useSSL=true", '<数据库访问地址>', '<指定访问数据库>');
    properties.setProperty("user", '<数据库访问用户名>');
    properties.setProperty("password", '<数据库访问密码>');
    conn = DriverManager.getConnection(url, properties);
    .NET (MySqlConnector)
    var builder = new MySqlConnectionStringBuilder
    {
    Server = "<数据库访问地址>",
    UserID = "<数据库访问用户名>",
    Password = "<数据库访问密码>",
    Database = "<指定访问数据库>",
    SslMode = MySqlSslMode.VerifyCA,
    SslCa = "<下载的证书>",
    };
    using (var connection = new MySqlConnection(builder.ConnectionString))
    {
    connection.Open();
    }
    Python (MySQLConnector Python)
    try:
    conn = mysql.connector.connect(user='<数据库访问用户名>',
    password='<数据库访问密码>',
    database='<指定访问数据库>',
    host='<数据库访问地址>',
    ssl_ca='<下载的证书路径>')
    except mysql.connector.Error as err:
    print(err)
    Python (PyMySQL)
    conn = pymysql.connect(user='<数据库访问用户名>',
    password='<数据库访问密码>',
    database='<指定访问数据库>',
    host='<数据库访问地址>',
    ssl={'ca': '<下载的证书路径>'})
    Django (PyMySQL)
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': '<指定访问数据库>',
    'USER': '<数据库访问用户名>',
    'PASSWORD': '<数据库访问密码>',
    'HOST': '<数据库访问地址>',
    'PORT': '<访问端口>',
    'OPTIONS': {
    'ssl': {'ca': '<下载的证书路径>'}
    }
    }
    }
    Node.js
    var fs = require('fs');
    var mysql = require('mysql');
    const serverCa = [fs.readFileSync("<下载的证书路径>", "utf8")];
    var conn=mysql.createConnection({
    host:"<数据库访问地址>",
    user:"<数据库访问用户名>",
    password:"<数据库访问密码>",
    database:"<指定访问数据库>",
    port:<访问端口>,
    ssl: {
    rejectUnauthorized: true,
    ca: serverCa
    }
    });
    conn.connect(function(err) {
    if (err) throw err;
    });
    Golang
    rootCertPool := x509.NewCertPool()
    pem, _ := ioutil.ReadFile("<下载的证书路径>")
    if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
    log.Fatal("Failed to append PEM.")
    }
    mysql.RegisterTLSConfig("custom", &tls.Config{RootCAs: rootCertPool})
    var connectionString string
    connectionString = fmt.Sprintf("%s:%s@tcp(%s:<访问端口>)/%s?allowNativePasswords=true&tls=custom","<数据库访问用户名>" , "<数据库访问密码>", "<数据库访问地址>", '<指定访问数据库>')
    db, _ := sql.Open("mysql", connectionString)
    Ruby
    client = Mysql2::Client.new(
    :host => '<数据库访问地址>',
    :username => '<数据库访问用户名>',
    :password => '<数据库访问密码>',
    :database => '<指定访问数据库>',
    :sslca => '<下载的证书路径>'
    )
    
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持