为了提高链路安全性,您可以启用SSL(Secure Sockets Layer)加密,并安装SSL CA证书到需要的应用服务。SSL在传输层对网络连接进行加密,能提升通信数据的安全性和完整性,但会同时增加网络连接响应时间。

前提条件

实例版本如下:

  • MySQL 8.0三节点企业版
  • MySQL 8.0高可用版
  • MySQL 5.7三节点企业版
  • MySQL 5.7高可用版
  • MySQL 5.6

背景信息

SSL是Netscape公司所提出的安全保密协议,在浏览器和Web服务器之间构造安全通道来进行数据传输,采用RC4、MD5、RSA等加密算法实现安全通讯。国际互联网工程任务组(IETF)对SSL 3.0进行了标准化,标准化后更名为安全传输层协议(TLS)。由于SSL这一术语更为常用,因此本文所述SSL加密实际是指TLS加密。
说明 RDS支持的TLS版本为1.0、1.1和1.2。

其他引擎设置SSL加密请参见:

注意事项

  • SSL的证书有效期为1年,请及时更新证书有效期并重新下载配置CA证书,否则使用加密连接的客户端程序将无法正常连接。
  • 由于SSL加密的实现原理,启用SSL加密会显著增加CPU使用率,建议您仅在外网链路有加密需求的时候启用SSL加密。内网链路相对较安全,一般无需对链路加密。
  • 读写分离地址不支持SSL加密。
  • 关闭SSL加密会重启实例,请谨慎操作。

开启SSL加密

  1. 访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
  2. 在左侧导航栏单击数据安全性
  3. 选择SSL标签页。
  4. 单击未开通前面的滑块开关。
  5. 在弹出的对话框中选择要开通SSL加密的地址,单击确定,开通SSL加密。
    说明 用户可以根据需要,选择加密内网链路或者外网链路,但只可以加密一条链路。
  6. 单击下载证书,下载SSL CA证书。

    下载的文件为压缩包,包含如下三个文件:

    • p7b文件:用于Windows系统中导入CA证书。
    • PEM文件:用于其他系统或应用中导入CA证书。
    • JKS文件:Java中的truststore证书存储文件,密码统一为apsaradb,用于Java程序中导入CA证书链。
      说明 在Java中使用JKS证书文件时,jdk7和jdk8需要修改默认的jdk安全配置,在应用程序所在主机的 jre/lib/security/Java.security文件中,修改如下两项配置:
      jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 224
      jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
      若不修改jdk安全配置,会报如下错误。其它类似报错,一般也都由Java安全配置导致。
      Javax.net.ssl.SSLHandshakeException: DHPublicKey does not comply to algorithm constraints

配置SSL CA证书

开通SSL加密后,应用或者客户端连接RDS时需要配置SSL CA证书。本文以MySQL Workbench和Navicat为例,介绍SSL CA证书安装方法。其它应用或者客户端请参见对应产品的使用说明。

MySQL Workbench配置方法

  1. 打开MySQL Workbench。
  2. 选择Database > Manage Connections
  3. 启用Use SSL,并导入SSL CA证书。

Navicat配置方法

  1. 打开Navicat。
  2. 在目标数据库上单击鼠标右键,选择编辑连接
  3. 选择SSL页签,选择.pem格式CA证书的路径。参照下图进行设置。
  4. 单击确定
    说明 如果报 connection is being used错误,是由于之前的会话未断开,请关闭Navicat重新打开。
  5. 双击目标数据库测试能否正常连接。

更新证书有效期

说明
  • 更新有效期操作将会重启实例,重启前请做好业务安排,谨慎操作。
  • 更新有效期后需要重新下载及配置CA证书。
更新证书有效期

关闭SSL加密

说明
  • 关闭SSL加密会重启RDS实例,系统会触发主备切换降低影响,但仍建议您在业务低峰期操作。
  • SSL加密关闭后,数据库访问性能会有一定程度提升,但安全性上有削弱,故非安全环境下不建议关闭SSL加密。
  1. 访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
  2. 在左侧导航栏单击数据安全性
  3. 选择SSL标签页。
  4. 单击已开通前面的开关,在弹出的提示框中单击确定

附录:通过SSL连接数据库示例代码

  • Java示例代码:
    <dependency>
           <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
           <version>8.0.11</version>
    </dependency>
    
    ---------------------------------------------------------demo-------------------------------------------------------------
    package com.aliyun.sample;
    
    import com.mysql.cj.jdbc.MysqlDataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    
    public class Sample {
    
        public static void main(String[] args) {
    
            Connection conn = null;
            MysqlDataSource mysqlDS=null;
    
            try{
                mysqlDS = new MysqlDataSource();
                // set useSSL=true and provide truststore for server certificate verification.
                mysqlDS.setUseSSL(true);
                mysqlDS.setClientCertificateKeyStoreType("JKS");
                // 您的ApsaraDB-CA-Chain.jks路劲 file:/D:\ApsaraDB-CA-Chain\ApsaraDB-CA-Chain.jks
                mysqlDS.setClientCertificateKeyStoreUrl("file:/D:\\xxxx\\ApsaraDB-CA-Chain.jks");
                // JAVA中密码统一为apsaradb
                mysqlDS.setClientCertificateKeyStorePassword("apsaradb");
                mysqlDS.setTrustCertificateKeyStoreType("JKS");
                // 您的ApsaraDB-CA-Chain.jks路劲 file:/D:\ApsaraDB-CA-Chain\ApsaraDB-CA-Chain.jks
                mysqlDS.setTrustCertificateKeyStoreUrl("file:/D:\\ApsaraDB-CA-Chain\\ApsaraDB-CA-Chain.jks");
                // JAVA中密码统一为apsaradb
                mysqlDS.setTrustCertificateKeyStorePassword("apsaradb");
                // 您的数据库连接串
                mysqlDS.setServerName("rm-xxxxxx.mysql.rds.aliyuncs.com");
                // 您的数据库端口
                mysqlDS.setPort(3306);
                // 您的数据库账号
                mysqlDS.setUser("xxxxxx");
                // 您的数据库密码
                mysqlDS.setPassword("xxxxxx");
                // 您的数据库名
                mysqlDS.setDatabaseName("xxxxxx");
    
                conn = mysqlDS.getConnection();
    
            }catch(Exception e){
                e.printStackTrace();
            } finally {
                try {
                    if (conn != null)
                        conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
  • Python示例代码:
    # 安装pymysql    pip install pymysql
    
    
    import pymysql
    
    try:
        conn = pymysql.connect(host='******.mysql.rds.aliyuncs.com',user='*****',passwd='******,db='*****',ssl=True,
                ssl_ca='/path/to/path/ApsaraDB-CA-Chain.pem')
        cursor = conn.cursor()
        cursor.execute('select version()')
        data = cursor.fetchone()
        print('Database version:', data[0])
        cursor.close()
    except pymysql.Error as e:
        print(e)

常见问题

SSL证书到期后不更新会有什么影响?会影响实例运行或数据安全吗?

SSL证书到期后不更新,仅会导致使用加密连接的客户端程序无法正常连接实例,不会影响实例运行或数据安全。