使用加密连接

使用加密连接

MySQL 支持使用 TLS (Transport Layer Security,传输层安全性) 协议在客户端和服务器之间进行加密连接。

TLS 有时被称为 SSL (Secure Sockets Layer,安全套接字层) ,但是 MySQL 实际上并不使用 SSL 协议进行加密连接,因为它的加密很弱。

MySQL 支持由 OpenSSL 提供的加密连接。

默认情况下,如果服务器支持加密连接,则 MySQL 程序会尝试使用加密连接,如果无法建立加密连接,则会退回到未加密连接。

MySQL 在每个连接的基础上执行加密,并且可以对指定用户强制使用加密连接。

概要

TLS 协议

  • 使用加密算法来确保可以信任通过公共网络接收的数据
  • 它具有检测数据更改、丢失或重放的机制
  • 合并了使用 X.509 标准提供身份验证的算法

X.509 标准

  • X.509 使得识别 Internet 上的某人成为可能
  • 从根本上说,应该有一个称为证书颁发机构 (或 CA) 的实体,它将实体电子证书分配给需要它们的任何人。
  • 证书依赖于具有两个加密密钥 (公钥和私钥) 的非对称加密算法。
  • 证书所有者可以将证书出示给另一方作为身份证明。
    • 证书由其所有者的公钥组成
    • 使用此公钥加密的任何数据都只能使用相应私钥来解密

配置加密连接

服务器端启动配置

  • 系统变量
    • 启用 SSL
      • ssl
        • 控制服务器是否允许加密连接。默认已启用。
      • require_secure_transport
        • 要求客户端使用加密连接
    • 证书和密钥文件
      • ssl_ca
        • 证书颁发机构 (CA) 证书文件
      • ssl_capath
        • CA 证书文件目录
      • ssl_cert
        • 服务器公钥证书文件
        • 可以将此证书发送到客户端,并根据其拥有的 CA 证书进行身份验证
      • ssl_key
        • 服务器私钥文件
    • 服务器端加密连接控制

      如果服务器无法通过系统变量为服务器端加密连接控制创建有效的 TLS 上下文,则服务器将不使用加密连接。

      • ssl_crl
        • 包含证书吊销列表的文件的路径名
      • ssl_crlpath
        • 指定证书吊销列表文件目录的路径名
      • ssl_cipher
        • 连接加密的允许密码列表
      • tls_version, tls_ciphersuites
        • 服务器允许哪种加密协议和密码套件进行加密连接
  • 服务器使用的证书和密钥文件
    [mysqld]
    ssl_ca=ca.pem
    ssl_cert=server-cert.pem
    ssl_key=server-key.pem
    require_secure_transport=ON
    
    • 文件格式
      • .pem
    • 自签名证书
      • 由服务器自动创建的,或者是使用 mysql_ssl_rsa_setup 手动创建的证书。
      • 换句话说,就是自己创建的证书,而不是权威机构颁发的证书。
    • 服务器会自动发现证书和密钥文件
      • 如果未显式指定证书和密钥文件 (除 ssl 和 ssl_cipher),则服务器将在启动时自动启用加密连接
      • 发现过程
        • 如果服务器在数据目录中发现名为 ca.pem,server-cert.pem 和 server-key.pem 的有效证书和密钥文件,则将启用加密连接
        • 如果服务器在数据目录中找不到有效的证书和密钥文件,则不使用加密连接
    • 错误日志中的记录
      • 如果服务器自动启用加密连接支持,它将在错误日志中写入注释。
      • 如果服务器发现 CA 证书是自签名的,它将在错误日志中写入警告

服务器端动态配置和监控

  • 系统变量
    • ssl_ca
    • ssl_capath
    • ssl_cert
    • ssl_cipher
    • ssl_crl
    • ssl_crlpath
    • ssl_key
    • tls_ciphersuites
    • tls_version
  • 状态变量
    • Current_tls_xxx
      • 与上面的系统变量相对应
  • 性能表
    • performance_schema.tls_channel_status
      mysql> select * from performance_schema.tls_channel_status limit 10;
      +------------+--------------------------+--------+
      | CHANNEL    | PROPERTY                 | VALUE  |
      +------------+--------------------------+--------+
      | mysql_main | Enabled                  | Yes    |
      | mysql_main | Ssl_accept_renegotiates  | 0      |
      | mysql_main | Ssl_accepts              | 0      |
      | mysql_main | Ssl_callback_cache_hits  | 0      |
      | mysql_main | Ssl_client_connects      | 0      |
      | mysql_main | Ssl_connect_renegotiates | 0      |
      | mysql_main | Ssl_ctx_verify_depth     | -1     |
      | mysql_main | Ssl_ctx_verify_mode      | 5      |
      | mysql_main | Current_tls_ca           | ca.pem |
      | mysql_main | Current_tls_capath       |        |
      +------------+--------------------------+--------+
      
  • 配置过程
    • 设置 TLS 相关的系统变量
      • 服务器为管理连接接口实现了独立的连接加密配置。
    • 重新加载 TLS 系统变量和状态变量
      mysql> ALTER INSTANCE RELOAD TLS
      
      • 所需权限
        • CONNECTION_ADMIN
      • 由于重新配置过程的工作方式,每对系统变量和状态变量的成员可能暂时具有不同的值

        在 ALTER INSTANCE RELOAD TLS 之前即使更改了 TLS 系统变量,也不会对新连接造成影响,此时就会导致相应的系统和状态变量具有不同的值。

        在 ALTER INSTANCE RELOAD TLS 之后,相应的系统变量和状态变量具有相同的值。

      • 在某些情况下,ALTER INSTANCE RELOAD TLS 本身可能足以重新配置 TLS 上下文,而无需更改任何系统变量

        假设 ssl_cert 命名的文件中的证书已过期。用未过期的证书替换现有文件内容并执行 ALTER INSTANCE RELOAD TLS 足以读取新文件内容并将其用于新连接。

      • 此外,ALTER INSTANCE RELOAD TLS 扩展了 FOR CHANNEL 子句

        • 该子句允许指定要为其重新加载 TLS 上下文的通道 (接口)
        • 查看
          • performance_schema.tls_channel_status
      • 默认情况下,如果配置值不允许创建新的 TLS 上下文,则 RELOAD TLS 操作会回滚并显示错误

        如果给出了可选的 NO ROLLBACK ON ERROR 子句,并且无法创建新的上下文,则不会发生回滚。而是会生成一条警告,并对该语句所应用的接口上的新连接禁用加密。

客户端的配置

默认情况下,如果服务器支持加密连接,则 MySQL 客户端程序会尝试建立加密连接,并通过 –ssl-mode 选项提供进一步的控制。

  • 系统变量
    • require_secure_transport
      • 服务器端配置,要求客户端必须使用加密连接
  • 客户端选项
    • 启用 SSL
      • –ssl-mode
        • 控制客户端的加密连接
        • 选项值
          • PREFFERED
            • (默认) 客户端尝试使用加密进行连接,如果无法建立加密连接,则会退回到未加密的连接
            • 如果未指定 –ssl-mode 选项,也是如此
          • REQUIRED
            • 客户端需要加密的连接,如果无法建立则失败
          • DISABLED
            • 客户端使用未加密的连接
          • VERIFY_CA
            • 客户端需要加密的连接,并且对服务器 CA 证书进行验证
          • VERIFY_IDENTITY
            • 客户端需要加密的连接,并且对其证书中的服务器主机名进行验证
    • 客户端使用的证书和密钥文件
      • –ssl-capath
        • 指定 CA 证书文件目录的路径名
      • –ssl-ca
        • 证书颁发机构 (CA) 证书文件
        • 如果使用此选项,则必须指定服务器使用的相同证书
      • –ssl-cert
        • 客户端公钥证书文件
      • –ssl-key
        • 客户端私钥文件
    • 客户端加密连接控制
      • –ssl-crlpath
        • 指定证书吊销列表文件目录的路径名
      • –ssl-cipher
        • 连接加密的允许密码列表
      • –ssl-crl
        • 包含证书吊销列表的文件的路径名
      • –tls-version, –tls-ciphersuites
        • 服务器允许哪种加密协议和密码套件进行加密连接
  • 进一步提高安全性

    为了获得更高的安全性,客户端可以指定 CA 证书,并启用主机名身份验证。
    通过这种方式,服务器和客户端将他们的信任放在相同的 CA 证书中,并且客户端验证它所连接的主机是否是预期的主机。

    • 指定 CA 证书
      • –ssl-ca, –ssl-capath
      • –ssl-mode = VERIFY_CA
    • 启用主机名身份验证
      • –ssl-mode = VERIFY_IDENTITY
      • 使用 VERIFY_IDENTITY 进行的主机名身份验证不适用于自签名证书。此类自签名证书不包含服务器名称作为通用名称值。
  • 配置示例
    • 对于使用 REQUIRE SSL 子句创建的账户
      mysql
      or
      mysql --ssl-mode=PREFERRED
      
    • 对于使用 REQUIRE X509 子句创建的帐户
      mysql --ssl-ca=ca.pem
            --ssl-cert=client-cert.pem
            --ssl-key=client-key.pem
      
      • 客户端必须至少指定 –ssl-cert 和 –ssl-key
      • 另外,建议使用 –ssl-ca 或 –ssl-capath ,以便可以验证服务器提供的公共证书
    • 明确指定需要加密连接,避免回退到未加密连接
      mysql --ssl-mode=REQUIRED
      
    • 对于使用 REQUIRE ISSUER 或 REQUIRE SUBJECT 子句创建的帐户
      • 加密要求与 REQUIRE X509 相同,但是证书必须分别与帐户定义中指定的问题或主题匹配。
    • 禁用加密连接
      mysql --ssl-mode=DISABLED
      
  • 查看与服务器的连接是否加密
    • 状态变量
      • Ssl_cipher
        mysql> SHOW SESSION STATUS LIKE 'Ssl_cipher';
        +---------------+---------------------------+
        | Variable_name | Value                     |
        +---------------+---------------------------+
        | Ssl_cipher    | DHE-RSA-AES128-GCM-SHA256 |
        +---------------+---------------------------+
        
    • 客户端命令
      • STATUS, \s
        mysql> \s
        ...
        SSL: Not in use
        or
        mysql> \s
        ...
        SSL: Cipher in use is DHE-RSA-AES128-GCM-SHA256
        

强制使用加密连接

分为以下控制级别:

  • 要求客户端使用加密连接
    • 系统变量
      • require_secure_transport=ON
        • 启用此变量后,要求与服务器的客户端连接使用安全传输
        • 服务器拒绝不安全的连接尝试,该尝试失败并显示 ER_SECURE_TRANSPORT_REQUIRED 错误
  • 调用单个客户端程序以要求加密连接
    • 选项
      • –ssl-mode
        • 使用选项值:REQUIRED,VERIFY_CA 或 VERIFY_IDENTITY
          mysql --ssl-mode=REQUIRED
          mysqldump --ssl-mode=VERIFY_CA
          mysqladmin --ssl-mode=VERIFY_IDENTITY
          
  • 将单个 MySQL 帐户配置为仅在加密连接上可用
    • 在创建帐户的 CREATE USER 语句中包括 REQUIRE 子句,并在该子句中指定所需的加密特征
      CREATE USER 'jeffrey'@'localhost' REQUIRE X509;
      
    • 如果将普通账户改为加密账户,使用 ALTER USER 语句

加密连接 TLS 协议和密码

MySQL 支持使用 TLSv1,TLSv1.1,TLSv1.2 和 TLSv1.3 协议的加密连接,安全性依次增加。

影响因素

实际受支持的协议受多种因素影响。

  • MySQL 配置
    • 可以在服务器端和客户端上都配置允许的 TLS 协议。双方的配置必须至少包含一个共同的协议,否则连接尝试无法协商要使用的协议。
  • 系统范围的主机配置
    • 主机系统可能仅允许某些 TLS 协议,这意味着即使 MySQL 本身允许它们,连接也可能失败

      假设 MySQL 配置允许 TLSv1,TLSv1.1 和 TLSv1.2,但是主机系统配置仅允许使用 TLSv1.2 或更高版本的连接。在这种情况下,即使将 MySQL 配置为允许使用 TLSv1 或 TLSv1.1 的 MySQL 连接,也无法建立。

      如果 MySQL 配置允许 TLSv1,TLSv1.1 和 TLSv1.2,但是主机系统配置仅允许使用 TLSv1.3 或更高版本的连接,则无法建立 MySQL 连接。

    • 解决方法

      • 更改系统范围的主机配置,以允许其他 TLS 协议
        shell> vim /etc/ssl/openssl.cnf
        [system_default_sect]
        MinProtocol = TLSv1.2
        

        Note: 将值更改为较低的协议版本或 “” 会使系统更宽松。缺点就是不安全。

      • 更改 MySQL 应用程序以使用主机系统允许的更高的 TLS 协议

  • SSL 库

    • 如果 SSL 库不支持特定协议,则 MySQL 以及下面讨论中指定该协议的任何部分均不适用
    • TLSv1.3 协议的支持
      • MySQL 版本最低是 8.0.16
      • OpenSSL 版本最低是 1.1.1

连接 TLS 协议配置

  • 系统变量
    • tls_version
      • MySQL 服务器允许进行加密连接的 TLS 协议

      • 协议列表

        [mysqld]
        tls_version=TLSv1.1,TLSv1.2
        
        • TLSv1,TLSv1.1,TLSv1.2 和 TLSV1.3

          TLSv1,TLSv1.1 已弃用,将来会删除。建议使用 TLSv1.2 和 TLSv1.3。

        • 不区分大小写

        • 多个协议之间使用逗号分隔

        • 避免在列表中留下漏洞,协议应该连续

          # 正确示例
          tls_version=TLSv1,TLSv1.1,TLSv1.2,TLSv1.3
          tls_version=TLSv1.1,TLSv1.2,TLSv1.3
          tls_version=TLSv1.2,TLSv1.3
          tls_version=TLSv1.3
          
          # 错误示例
          tls_version=TLSv1,TLSv1.2       (TLSv1.1 is missing)
          tls_version=TLSv1.1,TLSv1.3     (TLSv1.2 is missing)
          
        • 如果设置为 “”,则无法建立加密连接

        • 默认情况下,此变量列出用于编译 MySQL 的 SSL 库支持的所有协议

      • 对于复制

        • CHANGE REPLICATION SOURCE TO
          • 选项
            • SOURCE_TLS_VERSION
        • CHANGE MASTER TO
          • 选项
            • MASTER_TLS_VERSION
      • 对于组复制的分布式恢复连接
        • group_replication_recovery_tls_version
          • 指定客户端允许哪些协议
    • admin_tls_version
      • 管理连接接口允许进行加密连接的 TLS 协议

连接密码配置

在建立连接的过程中,连接的两端必须允许使用某些共同的密码,否则连接将失败。

在双方通用的允许密码中,SSL 库选择所提供证书支持的具有最高优先级的密码。

  • 系统变量
    • ssl_cipher
      • 允许的密码
      • 对于复制
        • CHANGE REPLICATION SOURCE TO
          • 选项
            • SOURCE_SSL_CIPHER
        • CHANGE MASTER TO
          • 选项
            • MASTER_SSL_CIPHER
      • 对于组复制的分布式恢复连接
        • group_replication_recovery_ssl_cipher
    • tls_ciphersuites
      • 允许的密码套件

      • 默认值

        • 对于使用 TLSv1.3 的加密连接,OpenSSL 1.1.1 和更高版本支持以下密码套件,默认情况下启用前三个密码套件
          TLS_AES_128_GCM_SHA256
          TLS_AES_256_GCM_SHA384
          TLS_CHACHA20_POLY1305_SHA256
          TLS_AES_128_CCM_SHA256
          TLS_AES_128_CCM_8_SHA256
          
        • 如果未设置此变量,则其默认值为 NULL,这意味着服务器允许使用默认的密码套件集

      • 对于复制

        • CHANGE REPLICATION SOURCE TO
          • 选项
            • SOURCE_TLS_CIPHERSUITES
        • CHANGE MASTER TO
          • 选项
            • MASTER_TLS_CIPHERSUITES
      • 对于组复制的分布式恢复连接
        • group_replication_recovery_tls_ciphersuites
  • 查看服务器支持的密码
    • 状态变量
      • Ssl_cipher_list
        SHOW SESSION STATUS LIKE 'Ssl_cipher_list';
        
    • TLSv1.2 以前的 TLS 协议,默认密码列表
      ECDHE-ECDSA-AES128-GCM-SHA256
      ECDHE-ECDSA-AES256-GCM-SHA384
      ECDHE-RSA-AES128-GCM-SHA256
      ECDHE-RSA-AES256-GCM-SHA384
      ECDHE-ECDSA-AES128-SHA256
      ECDHE-RSA-AES128-SHA256
      ECDHE-ECDSA-AES256-SHA384
      ECDHE-RSA-AES256-SHA384
      DHE-RSA-AES128-GCM-SHA256
      DHE-DSS-AES128-GCM-SHA256
      DHE-RSA-AES128-SHA256
      DHE-DSS-AES128-SHA256
      DHE-DSS-AES256-GCM-SHA384
      DHE-RSA-AES256-SHA256
      DHE-DSS-AES256-SHA256
      ECDHE-RSA-AES128-SHA
      ECDHE-ECDSA-AES128-SHA
      ECDHE-RSA-AES256-SHA
      ECDHE-ECDSA-AES256-SHA
      DHE-DSS-AES128-SHA
      DHE-RSA-AES128-SHA
      TLS_DHE_DSS_WITH_AES_256_CBC_SHA
      DHE-RSA-AES256-SHA
      AES128-GCM-SHA256
      DH-DSS-AES128-GCM-SHA256
      ECDH-ECDSA-AES128-GCM-SHA256
      AES256-GCM-SHA384
      DH-DSS-AES256-GCM-SHA384
      ECDH-ECDSA-AES256-GCM-SHA384
      AES128-SHA256
      DH-DSS-AES128-SHA256
      ECDH-ECDSA-AES128-SHA256
      AES256-SHA256
      DH-DSS-AES256-SHA256
      ECDH-ECDSA-AES256-SHA384
      AES128-SHA
      DH-DSS-AES128-SHA
      ECDH-ECDSA-AES128-SHA
      AES256-SHA
      DH-DSS-AES256-SHA
      ECDH-ECDSA-AES256-SHA
      DHE-RSA-AES256-GCM-SHA384
      DH-RSA-AES128-GCM-SHA256
      ECDH-RSA-AES128-GCM-SHA256
      DH-RSA-AES256-GCM-SHA384
      ECDH-RSA-AES256-GCM-SHA384
      DH-RSA-AES128-SHA256
      ECDH-RSA-AES128-SHA256
      DH-RSA-AES256-SHA256
      ECDH-RSA-AES256-SHA384
      ECDHE-RSA-AES128-SHA
      ECDHE-ECDSA-AES128-SHA
      ECDHE-RSA-AES256-SHA
      ECDHE-ECDSA-AES256-SHA
      DHE-DSS-AES128-SHA
      DHE-RSA-AES128-SHA
      TLS_DHE_DSS_WITH_AES_256_CBC_SHA
      DHE-RSA-AES256-SHA
      AES128-SHA
      DH-DSS-AES128-SHA
      ECDH-ECDSA-AES128-SHA
      AES256-SHA
      DH-DSS-AES256-SHA
      ECDH-ECDSA-AES256-SHA
      DH-RSA-AES128-SHA
      ECDH-RSA-AES128-SHA
      DH-RSA-AES256-SHA
      ECDH-RSA-AES256-SHA
      DES-CBC3-SHA
      
      • 这些密码受到适当限制
        • 以下密码受到永久限制
          !DHE-DSS-DES-CBC3-SHA
          !DHE-RSA-DES-CBC3-SHA
          !ECDH-RSA-DES-CBC3-SHA
          !ECDH-ECDSA-DES-CBC3-SHA
          !ECDHE-RSA-DES-CBC3-SHA
          !ECDHE-ECDSA-DES-CBC3-SHA
          
        • 下列类别的密码受到永久限制
          !aNULL
          !eNULL
          !EXPORT
          !LOW
          !MD5
          !DES
          !RC2
          !RC4
          !PSK
          !SSLv3
          
      • 如果使用了受限制的密码启动服务器,则服务器将禁用对加密连接的支持

协商过程

MySQL 中的连接尝试协商使用双方都可以使用的最高 TLS 协议版本,并且双方都可以使用协议兼容的加密密码。

如果服务器和客户端没有共同的允许协议,并且没有共同的协议兼容密码,则服务器将终止连接请求。

协商过程取决于多种因素:

  • 为了成功进行连接,服务器和客户端
    • TLS 协议配置必须允许某些通用协议
    • 加密密码配置必须允许一些共同的密码
  • 如果 TLSv1.3 可用,会优先使用

    这意味着服务器和客户端配置都必须允许 TLSv1.3,并且都必须允许某些与 TLSv1.3 兼容的加密密码。

    否则,MySQL 会继续浏览可用协议列表,并在可能的情况下使用 TLSv1.2,依此类推。

    • 协商顺序与配置协议的顺序无关
  • TLSv1.2 不适用于密钥大小为512位或更小的所有密码

  • 为了获得更好的安全性,请使用 RSA 密钥大小至少为2048位的证书

查看 TLS 协议和密码

  • 状态变量

    • Ssl_version
    • Ssl_cipher
  • 性能表
    • performance_schema.session_status
      mysql> SELECT * FROM performance_schema.session_status
             WHERE VARIABLE_NAME IN ('Ssl_version','Ssl_cipher');
      +---------------+---------------------------+
      | VARIABLE_NAME | VARIABLE_VALUE            |
      +---------------+---------------------------+
      | Ssl_cipher    | DHE-RSA-AES128-GCM-SHA256 |
      | Ssl_version   | TLSv1.2                   |
      +---------------+---------------------------+
      

创建 SSL 和 RSA 证书和密钥

SSL 证书和密钥文件使 MySQL 支持使用 SSL 的加密连接。

RSA 密钥文件使 MySQL 支持通过 sha256_password 或 caching_sha2_password 插件认证的帐户通过未加密的连接进行安全的密码交换。

使用 MySQL 创建

使用 MySQL 自身生成的文件降低了 SSL 的使用障碍,但是生成的证书是自签名的,不安全。

  • 自动生成 SSL 和 RSA 文件

    对于使用 OpenSSL 编译的 MySQL 发行版,MySQL 服务器具有在启动时自动生成丢失的 SSL 和 RSA 文件的功能。

    • 系统变量
      • auto_generate_certs
        • 控制服务器启动时自动生成缺失的证书和文件
      • sha256_password_auto_generate_rsa_keys
        • 控制服务器启动时自动生成 RSA 密钥对
      • caching_sha2_password_auto_generate_rsa_keys
        • 控制服务器启动时自动生成 RSA 密钥对
    • 自动生成 SSL 文件
      • 服务器在数据目录中检查以下 SSL 文件
        ca.pem
        server-cert.pem
        server-key.pem
        
        • 如果存在这些文件中的任何一个,则服务器不会创建 SSL 文件。否则,它将创建它们以及一些其他文件
          ca.pem               Self-signed CA certificate
          ca-key.pem           CA private key
          server-cert.pem      Server certificate
          server-key.pem       Server private key
          client-cert.pem      Client certificate
          client-key.pem       Client private key
          
      • 如果服务器自动生成 SSL 文件,它将使用 ca.pem,server-cert.pem 和 server-key.pem 文件的名称来设置相应的系统变量
        • ssl_ca
        • ssl_cert
        • ssl_key
    • 自动生成 RSA 密钥对
      • 前提
        • 启用了系统变量
          • sha256_password_auto_generate_rsa_keys
          • caching_sha2_password_auto_generate_rsa_keys
        • 未指定 RSA 选项

        • 数据目录中缺少 RSA 文件
      • 服务器在数据目录中检查以下 RSA 文件

        private_key.pem      Private member of private/public key pair
        public_key.pem       Public member of private/public key pair
        
        • 如果存在这些文件中的任何一个,则服务器不会创建 RSA 文件。否则,它将创建它们。
      • 如果服务器自动生成 RSA 文件,它将使用其名称来设置相应的系统变量
        • sha256_password_private_key_path, sha256_password_public_key_path
        • caching_sha2_password_private_key_path, caching_sha2_password_public_key_path
  • 使用 mysql_ssl_rsa_setup 手动生成 SSL 和 RSA 文件

    MySQL 发行版包括 mysql_ssl_rsa_setup 实用程序,可以手动调用该实用程序以生成 SSL 和 RSA 文件。这要求 openssl 命令可用。

    mysql_ssl_rsa_setup [options]
    
    • SSL 和 RSA 文件特征
      • SSL 和 RSA 密钥的大小为 2048 位

      • 生成的 CA 证书是自签名的

        • 使用 sha256WithRSAEncryption 签名算法,使用 CA 证书和密钥对 SSL 服务器和客户端证书进行签名。
      • SSL 证书通用名称
        • SSL 证书使用以下通用名称 (CN) 格式
          ca.pem:         MySQL_Server_suffix_Auto_Generated_CA_Certificate
          server-cert.pm: MySQL_Server_suffix_Auto_Generated_Server_Certificate
          client-cert.pm: MySQL_Server_suffix_Auto_Generated_Client_Certificate
          
        • 名称后缀
          [root@yingzai_23 data]$ openssl x509 -text -in ca.pem 
          ...
                  Issuer: CN = MySQL_Server_8.0.23_Auto_Generated_CA_Certificate
          
          • 基于 MySQL 版本号
            • mysql_ssl_rsa_setup 程序的选项
              • –suffix
                • 指定生成证书的后缀
          • 对于服务器生成的文件,如果结果 CN 值超过64个字符,则名称的 _suffix 部分将被省略

      • SSL 证书内容

        • SSL 文件的国家 (C) ,州或省 (ST) ,组织 (O) ,组织单位名称 (OU) 和电子邮件地址的值为空白。

        • 每个证书/密钥对的 SSL 文件具有不同的序列号(serial number):ca 是1,server 是2,client 是3

          [root@yingzai_23 data]$ openssl x509 -text -in ca.pem 
          Certificate:
              Data:
                  Version: 3 (0x2)
                  Serial Number: 1 (0x1)  # 序列号
                  Signature Algorithm: sha256WithRSAEncryption
                  Issuer: CN = MySQL_Server_8.0.23_Auto_Generated_CA_Certificate
                  Validity
                      Not Before: Feb 26 14:37:41 2021 GMT
                      Not After : Feb 24 14:37:41 2031 GMT
                  Subject: CN = MySQL_Server_8.0.23_Auto_Generated_CA_Certificate
                  Subject Public Key Info:
                      Public Key Algorithm: rsaEncryption
                          RSA Public-Key: (2048 bit)
                          Modulus:
                              00:97:0a:40:fd:ef:23:93:a1:2b:0b:42:f7:89:4f:
                              ...
                          Exponent: 65537 (0x10001)
                  X509v3 extensions:
                      X509v3 Basic Constraints: critical
                          CA:TRUE
              Signature Algorithm: sha256WithRSAEncryption
          
      • 有效期
        • 由服务器或 mysql_ssl_rsa_setup 创建的 SSL 文件从生成之日起有效期为十年
        • RSA 文件不会过期
      • 文件权限
        • 服务器自动创建的文件归运行服务器的帐户所有
        • 使用 mysql_ssl_rsa_setup 创建的文件归调用该程序的用户所有
        • 在类 Unix 的系统上,证书文件的文件访问模式为 644,密钥文件的文件访问模式为 600。
    • 查看 SSL 证书的内容
      openssl x509 -text -in ca.pem
      openssl x509 -text -in server-cert.pem
      openssl x509 -text -in client-cert.pem
      
    • 检查 SSL 证书到期信息
      • 状态变量
        mysql> show status like 'ssl_server_not%';
        +-----------------------+--------------------------+
        | Variable_name         | Value                    |
        +-----------------------+--------------------------+
        | Ssl_server_not_after  | Feb 24 14:37:41 2031 GMT |
        | Ssl_server_not_before | Feb 26 14:37:41 2021 GMT |
        +-----------------------+--------------------------+
        
        • Ssl_server_not_after
          • 证书到期日期
        • Ssl_server_not_before
          • 证书创建日期

使用 openssl 创建

  • 创建 SSL 证书和密钥
    • 无论使用哪种方法生成证书和密钥文件,用于服务器和客户端证书/密钥的通用名称都必须与用于 CA 证书的通用名称不同。
      • 否则,证书和密钥文件不适用于使用 OpenSSL 编译的服务器,并报错
        ERROR 2026 (HY000): SSL connection error:
        error:00000001:lib(0):func(0):reason(1)
        
    • 示例
      • 在 Unix 上从命令行创建 SSL 文件
        # Create clean environment
        rm -rf newcerts
        mkdir newcerts && cd newcerts
        
        # Create CA certificate
        openssl genrsa 2048 > ca-key.pem
        openssl req -new -x509 -nodes -days 3600 \
                -key ca-key.pem -out ca.pem
        
        # Create server certificate, remove passphrase, and sign it
        # server-cert.pem = public key, server-key.pem = private key
        openssl req -newkey rsa:2048 -days 3600 \
                -nodes -keyout server-key.pem -out server-req.pem
        openssl rsa -in server-key.pem -out server-key.pem
        openssl x509 -req -in server-req.pem -days 3600 \
                -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
        
        # Create client certificate, remove passphrase, and sign it
        # client-cert.pem = public key, client-key.pem = private key
        openssl req -newkey rsa:2048 -days 3600 \
                -nodes -keyout client-key.pem -out client-req.pem
        openssl rsa -in client-key.pem -out client-key.pem
        openssl x509 -req -in client-req.pem -days 3600 \
                -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
        
      • 在 Unix 上使用脚本创建 SSL 文件
        DIR=`pwd`/openssl
        PRIV=DIR/private
        
        mkdirDIR PRIVDIR/newcerts
        cp /usr/share/ssl/openssl.cnf DIR
        replace ./demoCADIR -- DIR/openssl.cnf
        
        # Create necessary files:database, serial andnew_certs_dir
        # directory (optional)
        
        touch DIR/index.txt
        echo "01">DIR/serial
        
        #
        # Generation of Certificate Authority(CA)
        #
        
        openssl req -new -x509 -keyout PRIV/cakey.pem -outDIR/ca.pem \
            -days 3600 -config DIR/openssl.cnf
        
        # Sample output:
        # Using configuration from /home/jones/openssl/openssl.cnf
        # Generating a 1024 bit RSA private key
        # ................++++++
        # .........++++++
        # writing new private key to '/home/jones/openssl/private/cakey.pem'
        # Enter PEM pass phrase:
        # Verifying password - Enter PEM pass phrase:
        # -----
        # You are about to be asked to enter information to be
        # incorporated into your certificate request.
        # What you are about to enter is what is called a Distinguished Name
        # or a DN.
        # There are quite a few fields but you can leave some blank
        # For some fields there will be a default value,
        # If you enter '.', the field will be left blank.
        # -----
        # Country Name (2 letter code) [AU]:FI
        # State or Province Name (full name) [Some-State]:.
        # Locality Name (eg, city) []:
        # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
        # Organizational Unit Name (eg, section) []:
        # Common Name (eg, YOUR name) []:MySQL admin
        # Email Address []:
        
        #
        # Create server request and key
        #
        openssl req -new -keyoutDIR/server-key.pem -out \
            DIR/server-req.pem -days 3600 -configDIR/openssl.cnf
        
        # Sample output:
        # Using configuration from /home/jones/openssl/openssl.cnf
        # Generating a 1024 bit RSA private key
        # ..++++++
        # ..........++++++
        # writing new private key to '/home/jones/openssl/server-key.pem'
        # Enter PEM pass phrase:
        # Verifying password - Enter PEM pass phrase:
        # -----
        # You are about to be asked to enter information that will be
        # incorporated into your certificate request.
        # What you are about to enter is what is called a Distinguished Name
        # or a DN.
        # There are quite a few fields but you can leave some blank
        # For some fields there will be a default value,
        # If you enter '.', the field will be left blank.
        # -----
        # Country Name (2 letter code) [AU]:FI
        # State or Province Name (full name) [Some-State]:.
        # Locality Name (eg, city) []:
        # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
        # Organizational Unit Name (eg, section) []:
        # Common Name (eg, YOUR name) []:MySQL server
        # Email Address []:
        #
        # Please enter the following 'extra' attributes
        # to be sent with your certificate request
        # A challenge password []:
        # An optional company name []:
        
        #
        # Remove the passphrase from the key
        #
        openssl rsa -in DIR/server-key.pem -outDIR/server-key.pem
        
        #
        # Sign server cert
        #
        openssl ca -cert DIR/ca.pem -policy policy_anything \
            -outDIR/server-cert.pem -config DIR/openssl.cnf \
            -infilesDIR/server-req.pem
        
        # Sample output:
        # Using configuration from /home/jones/openssl/openssl.cnf
        # Enter PEM pass phrase:
        # Check that the request matches the signature
        # Signature ok
        # The Subjects Distinguished Name is as follows
        # countryName           :PRINTABLE:'FI'
        # organizationName      :PRINTABLE:'MySQL AB'
        # commonName            :PRINTABLE:'MySQL admin'
        # Certificate is to be certified until Sep 13 14:22:46 2003 GMT
        # (365 days)
        # Sign the certificate? [y/n]:y
        #
        #
        # 1 out of 1 certificate requests certified, commit? [y/n]y
        # Write out database with 1 new entries
        # Data Base Updated
        
        #
        # Create client request and key
        #
        openssl req -new -keyout DIR/client-key.pem -out \DIR/client-req.pem -days 3600 -config DIR/openssl.cnf
        
        # Sample output:
        # Using configuration from /home/jones/openssl/openssl.cnf
        # Generating a 1024 bit RSA private key
        # .....................................++++++
        # .............................................++++++
        # writing new private key to '/home/jones/openssl/client-key.pem'
        # Enter PEM pass phrase:
        # Verifying password - Enter PEM pass phrase:
        # -----
        # You are about to be asked to enter information that will be
        # incorporated into your certificate request.
        # What you are about to enter is what is called a Distinguished Name
        # or a DN.
        # There are quite a few fields but you can leave some blank
        # For some fields there will be a default value,
        # If you enter '.', the field will be left blank.
        # -----
        # Country Name (2 letter code) [AU]:FI
        # State or Province Name (full name) [Some-State]:.
        # Locality Name (eg, city) []:
        # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
        # Organizational Unit Name (eg, section) []:
        # Common Name (eg, YOUR name) []:MySQL user
        # Email Address []:
        #
        # Please enter the following 'extra' attributes
        # to be sent with your certificate request
        # A challenge password []:
        # An optional company name []:
        
        #
        # Remove the passphrase from the key
        #
        openssl rsa -inDIR/client-key.pem -out DIR/client-key.pem
        
        #
        # Sign client cert
        #
        
        openssl ca -certDIR/ca.pem -policy policy_anything \
            -out DIR/client-cert.pem -configDIR/openssl.cnf \
            -infiles DIR/client-req.pem
        
        # Sample output:
        # Using configuration from /home/jones/openssl/openssl.cnf
        # Enter PEM pass phrase:
        # Check that the request matches the signature
        # Signature ok
        # The Subjects Distinguished Name is as follows
        # countryName           :PRINTABLE:'FI'
        # organizationName      :PRINTABLE:'MySQL AB'
        # commonName            :PRINTABLE:'MySQL user'
        # Certificate is to be certified until Sep 13 16:45:17 2003 GMT
        # (365 days)
        # Sign the certificate? [y/n]:y
        #
        #
        # 1 out of 1 certificate requests certified, commit? [y/n]y
        # Write out database with 1 new entries
        # Data Base Updated
        
        #
        # Create a my.cnf file that you can use to test the certificates
        #
        
        cat<DIR/my.cnf
        [client]
        ssl-ca=DIR/ca.pem
        ssl-cert=DIR/client-cert.pem
        ssl-key=DIR/client-key.pem
        [mysqld]
        ssl_ca=DIR/ca.pem
        ssl_cert=DIR/server-cert.pem
        ssl_key=DIR/server-key.pem
        EOF
        
      • 在 Windows 上创建 SSL 文件
    • 验证证书和密钥
      shell> openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
      server-cert.pem: OK
      client-cert.pem: OK
      
    • 查看证书内容
      openssl x509 -text -in ca.pem
      openssl x509 -text -in server-cert.pem
      openssl x509 -text -in client-cert.pem
      
  • 创建 RSA 密钥
    • 创建 RSA 密钥对文件
      openssl genrsa -out private_key.pem 2048
      openssl rsa -in private_key.pem -pubout -out public_key.pem
      

      Note: 这些命令创建 2048 位密钥。

    • 然后设置密钥文件的访问模式

      chmod 400 private_key.pem
      chmod 444 public_key.pem
      
      • 私钥只能由服务器读取,而公钥可以自由分发给客户端用户

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注