跳至内容

如何使用 SSL 连接成功连接到我的 Amazon RDS 实例?

5 分钟阅读
0

我想使用安全套接字层 (SSL) 连接来连接我的 Amazon Relational Database Service (Amazon RDS) 数据库实例。

简短描述

要加密与运行 MySQL、MariaDB、Microsoft SQL Server、Oracle 或 PostgreSQL 的数据库实例的连接,请在应用程序中使用 SSL 或传输层安全性 (TLS)。SSL/TLS 连接可提供一层安全保护,因为这些连接会对在您的客户端和数据库实例之间传输的数据进行加密。服务器证书可提供额外一层安全保护,因为该证书会验证是否连接到 Amazon RDS 数据库实例。

当预置数据库实例时,Amazon RDS 会创建 SSL 证书并将该证书安装在实例上。这些证书由证书颁发机构 (CA) 签署。SSL 证书会将数据库实例端点作为 SSL 证书的常用名称包含在内,以保护实例免受欺骗攻击。Amazon RDS 创建的 SSL 证书是受信任的根实体,可在大多数情况下使用。但是,如果应用程序不接受证书链,则该证书可能会失败。在这种情况下,请使用中间证书连接到 AWS 区域。例如,当使用 SSL 连接到 AWS GovCloud(美国)区域时,必须使用中间证书。

您可以从 AWS Trust Services 下载包含所有区域的中间证书和根证书的证书捆绑包。如果应用程序位于 Microsoft Windows 上且需要 PKCS7 文件,则您可以从 Amazon Trust Services 下载 PKCS7 证书捆绑包。该捆绑包包含中间证书和根证书。

解决方法

每个数据库引擎都有自己的用于实施 SSL/TLS 的流程。要为数据库集群实施 SSL/TLS 连接,请根据您的数据库引擎使用以下方法之一。

Amazon RDS for Oracle

对于 Amazon RDS for Oracle 实例,要启用 SSL 模式,请在您的自定义选项组中添加 SSL 选项

RDS for Oracle 支持 TLS 版本 1.0 和 1.2。要使用 Oracle SSL 选项,请使用选项组中的 SQLNET.SSL_VERSION 选项设置。此选项设置允许使用以下值:

  • “1.0”- 客户端只能使用 TLS 1.0 连接到数据库实例。
  • “1.2”- 客户端只能使用 TLS 1.2 连接到数据库实例。
  • “1.2 或 1.0”- 客户端可以使用 TLS 1.2 或 1.0 连接到数据库实例。

对于现有的 Oracle SSL 选项,SQLNET.SSL_VERSION 将自动设置为“1.0”。如有必要,您可以更改此设置。

在连接到使用 Oracle SSL 选项的 Oracle 数据库实例之前,必须将 SQL*Plus 客户端配置为使用 SSL。要通过 JDBC 使用 SSL 连接,必须创建密钥库,信任 Amazon RDS 根 CA 证书,然后配置 SSL 连接。

使用 JDBC 来设置 SSL 连接的示例代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class OracleSslConnectionTest {
    private static final String DB_SERVER_NAME = "example-dns";
    private static final Integer SSL_PORT = "example-ssl-option-port-in-option-group";
    private static final String DB_SID = "example-oracle-sid";
    private static final String DB_USER = "example-username";
    private static final String DB_PASSWORD = "example-password";
    // This key store has only the prod root ca.
    private static final String KEY_STORE_FILE_PATH = "example-file-path-to-keystore";
    private static final String KEY_STORE_PASS = "example-keystore-password";
    public static void main(String[] args) throws SQLException {
        final Properties properties = new Properties();
        final String connectionString = String.format(
                "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=%s)(PORT=%d))(CONNECT_DATA=(SID=%s)))",
                DB_SERVER_NAME, SSL_PORT, DB_SID);
        properties.put("example-username", DB_USER);
        properties.put("example-password", DB_PASSWORD);
        properties.put("oracle.jdbc.J2EE13Compliant", "true");
        properties.put("javax.net.ssl.trustStore", KEY_STORE_FILE_PATH);
        properties.put("javax.net.ssl.trustStoreType", "JKS");
        properties.put("javax.net.ssl.trustStorePassword", KEY_STORE_PASS);
        final Connection connection = DriverManager.getConnection(connectionString, properties);
        // If there is no exception, it means that an SSL connection can be opened
    }
}

在使用 SSL 连接您的 RDS for Oracle 实例之前,请检查以下内容:

  • RDS 根证书已下载并添加到钱包文件中。该文件存储在由 sqlnet.ora 文件中的 WALLET_LOCATION 参数指定的目录中。
  • 您的 TNS 条目中有正确的 SSL 端口号。
  • Amazon RDS 安全组已配置为允许您的计算机通过 SSL 端口进行入站连接。
  • 防火墙或安全策略经过适当配置,允许来自 Amazon RDS 的流量通过 SSL 端口。

Amazon RDS for MariaDB

Amazon RDS for MariaDB 支持 TLS 版本 1.0、1.1、1.2 和 1.3。在单向 TLS 连接中,可以在没有客户端证书的情况下使用 TLS,并且只需要对服务器进行身份验证。因此,可以进行单向身份验证。但是,仍然可以进行双向加密。有关详细信息,请参阅 MariaDB 网站上的 Activating one-way TLS for MariaDB clients

通过服务器证书验证,客户端可验证证书是否属于服务器。有关详细信息,请参阅 MariaDB 网站上的 Server certificate verification

要启动具有 RDS 证书的 MySQL 5.7 或更高版本的客户端,请运行类似于以下的命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-mode=VERIFY_IDENTITY

要启动具有 RDS 证书的 MariaDB 客户端,请运行类似于以下的命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-verify-server-cert

要要求特定用户或账户使用 SSL 连接,请根据您的 MariaDB 版本运行以下查询:

ALTER USER 'test'@'%' REQUIRE SSL;

对于已启用性能架构且应用程序已连接到数据库实例的 RDS for MariaDB 10.5 及更高版本,请检查哪些连接使用 SSL/TLS:

MariaDB> SELECT id, user, host, connection_type
FROM performance_schema.threads pst
INNER JOIN information_schema.processlist isp
ON pst.processlist_id = isp.id;

**注意:**有关性能架构的详细信息,请参阅 MariaDB 网站上的 Performance Schema

Amazon RDS for MySQL

MySQL 使用 OpenSSL 进行安全连接。有关详细信息,请参阅 Amazon RDS 上 MySQL 数据库实例的 SSL/TLS 支持

默认情况下,当服务器支持加密连接时,MySQL 客户端程序会尝试建立加密连接。为了提高安全性,请使用 --ssl-ca 参数来引用将数据库实例端点作为常用名称包含在内的 SSL 证书。SSL 证书可保护实例免受欺骗攻击。

要对 MySQL 5.7 及更高版本使用 --ssl-ca 参数来启动客户端,请运行类似于以下的命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-mode=VERIFY_IDENTITY

要要求特定用户或账户使用 SSL 连接,请根据您的 MySQL 版本运行类似于以下的命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-verify-server-cert

对于 MySQL 5.7 及更高版本,请运行以下命令:

ALTER USER 'testuser'@'%' REQUIRE SSL;

对于已启用性能架构且应用程序已连接到数据库实例的 RDS for MySQL 版本 5.7 或 8.0,请检查哪些连接使用 SSL/TLS:

mysql> SELECT id, user, host, connection_type
FROM performance_schema.threads pst
INNER JOIN information_schema.processlist isp
ON pst.processlist_id = isp.id;

**注意:**有关性能架构的详细信息,请参阅 MariaDB 网站上的 Performance Schema

Amazon RDS for Microsoft SQL Server

要使用 SSL 连接到 RDS for Microsoft SQL Server 数据库实例,您可以对所有连接强制使用 SSL加密特定连接

要对来自其他 SQL 客户端的连接进行加密,请在您的连接字符串中附加 encrypt=true。此字符串可以在 GUI 工具的连接页面上作为选项或属性使用。

要确认您的连接是否已加密,请运行以下查询:

SELECT ENCRYPT_OPTION FROM SYS.DM_EXEC_CONNECTIONS WHERE SESSION_ID = @@SPID;

验证查询对于 encrypt_option 是否返回 true

**注意:**要为使用 JDBC 进行连接的客户端激活 SSL 加密,您可能需要将 RDS SQL 证书添加到 Java CA 证书 (cacerts) 存储区。为此,请使用 keytool 实用程序。

Amazon RDS for PostgreSQL

Amazon RDS 支持对 PostgreSQL 数据库实例使用 SSL 加密。有关详细信息,请参阅将 SSL 与 PostgreSQL 数据库实例结合使用

在通过 SSL 连接到 RDS for PostgreSQL 数据库实例之前,请完成以下步骤:

  1. 下载证书。
  2. 将证书导入您的操作系统。

有关详细信息,请参阅通过 SSL 连接到 PostgreSQL 数据库实例

要引用证书,请使用 sslrootcert 参数。例如,sslrootcert=rds-ssl-ca-cert.pem

psql "host=myinstance.123456789012.rds-us-east-1.amazonaws.com port=5432 user=testuser dbname=testpg sslmode=verify-full sslrootcert=global-bundle.pem"

要将与 RDS for PostgreSQL 实例的连接配置为使用 SSL,请在自定义参数组中将 rds.force_ssl 设置为 1(启用)。默认情况下,此值设置为 0(关闭)

当将 rds.force_ssl 设置为 **1(启用)**时,您的数据库实例的 pg_hba.conf 文件会被修改为支持新的 SSL 配置。要查看 pg_hba.conf 文件的内容摘要,请使用 pg_hba_file_rules 视图。有关详细信息,请参阅 PostgreSQL 网站上的 pg_hba_file_rules

当将 rds.force_ssl 设置为 **0(关闭)**时,pg_hba.conf 文件看起来与以下内容类似:

SELECT * FROM pg_hba_file_rules;

 line_number | type  |     database      | user_name  | address  | netmask | auth_method | options | error
-------------+-------+-------------------+------------+----------+---------+-------------+---------+-------
           4 | local | {all}             | {all}      |          |         | md5         |         |
          10 | host  | {all}             | {rdsadmin} | samehost |         | md5         |         |
          11 | host  | {all}             | {rdsadmin} | all      |         | reject      |         |
          12 | host  | {rdsadmin}        | {all}      | all      |         | reject      |         |
          13 | host  | {all}             | {all}      | all      |         | md5         |         |
          14 | host  | {replication}     | {all}      | samehost |         | md5         |         |
          15 | host  | {rds_replication} | {all}      | all      |         | md5         |         |
(7 rows)

当将 rds.force_ssl 设置为 **1(启用)**时,pg_hba.conf 文件看起来与以下内容类似:

SELECT * FROM pg_hba_file_rules;

line_number |  type   |     database      | user_name  | address  | netmask | auth_method | options | error
-------------+---------+-------------------+------------+----------+---------+-------------+---------+-------
          4 | local   | {all}             | {all}      |          |         | md5         |         |
         10 | host    | {all}             | {rdsadmin} | samehost |         | md5         |         |
         11 | host    | {all}             | {rdsadmin} | all      |         | reject      |         |
         12 | host    | {rdsadmin}        | {all}      | all      |         | reject      |         |
         13 | hostssl | {all}             | {all}      | all      |         | md5         |         |
         14 | host    | {replication}     | {all}      | samehost |         | md5         |         |
         15 | hostssl | {rds_replication} | {all}      | all      |         | md5         |         |

**注意:**将 rds.force_ssl 设置为 **1(启用)**后,line_number (13) 的 type 值可能会更新为 hostssl

在您的实例上激活 SSL 连接并启动与 RDS for PostgreSQL 实例的连接后,您会看到一条类似于以下内容的消息:

psql "host=myinstance.123456789012.rds-us-east-1.amazonaws.com port=5432 user=testuser dbname=testpg"
. . .
SL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

所有非 SSL 连接都被拒绝,并显示以下消息:

psql "host=myinstance.123456789012.rds-us-east-1.amazonaws.com port=5432 user=testuser dbname=testpg sslmode=disable"psql: FATAL: no pg_hba.conf entry for host "host.ip", user "testuser", database "testpg", SSL off

相关信息

使用 SSL/TLS 加密与数据库实例或集群的连接